MBED library for LCD-TFT display: https://www.waveshare.com/wiki/2.8inch_TFT_Touch_Shield

Dependents:   DiffPressureMeter

Files at this revision

API Documentation at this revision

Comitter:
igbt6
Date:
Tue Apr 03 20:08:18 2018 +0000
Commit message:
Initial commit

Changed in this revision

HX8347D/LCD.cpp Show annotated file Show diff for this revision Revisions of this file
HX8347D/LCD.h Show annotated file Show diff for this revision Revisions of this file
HX8347D/font.c Show annotated file Show diff for this revision Revisions of this file
HX8347D/font.h Show annotated file Show diff for this revision Revisions of this file
Touch/Touch.cpp Show annotated file Show diff for this revision Revisions of this file
Touch/Touch.h Show annotated file Show diff for this revision Revisions of this file
XPT2046/XPT2046.cpp Show annotated file Show diff for this revision Revisions of this file
XPT2046/XPT2046.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HX8347D/LCD.cpp	Tue Apr 03 20:08:18 2018 +0000
@@ -0,0 +1,352 @@
+
+
+#include <LCD.h>
+#include <algorithm>
+
+LCD::LCD()
+	: __LCD_CS_OUT()
+	, __LCD_DC_OUT()
+	, __LCD_BKL_OUT()
+{
+}
+
+void LCD::lcd_init()
+{
+
+	__LCD_DC_SET();
+    __LCD_CS_SET();
+    __LCD_BKL_OFF();
+
+	//Driving ability Setting
+	lcd_write_register(0xEA,0x00); //PTBA[15:8]
+	lcd_write_register(0xEB,0x20); //PTBA[7:0]
+	lcd_write_register(0xEC,0x0C); //STBA[15:8]
+	lcd_write_register(0xED,0xC4); //STBA[7:0]
+	lcd_write_register(0xE8,0x38); //OPON[7:0]
+	lcd_write_register(0xE9,0x10); //OPON1[7:0]
+	lcd_write_register(0xF1,0x01); //OTPS1B
+	lcd_write_register(0xF2,0x10); //GEN
+	//Gamma 2.2 Setting
+	lcd_write_register(0x40,0x01); //
+	lcd_write_register(0x41,0x00); //
+	lcd_write_register(0x42,0x00); //
+	lcd_write_register(0x43,0x10); //
+	lcd_write_register(0x44,0x0E); //
+	lcd_write_register(0x45,0x24); //
+	lcd_write_register(0x46,0x04); //
+	lcd_write_register(0x47,0x50); //
+	lcd_write_register(0x48,0x02); //
+	lcd_write_register(0x49,0x13); //
+	lcd_write_register(0x4A,0x19); //
+	lcd_write_register(0x4B,0x19); //
+	lcd_write_register(0x4C,0x16); //
+	lcd_write_register(0x50,0x1B); //
+	lcd_write_register(0x51,0x31); //
+	lcd_write_register(0x52,0x2F); //
+	lcd_write_register(0x53,0x3F); //
+	lcd_write_register(0x54,0x3F); //
+	lcd_write_register(0x55,0x3E); //
+	lcd_write_register(0x56,0x2F); //
+	lcd_write_register(0x57,0x7B); //
+	lcd_write_register(0x58,0x09); //
+	lcd_write_register(0x59,0x06); //
+	lcd_write_register(0x5A,0x06); //
+	lcd_write_register(0x5B,0x0C); //
+	lcd_write_register(0x5C,0x1D); //
+	lcd_write_register(0x5D,0xCC); //
+	//Power Voltage Setting
+	lcd_write_register(0x1B,0x1B); //VRH=4.65V
+	lcd_write_register(0x1A,0x01); //BT (VGH~15V,VGL~-10V,DDVDH~5V)
+	lcd_write_register(0x24,0x2F); //VMH(VCOM High voltage ~3.2V)
+	lcd_write_register(0x25,0x57); //VML(VCOM Low voltage -1.2V)
+	//****VCOM offset**///
+	lcd_write_register(0x23,0x88); //for Flicker adjust //can reload from OTP
+	//Power on Setting
+	lcd_write_register(0x18,0x34); //I/P_RADJ,N/P_RADJ, Normal mode 60Hz
+	lcd_write_register(0x19,0x01); //OSC_EN='1', start Osc
+	lcd_write_register(0x01,0x00); //DP_STB='0', out deep sleep
+	lcd_write_register(0x1F,0x88);// GAS=1, VOMG=00, PON=0, DK=1, XDK=0, DVDH_TRI=0, STB=0
+	wait(5);
+	lcd_write_register(0x1F,0x80);// GAS=1, VOMG=00, PON=0, DK=0, XDK=0, DVDH_TRI=0, STB=0
+	wait(5);
+	lcd_write_register(0x1F,0x90);// GAS=1, VOMG=00, PON=1, DK=0, XDK=0, DVDH_TRI=0, STB=0
+	wait(5);
+	lcd_write_register(0x1F,0xD0);// GAS=1, VOMG=10, PON=1, DK=0, XDK=0, DDVDH_TRI=0, STB=0
+	wait(5);
+	//262k/65k color selection
+	lcd_write_register(0x17,0x05); //default 0x06 262k color // 0x05 65k color
+	//SET PANEL
+	lcd_write_register(0x36,0x00); //SS_P, GS_P,REV_P,BGR_P
+	//Display ON Setting
+	lcd_write_register(0x28,0x38); //GON=1, DTE=1, D=1000
+	wait(40);
+	lcd_write_register(0x28,0x3F); //GON=1, DTE=1, D=1100
+
+	lcd_write_register(0x16,0x18); 
+	//Set GRAM Area
+	lcd_write_register(0x02,0x00);
+	lcd_write_register(0x03,0x00); //Column Start
+	lcd_write_register(0x04,0x00);
+	lcd_write_register(0x05,0xEF); //Column End
+	lcd_write_register(0x06,0x00);
+	lcd_write_register(0x07,0x00); //Row Start
+	lcd_write_register(0x08,0x01);
+	lcd_write_register(0x09,0x3F); //Row End
+	
+    lcd_clear_screen(WHITE);
+	__LCD_BKL_ON();
+}
+
+//draw a point on the lcd with the specified color.
+//hwXpos specify x position.
+//hwYpos specify y position.
+//hwColor color of the point.
+void LCD::lcd_draw_point(uint16_t hwXpos, uint16_t hwYpos, uint16_t hwColor) 
+{
+	if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
+		return;
+	}
+	
+	lcd_set_cursor(hwXpos, hwYpos);
+	lcd_write_byte(0x22, LCD_CMD);
+    lcd_write_word(hwColor);
+}
+
+//display a char at the specified position on lcd.
+void LCD::lcd_display_char(uint16_t hwXpos, //specify x position.
+                         uint16_t hwYpos, //specify y position.
+                         uint8_t chChr,   //a char is display.
+                         uint8_t chSize,  //specify the size of the char
+                         uint16_t hwColor) //specify the color of the char
+{      	
+	uint8_t i, j, chTemp;
+	uint16_t hwYpos0 = hwYpos, hwColorVal = 0;
+
+	if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
+		return;
+	}
+
+					   
+    for (i = 0; i < chSize; i ++) {   
+		if (FONT_1206 == chSize) {
+			chTemp = c_chFont1206[chChr - 0x20][i];  
+		} else if (FONT_1608 == chSize) { 
+			chTemp = c_chFont1608[chChr - 0x20][i];
+		}
+		
+        for (j = 0; j < 8; j ++) {
+    		if (chTemp & 0x80) {
+				hwColorVal = hwColor;
+				lcd_draw_point(hwXpos, hwYpos, hwColorVal);
+    		}			
+			chTemp <<= 1;
+			hwYpos ++;
+			if ((hwYpos - hwYpos0) == chSize) {
+				hwYpos = hwYpos0;
+				hwXpos ++;
+				break;
+			}
+		}  	 
+    } 
+}
+
+
+//_pow
+static uint32_t _pow(uint8_t m, uint8_t n)
+{
+	uint32_t result = 1;
+	
+	while(n --) result *= m;    
+	return result;
+}
+
+//display a number at the specified position on lcd.
+void LCD::lcd_display_num(uint16_t hwXpos,  //specify x position.
+                          uint16_t hwYpos, //specify y position.
+                          uint32_t chNum,  //a number is display.
+                          uint8_t chLen,   //length ot the number
+                          uint8_t chSize,  //specify the size of the number
+                          uint16_t hwColor) //specify the color of the number
+{         	
+	uint8_t i;
+	uint8_t chTemp, chShow = 0;
+
+	if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
+		return;
+	}
+	
+	for(i = 0; i < chLen; i ++) {
+		chTemp = (chNum / _pow(10, chLen - i - 1)) % 10;
+		if(chShow == 0 && i < (chLen - 1)) {
+			if(chTemp == 0) {
+				lcd_display_char(hwXpos + (chSize / 2) * i, hwYpos, ' ', chSize, hwColor);
+				continue;
+			} else {
+				chShow = 1;
+			}	 
+		}
+	 	lcd_display_char(hwXpos + (chSize / 2) * i, hwYpos, chTemp + '0', chSize, hwColor); 
+	}
+} 
+
+//display a string at the specified position on lcd.
+void LCD::lcd_display_string(uint16_t hwXpos, //specify x position.
+                         uint16_t hwYpos,   //specify y position.
+                         const uint8_t *pchString,  //a pointer to string
+                         uint8_t chSize,    // the size of the string 
+                         uint16_t hwColor)  // specify the color of the string 
+{
+
+	if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
+		return;
+	}
+	
+    while (*pchString != '\0') {       
+        if (hwXpos > (LCD_WIDTH - chSize / 2)) {
+			hwXpos = 0;
+			hwYpos += chSize;
+			if (hwYpos > (LCD_HEIGHT - chSize)) {
+				hwYpos = hwXpos = 0;
+				lcd_clear_screen(0x00);
+			}
+		}
+		
+        lcd_display_char(hwXpos, hwYpos, (uint8_t)*pchString, chSize, hwColor);
+        hwXpos += chSize / 2;
+        pchString ++;
+    } 
+}
+
+//draw a line at the specified position on lcd.
+void LCD::lcd_draw_line(uint16_t hwXpos0, //specify x0 position.
+                      uint16_t hwYpos0, //specify y0 position.
+                      uint16_t hwXpos1, //specify x1 position.
+                      uint16_t hwYpos1, //specify y1 position.
+                      uint16_t hwColor) //specify the color of the line
+{
+	int x = hwXpos1 - hwXpos0;
+    int y = hwYpos1 - hwYpos0;
+    int dx = abs(x), sx = hwXpos0 < hwXpos1 ? 1 : -1;
+    int dy = -abs(y), sy = hwYpos0 < hwYpos1 ? 1 : -1;
+    int err = dx + dy, e2;
+
+	if (hwXpos0 >= LCD_WIDTH || hwYpos0 >= LCD_HEIGHT || hwXpos1 >= LCD_WIDTH || hwYpos1 >= LCD_HEIGHT) {
+		return;
+	}
+    
+    for (;;){
+        lcd_draw_point(hwXpos0, hwYpos0 , hwColor);
+        e2 = 2 * err;
+        if (e2 >= dy) {     
+            if (hwXpos0 == hwXpos1) break;
+            err += dy; hwXpos0 += sx;
+        }
+        if (e2 <= dx) {
+            if (hwYpos0 == hwYpos1) break;
+            err += dx; hwYpos0 += sy;
+        }
+    }
+}
+
+//draw a circle at the specified position on lcd.
+void LCD::lcd_draw_circle(uint16_t hwXpos,  //specify x position.
+                        uint16_t hwYpos,  //specify y position.
+                        uint16_t hwRadius, //specify the radius of the circle.
+                        uint16_t hwColor)  //specify the color of the circle.
+{
+	int x = -hwRadius, y = 0, err = 2 - 2 * hwRadius, e2;
+
+	if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
+		return;
+	}
+	
+    do {
+        lcd_draw_point(hwXpos - x, hwYpos + y, hwColor);
+        lcd_draw_point(hwXpos + x, hwYpos + y, hwColor);
+        lcd_draw_point(hwXpos + x, hwYpos - y, hwColor);
+        lcd_draw_point(hwXpos - x, hwYpos - y, hwColor);
+        e2 = err;
+        if (e2 <= y) {
+            err += ++ y * 2 + 1;
+            if(-x == y && e2 <= x) e2 = 0;
+        }
+        if(e2 > x) err += ++ x * 2 + 1;
+    } while(x <= 0);
+}
+
+//fill a rectangle out at the specified position on lcd.
+void LCD::lcd_fill_rect(uint16_t hwXpos,  //specify x position.
+                   uint16_t hwYpos,  //specify y position.
+                   uint16_t hwWidth, //specify the width of the rectangle.
+                   uint16_t hwHeight, //specify the height of the rectangle.
+                   uint16_t hwColor)  //specify the color of rectangle.
+{
+	uint16_t i, j;
+
+	if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
+		return;
+	}
+	
+	for(i = 0; i < hwHeight; i ++){
+		for(j = 0; j < hwWidth; j ++){
+			lcd_draw_point(hwXpos + j, hwYpos + i, hwColor);
+		}
+	}
+}
+
+//draw a vertical line at the specified position on lcd.
+void LCD::lcd_draw_v_line(uint16_t hwXpos, //specify x position.
+                        uint16_t hwYpos, //specify y position. 
+                        uint16_t hwHeight, //specify the height of the vertical line.
+                        uint16_t hwColor)  //specify the color of the vertical line.
+{	
+	uint16_t i, y1 = min(hwYpos + hwHeight, LCD_HEIGHT - 1);
+
+	if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
+		return;
+	}
+	
+    for (i = hwYpos; i < y1; i ++) {
+        lcd_draw_point(hwXpos, i, hwColor);
+    }
+}
+
+//draw a horizonal line at the specified position on lcd.
+void LCD::lcd_draw_h_line(uint16_t hwXpos, //specify x position.
+                        uint16_t hwYpos,  //specify y position. 
+                        uint16_t hwWidth, //specify the width of the horizonal line.
+                        uint16_t hwColor) //specify the color of the horizonal line.
+{	
+	uint16_t i, x1 = min(hwXpos + hwWidth, LCD_WIDTH - 1);
+
+	if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
+		return;
+	}
+	
+    for (i = hwXpos; i < x1; i ++) {
+        lcd_draw_point(i, hwYpos, hwColor);
+    }
+}
+
+void LCD::lcd_draw_rect(uint16_t hwXpos,  //specify x position.
+                      uint16_t hwYpos,  //specify y position.
+                      uint16_t hwWidth, //specify the width of the rectangle.
+                      uint16_t hwHeight, //specify the height of the rectangle.
+                      uint16_t hwColor)  //specify the color of rectangle.
+{
+	if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
+		return;
+	}
+
+	lcd_draw_h_line(hwXpos, hwYpos, hwWidth, hwColor);
+	lcd_draw_h_line(hwXpos, hwYpos + hwHeight, hwWidth, hwColor);
+	lcd_draw_v_line(hwXpos, hwYpos, hwHeight, hwColor);
+	lcd_draw_v_line(hwXpos + hwWidth, hwYpos, hwHeight + 1, hwColor);
+}
+
+
+LCD lcd = LCD();
+/*********************************************************************************************************
+  END FILE
+*********************************************************************************************************/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HX8347D/LCD.h	Tue Apr 03 20:08:18 2018 +0000
@@ -0,0 +1,193 @@
+#ifndef LCD_h
+#define LCD_h
+
+#include "mbed.h"
+#include "system.h"
+#include "interfaces.h"
+
+#include "font.h"
+
+//Basic Colors
+#define WHITE          0xFFFF
+#define BLACK          0x0000	  
+#define BLUE           0x001F  
+#define BRED           0XF81F
+#define GRED 		   0XFFE0
+#define GBLUE		   0X07FF
+#define RED            0xF800
+#define MAGENTA        0xF81F
+#define GREEN          0x07E0
+#define CYAN           0x7FFF
+#define YELLOW         0xFFE0
+#define BROWN 		   0XBC40 
+#define BRRED 		   0XFC07 
+#define GRAY  		   0X8430
+
+#define LCD_CMD      0
+#define LCD_DATA     1
+
+#define FONT_1206    12
+#define FONT_1608    16
+
+#define LCD_WIDTH    240
+#define LCD_HEIGHT   320
+
+#define LCD_DC_PIN         PA_8
+#define LCD_BKL_PIN        PC_7
+#define LCD_CS_PIN         PB_6
+
+#define __LCD_CS_OUT()    lcd_cs_pin(LCD_CS_PIN)
+#define __LCD_CS_CLR()    lcd_cs_pin.write(LOW)
+#define __LCD_CS_SET()    lcd_cs_pin.write(HIGH)
+
+#define __LCD_DC_OUT()    lcd_dc_pin(LCD_DC_PIN)
+#define __LCD_DC_CLR()    lcd_dc_pin.write(LOW)
+#define __LCD_DC_SET()    lcd_dc_pin.write(HIGH)
+
+#define __LCD_BKL_OUT()   lcd_bkl_pin(LCD_BKL_PIN)
+#define __LCD_BKL_OFF()   lcd_bkl_pin.write(LOW)
+#define __LCD_BKL_ON()    lcd_bkl_pin.write(HIGH)
+
+
+#define __LCD_WRITE_BYTE(__DATA) HwInterfaces::instance()::getHwInterface<SPI__1>().handle().transfer(__DATA)
+
+
+
+
+class LCD
+{
+
+public:
+
+	LCD();
+
+	void lcd_write_byte(uint8_t chByte, uint8_t chCmd)
+	{
+	    if (chCmd) {
+	        __LCD_DC_SET();
+	    } else {
+	        __LCD_DC_CLR();
+	    }
+	    
+	    __LCD_CS_CLR();
+	    __LCD_WRITE_BYTE(chByte);
+	    __LCD_CS_SET();
+	}
+	
+	inline void lcd_write_word(uint16_t hwData)
+	{
+		__LCD_DC_SET();
+	    __LCD_CS_CLR();
+	    __LCD_WRITE_BYTE(hwData >> 8);
+	    __LCD_WRITE_BYTE(hwData & 0xFF);
+	    __LCD_CS_SET();
+	}
+
+	
+	//write a word(two bytes) to the specified register of lcd.
+	//chRegister address of the register of lcd.
+	//hwValue value is written to the specified register.
+	void lcd_write_register(uint8_t chRegister, uint8_t chValue)
+	{
+		lcd_write_byte(chRegister, LCD_CMD);
+		lcd_write_byte(chValue, LCD_DATA);
+	}
+
+	//set the specified position of cursor on lcd.
+	//hwXpos specify x position
+	//hwYpos specify y position
+	void lcd_set_cursor(uint16_t hwXpos, uint16_t hwYpos)
+	{
+		if (hwXpos >= LCD_WIDTH|| hwYpos >= LCD_HEIGHT) {
+			return;
+		}
+
+		lcd_write_register(0x02, hwXpos >> 8);
+		lcd_write_register(0x03, hwXpos & 0xFF); //Column Start
+		lcd_write_register(0x06, hwYpos >> 8);
+		lcd_write_register(0x07, hwYpos & 0xFF); //Row Start
+	}
+
+    //clear the lcd with the specified color.
+	void lcd_clear_screen(uint16_t hwColor)  
+	{
+		uint32_t i, wCount = LCD_WIDTH;
+	
+		wCount *= LCD_HEIGHT;
+		
+		lcd_set_cursor(0, 0);
+		lcd_write_byte(0x22, LCD_CMD);
+	    
+	    __LCD_DC_SET();
+		__LCD_CS_CLR();
+		for (i = 0; i < wCount; i ++) {
+			__LCD_WRITE_BYTE(hwColor >> 8);
+			__LCD_WRITE_BYTE(hwColor & 0xFF);
+		}
+		__LCD_CS_SET();
+	}
+
+	void lcd_init ();
+	void lcd_draw_point(uint16_t hwXpos, uint16_t hwYpos, uint16_t hwColor);
+	void lcd_display_char(uint16_t hwXpos, //specify x position.
+                         uint16_t hwYpos, //specify y position.
+                         uint8_t chChr,   //a char is display.
+                         uint8_t chSize,  //specify the size of the char
+                         uint16_t hwColor); //specify the color of the char
+	//display a number at the specified position on lcd.
+	void lcd_display_num(uint16_t hwXpos,  //specify x position.
+	                          uint16_t hwYpos, //specify y position.
+	                          uint32_t chNum,  //a number is display.
+	                          uint8_t chLen,   //length ot the number
+	                          uint8_t chSize,  //specify the size of the number
+	                          uint16_t hwColor); //specify the color of the number
+	//display a string at the specified position on lcd.
+	void lcd_display_string(uint16_t hwXpos, //specify x position.
+	                         uint16_t hwYpos,   //specify y position.
+	                         const uint8_t *pchString,  //a pointer to string
+	                         uint8_t chSize,    // the size of the string 
+	                         uint16_t hwColor);  // specify the color of the string
+    void lcd_draw_line(uint16_t hwXpos0, //specify x0 position.
+                      uint16_t hwYpos0, //specify y0 position.
+                      uint16_t hwXpos1, //specify x1 position.
+                      uint16_t hwYpos1, //specify y1 position.
+                      uint16_t hwColor); //specify the color of the line
+    void lcd_draw_circle(uint16_t hwXpos,  //specify x position.
+                        uint16_t hwYpos,  //specify y position.
+                        uint16_t hwRadius, //specify the radius of the circle.
+                        uint16_t hwColor);  //specify the color of the circle.
+    void lcd_fill_rect(uint16_t hwXpos,  //specify x position.
+                   uint16_t hwYpos,  //specify y position.
+                   uint16_t hwWidth, //specify the width of the rectangle.
+                   uint16_t hwHeight, //specify the height of the rectangle.
+                   uint16_t hwColor);  //specify the color of rectangle.
+    void lcd_draw_v_line(uint16_t hwXpos, //specify x position.
+                        uint16_t hwYpos, //specify y position. 
+                        uint16_t hwHeight, //specify the height of the vertical line.
+                        uint16_t hwColor);  //specify the color of the vertical line.
+    void lcd_draw_h_line(uint16_t hwXpos, //specify x position.
+                        uint16_t hwYpos,  //specify y position. 
+                        uint16_t hwWidth, //specify the width of the horizonal line.
+                        uint16_t hwColor); //specify the color of the horizonal line.
+	void lcd_draw_rect(uint16_t hwXpos,  //specify x position.
+                      uint16_t hwYpos,  //specify y position.
+                      uint16_t hwWidth, //specify the width of the rectangle.
+                      uint16_t hwHeight, //specify the height of the rectangle.
+                      uint16_t hwColor);  //specify the color of rectangle.
+                      
+private:
+	DigitalOut lcd_cs_pin;
+	DigitalOut lcd_dc_pin;
+	DigitalOut lcd_bkl_pin;
+
+                       
+};
+
+extern LCD lcd;
+
+#endif
+
+/*********************************************************************************************************
+  END FILE
+*********************************************************************************************************/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HX8347D/font.c	Tue Apr 03 20:08:18 2018 +0000
@@ -0,0 +1,201 @@
+#include <stdint.h>
+static const uint8_t c_chFont1206[95][12] =
+{
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
+	{0x00,0x00,0x00,0x00,0x3F,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
+	{0x00,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x40,0x00,0x00,0x00},/*""",2*/
+	{0x09,0x00,0x0B,0xC0,0x3D,0x00,0x0B,0xC0,0x3D,0x00,0x09,0x00},/*"#",3*/
+	{0x18,0xC0,0x24,0x40,0x7F,0xE0,0x22,0x40,0x31,0x80,0x00,0x00},/*"$",4*/
+	{0x18,0x00,0x24,0xC0,0x1B,0x00,0x0D,0x80,0x32,0x40,0x01,0x80},/*"%",5*/
+	{0x03,0x80,0x1C,0x40,0x27,0x40,0x1C,0x80,0x07,0x40,0x00,0x40},/*"&",6*/
+	{0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x20,0x40,0x40,0x20},/*"(",8*/
+	{0x00,0x00,0x40,0x20,0x20,0x40,0x1F,0x80,0x00,0x00,0x00,0x00},/*")",9*/
+	{0x09,0x00,0x06,0x00,0x1F,0x80,0x06,0x00,0x09,0x00,0x00,0x00},/*"*",10*/
+	{0x04,0x00,0x04,0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0x00,0x00},/*"+",11*/
+	{0x00,0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
+	{0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00},/*"-",13*/
+	{0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
+	{0x00,0x20,0x01,0xC0,0x06,0x00,0x38,0x00,0x40,0x00,0x00,0x00},/*"/",15*/
+	{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"0",16*/
+	{0x00,0x00,0x10,0x40,0x3F,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"1",17*/
+	{0x18,0xC0,0x21,0x40,0x22,0x40,0x24,0x40,0x18,0x40,0x00,0x00},/*"2",18*/
+	{0x10,0x80,0x20,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"3",19*/
+	{0x02,0x00,0x0D,0x00,0x11,0x00,0x3F,0xC0,0x01,0x40,0x00,0x00},/*"4",20*/
+	{0x3C,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x23,0x80,0x00,0x00},/*"5",21*/
+	{0x1F,0x80,0x24,0x40,0x24,0x40,0x34,0x40,0x03,0x80,0x00,0x00},/*"6",22*/
+	{0x30,0x00,0x20,0x00,0x27,0xC0,0x38,0x00,0x20,0x00,0x00,0x00},/*"7",23*/
+	{0x1B,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"8",24*/
+	{0x1C,0x00,0x22,0xC0,0x22,0x40,0x22,0x40,0x1F,0x80,0x00,0x00},/*"9",25*/
+	{0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
+	{0x00,0x00,0x00,0x00,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
+	{0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40},/*"<",28*/
+	{0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x00,0x00},/*"=",29*/
+	{0x00,0x00,0x40,0x40,0x20,0x80,0x11,0x00,0x0A,0x00,0x04,0x00},/*">",30*/
+	{0x18,0x00,0x20,0x00,0x23,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"?",31*/
+	{0x1F,0x80,0x20,0x40,0x27,0x40,0x29,0x40,0x1F,0x40,0x00,0x00},/*"@",32*/
+	{0x00,0x40,0x07,0xC0,0x39,0x00,0x0F,0x00,0x01,0xC0,0x00,0x40},/*"A",33*/
+	{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"B",34*/
+	{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x30,0x80,0x00,0x00},/*"C",35*/
+	{0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"D",36*/
+	{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x40,0x30,0xC0,0x00,0x00},/*"E",37*/
+	{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x00,0x30,0x00,0x00,0x00},/*"F",38*/
+	{0x0F,0x00,0x10,0x80,0x20,0x40,0x22,0x40,0x33,0x80,0x02,0x00},/*"G",39*/
+	{0x20,0x40,0x3F,0xC0,0x04,0x00,0x04,0x00,0x3F,0xC0,0x20,0x40},/*"H",40*/
+	{0x20,0x40,0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x00,0x00},/*"I",41*/
+	{0x00,0x60,0x20,0x20,0x20,0x20,0x3F,0xC0,0x20,0x00,0x20,0x00},/*"J",42*/
+	{0x20,0x40,0x3F,0xC0,0x24,0x40,0x0B,0x00,0x30,0xC0,0x20,0x40},/*"K",43*/
+	{0x20,0x40,0x3F,0xC0,0x20,0x40,0x00,0x40,0x00,0x40,0x00,0xC0},/*"L",44*/
+	{0x3F,0xC0,0x3C,0x00,0x03,0xC0,0x3C,0x00,0x3F,0xC0,0x00,0x00},/*"M",45*/
+	{0x20,0x40,0x3F,0xC0,0x0C,0x40,0x23,0x00,0x3F,0xC0,0x20,0x00},/*"N",46*/
+	{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"O",47*/
+	{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"P",48*/
+	{0x1F,0x80,0x21,0x40,0x21,0x40,0x20,0xE0,0x1F,0xA0,0x00,0x00},/*"Q",49*/
+	{0x20,0x40,0x3F,0xC0,0x24,0x40,0x26,0x00,0x19,0xC0,0x00,0x40},/*"R",50*/
+	{0x18,0xC0,0x24,0x40,0x24,0x40,0x22,0x40,0x31,0x80,0x00,0x00},/*"S",51*/
+	{0x30,0x00,0x20,0x40,0x3F,0xC0,0x20,0x40,0x30,0x00,0x00,0x00},/*"T",52*/
+	{0x20,0x00,0x3F,0x80,0x00,0x40,0x00,0x40,0x3F,0x80,0x20,0x00},/*"U",53*/
+	{0x20,0x00,0x3E,0x00,0x01,0xC0,0x07,0x00,0x38,0x00,0x20,0x00},/*"V",54*/
+	{0x38,0x00,0x07,0xC0,0x3C,0x00,0x07,0xC0,0x38,0x00,0x00,0x00},/*"W",55*/
+	{0x20,0x40,0x39,0xC0,0x06,0x00,0x39,0xC0,0x20,0x40,0x00,0x00},/*"X",56*/
+	{0x20,0x00,0x38,0x40,0x07,0xC0,0x38,0x40,0x20,0x00,0x00,0x00},/*"Y",57*/
+	{0x30,0x40,0x21,0xC0,0x26,0x40,0x38,0x40,0x20,0xC0,0x00,0x00},/*"Z",58*/
+	{0x00,0x00,0x00,0x00,0x7F,0xE0,0x40,0x20,0x40,0x20,0x00,0x00},/*"[",59*/
+	{0x00,0x00,0x70,0x00,0x0C,0x00,0x03,0x80,0x00,0x40,0x00,0x00},/*"\",60*/
+	{0x00,0x00,0x40,0x20,0x40,0x20,0x7F,0xE0,0x00,0x00,0x00,0x00},/*"]",61*/
+	{0x00,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
+	{0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10},/*"_",63*/
+	{0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
+	{0x00,0x00,0x02,0x80,0x05,0x40,0x05,0x40,0x03,0xC0,0x00,0x40},/*"a",65*/
+	{0x20,0x00,0x3F,0xC0,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"b",66*/
+	{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x06,0x40,0x00,0x00},/*"c",67*/
+	{0x00,0x00,0x03,0x80,0x04,0x40,0x24,0x40,0x3F,0xC0,0x00,0x40},/*"d",68*/
+	{0x00,0x00,0x03,0x80,0x05,0x40,0x05,0x40,0x03,0x40,0x00,0x00},/*"e",69*/
+	{0x00,0x00,0x04,0x40,0x1F,0xC0,0x24,0x40,0x24,0x40,0x20,0x00},/*"f",70*/
+	{0x00,0x00,0x02,0xE0,0x05,0x50,0x05,0x50,0x06,0x50,0x04,0x20},/*"g",71*/
+	{0x20,0x40,0x3F,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"h",72*/
+	{0x00,0x00,0x04,0x40,0x27,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"i",73*/
+	{0x00,0x10,0x00,0x10,0x04,0x10,0x27,0xE0,0x00,0x00,0x00,0x00},/*"j",74*/
+	{0x20,0x40,0x3F,0xC0,0x01,0x40,0x07,0x00,0x04,0xC0,0x04,0x40},/*"k",75*/
+	{0x20,0x40,0x20,0x40,0x3F,0xC0,0x00,0x40,0x00,0x40,0x00,0x00},/*"l",76*/
+	{0x07,0xC0,0x04,0x00,0x07,0xC0,0x04,0x00,0x03,0xC0,0x00,0x00},/*"m",77*/
+	{0x04,0x40,0x07,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"n",78*/
+	{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"o",79*/
+	{0x04,0x10,0x07,0xF0,0x04,0x50,0x04,0x40,0x03,0x80,0x00,0x00},/*"p",80*/
+	{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x50,0x07,0xF0,0x00,0x10},/*"q",81*/
+	{0x04,0x40,0x07,0xC0,0x02,0x40,0x04,0x00,0x04,0x00,0x00,0x00},/*"r",82*/
+	{0x00,0x00,0x06,0x40,0x05,0x40,0x05,0x40,0x04,0xC0,0x00,0x00},/*"s",83*/
+	{0x00,0x00,0x04,0x00,0x1F,0x80,0x04,0x40,0x00,0x40,0x00,0x00},/*"t",84*/
+	{0x04,0x00,0x07,0x80,0x00,0x40,0x04,0x40,0x07,0xC0,0x00,0x40},/*"u",85*/
+	{0x04,0x00,0x07,0x00,0x04,0xC0,0x01,0x80,0x06,0x00,0x04,0x00},/*"v",86*/
+	{0x06,0x00,0x01,0xC0,0x07,0x00,0x01,0xC0,0x06,0x00,0x00,0x00},/*"w",87*/
+	{0x04,0x40,0x06,0xC0,0x01,0x00,0x06,0xC0,0x04,0x40,0x00,0x00},/*"x",88*/
+	{0x04,0x10,0x07,0x10,0x04,0xE0,0x01,0x80,0x06,0x00,0x04,0x00},/*"y",89*/
+	{0x00,0x00,0x04,0x40,0x05,0xC0,0x06,0x40,0x04,0x40,0x00,0x00},/*"z",90*/
+	{0x00,0x00,0x00,0x00,0x04,0x00,0x7B,0xE0,0x40,0x20,0x00,0x00},/*"{",91*/
+	{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xF0,0x00,0x00,0x00,0x00},/*"|",92*/
+	{0x00,0x00,0x40,0x20,0x7B,0xE0,0x04,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
+	{0x40,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x40,0x00},/*"~",94*/
+
+};
+
+static const uint8_t c_chFont1608[95][16] = {	  
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xCC,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
+{0x00,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x00,0x00},/*""",2*/
+{0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x00,0x00},/*"#",3*/
+{0x00,0x00,0x0E,0x18,0x11,0x04,0x3F,0xFF,0x10,0x84,0x0C,0x78,0x00,0x00,0x00,0x00},/*"$",4*/
+{0x0F,0x00,0x10,0x84,0x0F,0x38,0x00,0xC0,0x07,0x78,0x18,0x84,0x00,0x78,0x00,0x00},/*"%",5*/
+{0x00,0x78,0x0F,0x84,0x10,0xC4,0x11,0x24,0x0E,0x98,0x00,0xE4,0x00,0x84,0x00,0x08},/*"&",6*/
+{0x08,0x00,0x68,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x18,0x18,0x20,0x04,0x40,0x02,0x00,0x00},/*"(",8*/
+{0x00,0x00,0x40,0x02,0x20,0x04,0x18,0x18,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/
+{0x02,0x40,0x02,0x40,0x01,0x80,0x0F,0xF0,0x01,0x80,0x02,0x40,0x02,0x40,0x00,0x00},/*"*",10*/
+{0x00,0x80,0x00,0x80,0x00,0x80,0x0F,0xF8,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00},/*"+",11*/
+{0x00,0x01,0x00,0x0D,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
+{0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80},/*"-",13*/
+{0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
+{0x00,0x00,0x00,0x06,0x00,0x18,0x00,0x60,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00},/*"/",15*/
+{0x00,0x00,0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"0",16*/
+{0x00,0x00,0x08,0x04,0x08,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"1",17*/
+{0x00,0x00,0x0E,0x0C,0x10,0x14,0x10,0x24,0x10,0x44,0x11,0x84,0x0E,0x0C,0x00,0x00},/*"2",18*/
+{0x00,0x00,0x0C,0x18,0x10,0x04,0x11,0x04,0x11,0x04,0x12,0x88,0x0C,0x70,0x00,0x00},/*"3",19*/
+{0x00,0x00,0x00,0xE0,0x03,0x20,0x04,0x24,0x08,0x24,0x1F,0xFC,0x00,0x24,0x00,0x00},/*"4",20*/
+{0x00,0x00,0x1F,0x98,0x10,0x84,0x11,0x04,0x11,0x04,0x10,0x88,0x10,0x70,0x00,0x00},/*"5",21*/
+{0x00,0x00,0x07,0xF0,0x08,0x88,0x11,0x04,0x11,0x04,0x18,0x88,0x00,0x70,0x00,0x00},/*"6",22*/
+{0x00,0x00,0x1C,0x00,0x10,0x00,0x10,0xFC,0x13,0x00,0x1C,0x00,0x10,0x00,0x00,0x00},/*"7",23*/
+{0x00,0x00,0x0E,0x38,0x11,0x44,0x10,0x84,0x10,0x84,0x11,0x44,0x0E,0x38,0x00,0x00},/*"8",24*/
+{0x00,0x00,0x07,0x00,0x08,0x8C,0x10,0x44,0x10,0x44,0x08,0x88,0x07,0xF0,0x00,0x00},/*"9",25*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
+{0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
+{0x00,0x00,0x00,0x80,0x01,0x40,0x02,0x20,0x04,0x10,0x08,0x08,0x10,0x04,0x00,0x00},/*"<",28*/
+{0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x00,0x00},/*"=",29*/
+{0x00,0x00,0x10,0x04,0x08,0x08,0x04,0x10,0x02,0x20,0x01,0x40,0x00,0x80,0x00,0x00},/*">",30*/
+{0x00,0x00,0x0E,0x00,0x12,0x00,0x10,0x0C,0x10,0x6C,0x10,0x80,0x0F,0x00,0x00,0x00},/*"?",31*/
+{0x03,0xE0,0x0C,0x18,0x13,0xE4,0x14,0x24,0x17,0xC4,0x08,0x28,0x07,0xD0,0x00,0x00},/*"@",32*/
+{0x00,0x04,0x00,0x3C,0x03,0xC4,0x1C,0x40,0x07,0x40,0x00,0xE4,0x00,0x1C,0x00,0x04},/*"A",33*/
+{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x11,0x04,0x0E,0x88,0x00,0x70,0x00,0x00},/*"B",34*/
+{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x04,0x10,0x08,0x1C,0x10,0x00,0x00},/*"C",35*/
+{0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"D",36*/
+{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x17,0xC4,0x10,0x04,0x08,0x18,0x00,0x00},/*"E",37*/
+{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x17,0xC0,0x10,0x00,0x08,0x00,0x00,0x00},/*"F",38*/
+{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x44,0x1C,0x78,0x00,0x40,0x00,0x00},/*"G",39*/
+{0x10,0x04,0x1F,0xFC,0x10,0x84,0x00,0x80,0x00,0x80,0x10,0x84,0x1F,0xFC,0x10,0x04},/*"H",40*/
+{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x00,0x00,0x00,0x00},/*"I",41*/
+{0x00,0x03,0x00,0x01,0x10,0x01,0x10,0x01,0x1F,0xFE,0x10,0x00,0x10,0x00,0x00,0x00},/*"J",42*/
+{0x10,0x04,0x1F,0xFC,0x11,0x04,0x03,0x80,0x14,0x64,0x18,0x1C,0x10,0x04,0x00,0x00},/*"K",43*/
+{0x10,0x04,0x1F,0xFC,0x10,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x0C,0x00,0x00},/*"L",44*/
+{0x10,0x04,0x1F,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x1F,0xFC,0x10,0x04,0x00,0x00},/*"M",45*/
+{0x10,0x04,0x1F,0xFC,0x0C,0x04,0x03,0x00,0x00,0xE0,0x10,0x18,0x1F,0xFC,0x10,0x00},/*"N",46*/
+{0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"O",47*/
+{0x10,0x04,0x1F,0xFC,0x10,0x84,0x10,0x80,0x10,0x80,0x10,0x80,0x0F,0x00,0x00,0x00},/*"P",48*/
+{0x07,0xF0,0x08,0x18,0x10,0x24,0x10,0x24,0x10,0x1C,0x08,0x0A,0x07,0xF2,0x00,0x00},/*"Q",49*/
+{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x11,0xC0,0x11,0x30,0x0E,0x0C,0x00,0x04},/*"R",50*/
+{0x00,0x00,0x0E,0x1C,0x11,0x04,0x10,0x84,0x10,0x84,0x10,0x44,0x1C,0x38,0x00,0x00},/*"S",51*/
+{0x18,0x00,0x10,0x00,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x00,0x18,0x00,0x00,0x00},/*"T",52*/
+{0x10,0x00,0x1F,0xF8,0x10,0x04,0x00,0x04,0x00,0x04,0x10,0x04,0x1F,0xF8,0x10,0x00},/*"U",53*/
+{0x10,0x00,0x1E,0x00,0x11,0xE0,0x00,0x1C,0x00,0x70,0x13,0x80,0x1C,0x00,0x10,0x00},/*"V",54*/
+{0x1F,0xC0,0x10,0x3C,0x00,0xE0,0x1F,0x00,0x00,0xE0,0x10,0x3C,0x1F,0xC0,0x00,0x00},/*"W",55*/
+{0x10,0x04,0x18,0x0C,0x16,0x34,0x01,0xC0,0x01,0xC0,0x16,0x34,0x18,0x0C,0x10,0x04},/*"X",56*/
+{0x10,0x00,0x1C,0x00,0x13,0x04,0x00,0xFC,0x13,0x04,0x1C,0x00,0x10,0x00,0x00,0x00},/*"Y",57*/
+{0x08,0x04,0x10,0x1C,0x10,0x64,0x10,0x84,0x13,0x04,0x1C,0x04,0x10,0x18,0x00,0x00},/*"Z",58*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFE,0x40,0x02,0x40,0x02,0x40,0x02,0x00,0x00},/*"[",59*/
+{0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x80,0x00,0x60,0x00,0x1C,0x00,0x03,0x00,0x00},/*"\",60*/
+{0x00,0x00,0x40,0x02,0x40,0x02,0x40,0x02,0x7F,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/
+{0x00,0x00,0x00,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00},/*"^",62*/
+{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01},/*"_",63*/
+{0x00,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
+{0x00,0x00,0x00,0x98,0x01,0x24,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xFC,0x00,0x04},/*"a",65*/
+{0x10,0x00,0x1F,0xFC,0x00,0x88,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"b",66*/
+{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x00},/*"c",67*/
+{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x11,0x08,0x1F,0xFC,0x00,0x04},/*"d",68*/
+{0x00,0x00,0x00,0xF8,0x01,0x44,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xC8,0x00,0x00},/*"e",69*/
+{0x00,0x00,0x01,0x04,0x01,0x04,0x0F,0xFC,0x11,0x04,0x11,0x04,0x11,0x00,0x18,0x00},/*"f",70*/
+{0x00,0x00,0x00,0xD6,0x01,0x29,0x01,0x29,0x01,0x29,0x01,0xC9,0x01,0x06,0x00,0x00},/*"g",71*/
+{0x10,0x04,0x1F,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"h",72*/
+{0x00,0x00,0x01,0x04,0x19,0x04,0x19,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"i",73*/
+{0x00,0x00,0x00,0x03,0x00,0x01,0x01,0x01,0x19,0x01,0x19,0xFE,0x00,0x00,0x00,0x00},/*"j",74*/
+{0x10,0x04,0x1F,0xFC,0x00,0x24,0x00,0x40,0x01,0xB4,0x01,0x0C,0x01,0x04,0x00,0x00},/*"k",75*/
+{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"l",76*/
+{0x01,0x04,0x01,0xFC,0x01,0x04,0x01,0x00,0x01,0xFC,0x01,0x04,0x01,0x00,0x00,0xFC},/*"m",77*/
+{0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"n",78*/
+{0x00,0x00,0x00,0xF8,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0xF8,0x00,0x00},/*"o",79*/
+{0x01,0x01,0x01,0xFF,0x00,0x85,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"p",80*/
+{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x05,0x01,0xFF,0x00,0x01},/*"q",81*/
+{0x01,0x04,0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x04,0x01,0x00,0x01,0x80,0x00,0x00},/*"r",82*/
+{0x00,0x00,0x00,0xCC,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x98,0x00,0x00},/*"s",83*/
+{0x00,0x00,0x01,0x00,0x01,0x00,0x07,0xF8,0x01,0x04,0x01,0x04,0x00,0x00,0x00,0x00},/*"t",84*/
+{0x01,0x00,0x01,0xF8,0x00,0x04,0x00,0x04,0x00,0x04,0x01,0x08,0x01,0xFC,0x00,0x04},/*"u",85*/
+{0x01,0x00,0x01,0x80,0x01,0x70,0x00,0x0C,0x00,0x10,0x01,0x60,0x01,0x80,0x01,0x00},/*"v",86*/
+{0x01,0xF0,0x01,0x0C,0x00,0x30,0x01,0xC0,0x00,0x30,0x01,0x0C,0x01,0xF0,0x01,0x00},/*"w",87*/
+{0x00,0x00,0x01,0x04,0x01,0x8C,0x00,0x74,0x01,0x70,0x01,0x8C,0x01,0x04,0x00,0x00},/*"x",88*/
+{0x01,0x01,0x01,0x81,0x01,0x71,0x00,0x0E,0x00,0x18,0x01,0x60,0x01,0x80,0x01,0x00},/*"y",89*/
+{0x00,0x00,0x01,0x84,0x01,0x0C,0x01,0x34,0x01,0x44,0x01,0x84,0x01,0x0C,0x00,0x00},/*"z",90*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x3E,0xFC,0x40,0x02,0x40,0x02},/*"{",91*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/
+{0x00,0x00,0x40,0x02,0x40,0x02,0x3E,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
+{0x00,0x00,0x60,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x20,0x00},/*"~",94*/
+};
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HX8347D/font.h	Tue Apr 03 20:08:18 2018 +0000
@@ -0,0 +1,5 @@
+extern const uint8_t c_chFont1206[95][12];
+extern const uint8_t c_chFont1608[95][16];
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Touch/Touch.cpp	Tue Apr 03 20:08:18 2018 +0000
@@ -0,0 +1,277 @@
+
+#include <Touch.h>
+#include <LCD.h>
+#include <XPT2046.h>
+#include <stdlib.h>
+#include <math.h>
+//#include <Serial.h>
+
+
+void TP::tp_init(void)
+{
+	Xpt.xpt2046_init();
+	//Serial.begin(9600, SERIAL_8N1);
+}
+
+void TP::tp_draw_touch_point(uint16_t hwXpos, uint16_t hwYpos, uint16_t hwColor)
+{
+	Tft.lcd_draw_line(hwXpos - 12, hwYpos, hwXpos + 13, hwYpos, hwColor);
+	Tft.lcd_draw_line(hwXpos, hwYpos - 12, hwXpos, hwYpos + 13, hwColor);
+	Tft.lcd_draw_point(hwXpos + 1, hwYpos + 1, hwColor);
+	Tft.lcd_draw_point(hwXpos - 1, hwYpos + 1, hwColor);
+	Tft.lcd_draw_point(hwXpos + 1, hwYpos - 1, hwColor);
+	Tft.lcd_draw_point(hwXpos - 1, hwYpos - 1, hwColor);
+	Tft.lcd_draw_circle(hwXpos, hwYpos, 6, hwColor);
+}
+
+void TP::tp_draw_big_point(uint16_t hwXpos, uint16_t hwYpos, uint16_t hwColor)
+{
+	Tft.lcd_draw_point(hwXpos, hwYpos, hwColor);
+	Tft.lcd_draw_point(hwXpos + 1, hwYpos, hwColor);
+	Tft.lcd_draw_point(hwXpos, hwYpos + 1, hwColor);
+	Tft.lcd_draw_point(hwXpos + 1, hwYpos + 1, hwColor);
+}
+
+void TP::tp_show_info(uint16_t hwXpos0, uint16_t hwYpos0,
+                     uint16_t hwXpos1, uint16_t hwYpos1,
+                     uint16_t hwXpos2, uint16_t hwYpos2,
+                     uint16_t hwXpos3, uint16_t hwYpos3, uint16_t hwFac)
+{
+
+	Tft.lcd_display_string(40, 160, (const uint8_t *)"x1", 16, RED);
+	Tft.lcd_display_string(40 + 80, 160, (const uint8_t *)"y1", 16, RED);
+
+	Tft.lcd_display_string(40, 180, (const uint8_t *)"x2", 16, RED);
+	Tft.lcd_display_string(40 + 80, 180, (const uint8_t *)"y2", 16, RED);
+
+	Tft.lcd_display_string(40, 200, (const uint8_t *)"x3", 16, RED);
+	Tft.lcd_display_string(40 + 80, 200, (const uint8_t *)"y3", 16, RED);
+
+	Tft.lcd_display_string(40, 220, (const uint8_t *)"x4", 16, RED);
+	Tft.lcd_display_string(40 + 80, 220, (const uint8_t *)"y4", 16, RED);
+
+	Tft.lcd_display_string(40, 240, (const uint8_t *)"fac is:", 16, RED);
+
+	Tft.lcd_display_num(40 + 24, 160, hwXpos0, 4, 16, RED);
+	Tft.lcd_display_num(40 + 24 + 80, 160, hwYpos0, 4, 16, RED);
+
+	Tft.lcd_display_num(40 + 24, 180, hwXpos1, 4, 16, RED);
+	Tft.lcd_display_num(40 + 24 + 80, 180, hwYpos1, 4, 16, RED);
+
+	Tft.lcd_display_num(40 + 24, 200, hwXpos2, 4, 16, RED);
+	Tft.lcd_display_num(40 + 24 + 80, 200, hwYpos2, 4, 16, RED);
+
+	Tft.lcd_display_num(40 + 24, 220, hwXpos3, 4, 16, RED);
+	Tft.lcd_display_num(40 + 24 + 80, 220, hwYpos3, 4, 16, RED);
+
+	Tft.lcd_display_num(40 + 56, 240, hwFac, 3, 16, RED);
+}
+
+uint8_t TP::tp_scan(uint8_t chCoordType)
+{
+	if (!(__XPT2046_IRQ_READ())) {
+		if (chCoordType) {
+			Xpt.xpt2046_twice_read_xy(&s_tTouch.hwXpos, &s_tTouch.hwYpos);
+		} else if (Xpt.xpt2046_twice_read_xy(&s_tTouch.hwXpos, &s_tTouch.hwYpos)) {
+			//s_tTouch.hwXpos = 0.066 * s_tTouch.hwXpos + (-12);//s_tTouch.fXfac * s_tTouch.hwXpos + s_tTouch.iXoff;
+			//s_tTouch.hwYpos = (-0.089) * s_tTouch.hwYpos + (352);//s_tTouch.fYfac * s_tTouch.hwYpos + s_tTouch.iYoff;
+			s_tTouch.hwXpos = s_tTouch.fXfac * s_tTouch.hwXpos + s_tTouch.iXoff;
+			s_tTouch.hwYpos = s_tTouch.fYfac * s_tTouch.hwYpos + s_tTouch.iYoff;
+		}
+		if (0 == (s_tTouch.chStatus & TP_PRESS_DOWN)) {
+			s_tTouch.chStatus = TP_PRESS_DOWN | TP_PRESSED;
+			s_tTouch.hwXpos0 = s_tTouch.hwXpos;
+			s_tTouch.hwYpos0 = s_tTouch.hwYpos;
+		} 
+
+	} else {
+		if (s_tTouch.chStatus & TP_PRESS_DOWN) {
+			s_tTouch.chStatus &= ~(1 << 7);
+		} else {
+			s_tTouch.hwXpos0 = 0;
+			s_tTouch.hwYpos0 = 0;
+			s_tTouch.hwXpos = 0xffff;
+			s_tTouch.hwYpos = 0xffff;
+		}
+	}
+
+	return (s_tTouch.chStatus & TP_PRESS_DOWN);
+}
+
+
+void TP::tp_adjust(void)
+{	
+	uint8_t  cnt = 0;
+	uint16_t hwTimeout = 0, d1, d2, pos_temp[4][2];
+	uint32_t tem1, tem2;
+	float fac;				
+
+	Tft.lcd_clear_screen(WHITE);
+	Tft.lcd_display_string(40, 40, (const uint8_t *)"Please use the stylus click the cross on the screen. The cross will always move until the screen adjustment is completed.",
+					16, RED);
+	tp_draw_touch_point(20, 20, RED);
+	s_tTouch.chStatus = 0;
+	s_tTouch.fXfac = 0;
+	while (1) {
+		tp_scan(1);
+		if((s_tTouch.chStatus & 0xC0) == TP_PRESSED) {	
+			hwTimeout = 0;
+			s_tTouch.chStatus &= ~(1 << 6);
+						   			   
+			pos_temp[cnt][0] = s_tTouch.hwXpos;
+			pos_temp[cnt][1] = s_tTouch.hwYpos;
+			cnt ++;	  
+			switch(cnt) {			   
+				case 1:						 
+					tp_draw_touch_point(20, 20, WHITE);
+					tp_draw_touch_point(LCD_WIDTH - 20, 20, RED);
+					break;
+				case 2:
+					tp_draw_touch_point(LCD_WIDTH - 20, 20, WHITE);
+					tp_draw_touch_point(20, LCD_HEIGHT - 20, RED);
+					break;
+				case 3:
+					tp_draw_touch_point(20, LCD_HEIGHT - 20, WHITE);
+					tp_draw_touch_point(LCD_WIDTH - 20, LCD_HEIGHT - 20, RED);
+					break;
+				case 4:	
+					tem1=abs((int16_t)(pos_temp[0][0]-pos_temp[1][0]));//x1-x2
+					tem2=abs((int16_t)(pos_temp[0][1]-pos_temp[1][1]));//y1-y2
+					tem1*=tem1;
+					tem2*=tem2;
+					tem1+=tem2;
+					d1=sqrt(tem1);
+
+					tem1=abs((int16_t)(pos_temp[2][0]-pos_temp[3][0]));//x3-x4
+					tem2=abs((int16_t)(pos_temp[2][1]-pos_temp[3][1]));//y3-y4
+					tem1*=tem1;
+					tem2*=tem2;
+					tem1+=tem2;
+					d2=sqrt(tem1);
+					fac=(float)d1/d2;
+					if(fac<0.95||fac>1.05||d1==0||d2==0) {
+						cnt=0;
+						//Serial.print(d1, DEC);
+						//Serial.print("\t"); 
+						//Serial.print(d2, DEC);
+						//Serial.print("\t"); 
+						//Serial.println(fac, 2);
+ 						tp_show_info(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//??¡§o?¡§oy?Y   
+						delay(1000);
+						Tft.lcd_fill_rect(96, 240, 24, 16, WHITE);
+						tp_draw_touch_point(LCD_WIDTH - 20, LCD_HEIGHT - 20, WHITE);
+						tp_draw_touch_point(20, 20, RED);
+						continue;
+					}
+
+					tem1=abs((int16_t)(pos_temp[0][0]-pos_temp[2][0]));//x1-x3
+					tem2=abs((int16_t)(pos_temp[0][1]-pos_temp[2][1]));//y1-y3
+					tem1*=tem1;
+					tem2*=tem2;
+					tem1+=tem2;
+					d1=sqrt(tem1);//
+
+					tem1=abs((int16_t)(pos_temp[1][0]-pos_temp[3][0]));//x2-x4
+					tem2=abs((int16_t)(pos_temp[1][1]-pos_temp[3][1]));//y2-y4
+					tem1*=tem1;
+					tem2*=tem2;
+					tem1+=tem2;
+					d2=sqrt(tem1);//
+					fac=(float)d1/d2;
+					if(fac<0.95||fac>1.05) {
+						cnt=0;
+						//Serial.print(d1, DEC);
+						//Serial.print("\t"); 
+						//Serial.print(d2, DEC);
+						//Serial.print("\t"); 
+						//Serial.println(fac, 2);
+ 						tp_show_info(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//??¡§o?¡§oy?Y   
+						delay(1000);
+						Tft.lcd_fill_rect(96, 240, 24, 16, WHITE);
+						tp_draw_touch_point(LCD_WIDTH - 20, LCD_HEIGHT - 20, WHITE);
+						tp_draw_touch_point(20, 20, RED);
+						continue;
+					}//
+								   
+					tem1=abs((int16_t)(pos_temp[1][0]-pos_temp[2][0]));//x1-x3
+					tem2=abs((int16_t)(pos_temp[1][1]-pos_temp[2][1]));//y1-y3
+					tem1*=tem1;
+					tem2*=tem2;
+					tem1+=tem2;
+					d1=sqrt(tem1);//
+
+					tem1=abs((int16_t)(pos_temp[0][0]-pos_temp[3][0]));//x2-x4
+					tem2=abs((int16_t)(pos_temp[0][1]-pos_temp[3][1]));//y2-y4
+					tem1*=tem1;
+					tem2*=tem2;
+					tem1+=tem2;
+					d2=sqrt(tem1);//
+					fac=(float)d1/d2;
+					if(fac<0.95||fac>1.05) {
+						cnt=0;	
+						//Serial.print(d1, DEC);
+						//Serial.print("\t"); 
+						//Serial.print(d2, DEC);
+						//Serial.print("\t"); 
+						//Serial.println(fac, 2);
+ 						tp_show_info(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//??¡§o?¡§oy?Y   
+						delay(1000);
+						Tft.lcd_fill_rect(96, 240, 24, 16, WHITE);
+						tp_draw_touch_point(LCD_WIDTH - 20, LCD_HEIGHT - 20, WHITE);
+						tp_draw_touch_point(20, 20, RED);
+						continue;
+					}
+
+					s_tTouch.fXfac = (float)(LCD_WIDTH - 40) / (int16_t)(pos_temp[1][0] - pos_temp[0][0]);	
+					s_tTouch.iXoff = (LCD_WIDTH - s_tTouch.fXfac * (pos_temp[1][0] + pos_temp[0][0])) / 2;
+
+					s_tTouch.fYfac = (float)(LCD_HEIGHT - 40) / (int16_t)(pos_temp[2][1] - pos_temp[0][1]);	  
+					s_tTouch.iYoff = (LCD_HEIGHT - s_tTouch.fYfac * (pos_temp[2][1] + pos_temp[0][1])) / 2;
+
+					
+					if(abs(s_tTouch.fXfac) > 2 || abs(s_tTouch.fYfac) > 2) {
+						cnt=0;
+ 				    	tp_draw_touch_point(LCD_WIDTH - 20, LCD_HEIGHT - 20, WHITE);
+						tp_draw_touch_point(20, 20, RED);								
+						Tft.lcd_display_string(40, 26, (const uint8_t *)"TP Need readjust!", 16, RED);
+						continue;
+					}
+					Tft.lcd_clear_screen(WHITE);
+					Tft.lcd_display_string(35, 110, (const uint8_t *)"Touch Screen Adjust OK!", 16, BLUE);
+					delay(1000); 
+ 					Tft.lcd_clear_screen(WHITE);  
+					return;				 
+			}
+		}
+		delay(10);
+		if (++ hwTimeout >= 1000) {
+			break;
+		}
+ 	}
+}
+
+
+void TP::tp_dialog(void)
+{
+	Tft.lcd_clear_screen(WHITE);
+	Tft.lcd_display_string(LCD_WIDTH - 40, 0, (const uint8_t *)"CLEAR", 16, BLUE);
+}
+
+void TP::tp_draw_board(void)
+{
+	tp_scan(0);
+	if (s_tTouch.chStatus & TP_PRESS_DOWN) {
+		if (s_tTouch.hwXpos < LCD_WIDTH && s_tTouch.hwYpos < LCD_HEIGHT) {
+			if (s_tTouch.hwXpos > (LCD_WIDTH - 40) && s_tTouch.hwYpos < 16) {
+				tp_dialog();
+			} else {
+				tp_draw_big_point(s_tTouch.hwXpos, s_tTouch.hwYpos, RED);
+			}
+		}
+	}
+}
+
+TP Tp = TP();
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Touch/Touch.h	Tue Apr 03 20:08:18 2018 +0000
@@ -0,0 +1,51 @@
+#ifndef __TOUCH_H_
+#define __TOUCH_H_
+
+#include "system.h"
+
+
+#define TP_PRESS_DOWN           0x80
+#define TP_PRESSED              0x40
+
+typedef struct {
+	uint16_t hwXpos0;
+	uint16_t hwYpos0;
+	uint16_t hwXpos;
+	uint16_t hwYpos;
+	uint8_t chStatus;
+	uint8_t chType;
+	short iXoff;
+	short iYoff;
+	float fXfac;
+	float fYfac;
+} tp_dev_t;
+
+class TP
+{
+private :
+	tp_dev_t s_tTouch;
+	uint8_t tp_scan(uint8_t chCoordType);
+	
+	void tp_show_info(uint16_t hwXpos0, uint16_t hwYpos0,
+						 uint16_t hwXpos1, uint16_t hwYpos1,
+						 uint16_t hwXpos2, uint16_t hwYpos2,
+						 uint16_t hwXpos3, uint16_t hwYpos3, uint16_t hwFac);
+	void tp_draw_big_point(uint16_t hwXpos, uint16_t hwYpos, uint16_t hwColor);
+	void tp_draw_touch_point(uint16_t hwXpos, uint16_t hwYpos, uint16_t hwColor);
+
+public:
+	
+
+	void tp_init(void);
+	void tp_adjust(void);
+	void tp_dialog(void);
+	void tp_draw_board(void);
+};
+
+extern TP Tp;
+
+#endif
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/XPT2046/XPT2046.cpp	Tue Apr 03 20:08:18 2018 +0000
@@ -0,0 +1,48 @@
+
+#include <XPT2046.h>
+
+XPT::XPT()
+	:  __XPT2046_CS_OUT()
+	, __XPT2046_IRQ_IN()
+{
+	__SD_CS_DISABLE();
+}
+
+void XPT::xpt2046_init(void)
+{
+	uint16_t hwXpos, hwYpos;
+		
+	__XPT2046_CS_SET();
+
+	xpt2046_read_xy(&hwXpos, &hwYpos);
+}
+
+void XPT::xpt2046_read_xy(uint16_t *phwXpos, uint16_t *phwYpos)
+{
+	*phwXpos = xpt2046_read_average(0xD0);
+	*phwYpos = xpt2046_read_average(0x90);
+}
+
+
+#define ERR_RANGE 50
+bool XPT::xpt2046_twice_read_xy(uint16_t *phwXpos, uint16_t *phwYpos)
+{
+	uint16_t hwXpos1, hwYpos1, hwXpos2, hwYpos2;
+
+	xpt2046_read_xy(&hwXpos1, &hwYpos1);
+	xpt2046_read_xy(&hwXpos2, &hwYpos2);
+
+	if (((hwXpos2 <= hwXpos1 && hwXpos1 < hwXpos2 + ERR_RANGE) || (hwXpos1 <= hwXpos2 && hwXpos2 < hwXpos1 + ERR_RANGE))
+	&& ((hwYpos2 <= hwYpos1 && hwYpos1 < hwYpos2 + ERR_RANGE) || (hwYpos1 <= hwYpos2 && hwYpos2 < hwYpos1 + ERR_RANGE))) {
+		*phwXpos = (hwXpos1 + hwXpos2) / 2;
+		*phwYpos = (hwYpos1 + hwYpos2) / 2;
+		return true;
+	}
+
+	return false;
+}
+
+XPT Xpt = XPT();
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/XPT2046/XPT2046.h	Tue Apr 03 20:08:18 2018 +0000
@@ -0,0 +1,111 @@
+#ifndef __XPT2046_H
+#define __XPT2046_H
+
+#include "mbed.h"
+#include "system.h"
+#include "interfaces.h"
+
+
+#define BIT(__N)  (uint8_t)(1 << (__N))
+
+#define TP_IRQ_PIN         PB_3
+#define TP_CS_PIN          PB_5
+#define SD_CS_PIN          PB_4
+
+#define __XPT2046_CS_OUT()      tp_cs_pin(TP_CS_PIN)
+#define __XPT2046_CS_SET()      tp_cs_pin.write(HIGH)
+#define __XPT2046_CS_CLR()      tp_cs_pin.write(LOW)
+#define __XPT2046_CS_DISABLE()  __XPT2046_CS_SET()
+
+#define __XPT2046_IRQ_IN()      tp_irq_pin(TP_IRQ_PIN, PullUp)
+#define __XPT2046_IRQ_READ()    tp_irq_pin.read()
+
+#define __SD_CS_DISABLE()       do { \
+                                    DigitalOut sd_cs_pin(SD_CS_PIN); \
+                                    sd_cs_pin.write(HIGH); \
+                                } while (0)
+                                
+#define __XPT2046_WRITE_BYTE(__DATA)  HwInterfaces::getHwInterface<SPI__1>().handle().write(__DATA)
+
+
+
+
+
+
+
+
+
+
+class XPT
+{
+
+public:
+
+    XPT();
+    
+    inline uint8_t xpt2046_write_byte(uint8_t chData)
+    {
+        uint8_t x = 0;
+        HwInterfaces::getHwInterface<SPI__1>().handle().write(x);
+        return __XPT2046_WRITE_BYTE(chData);
+    }
+
+    uint16_t xpt2046_read_ad_value(uint8_t chCmd)
+    {
+        uint16_t hwData = 0;
+    
+        __XPT2046_CS_CLR();
+        xpt2046_write_byte(chCmd);
+        hwData = xpt2046_write_byte(0x00);
+        hwData <<= 8;
+        hwData |= xpt2046_write_byte(0x00);
+        hwData >>= 4;
+       __XPT2046_CS_SET();
+        
+        return hwData;
+    }
+    
+#define READ_TIMES  5
+#define LOST_NUM    1
+    uint16_t xpt2046_read_average(uint8_t chCmd)
+    {
+        uint8_t i, j;
+        uint16_t hwbuffer[READ_TIMES], hwSum = 0, hwTemp;
+
+        for (i = 0; i < READ_TIMES; i ++) {
+            hwbuffer[i] = xpt2046_read_ad_value(chCmd);
+        }
+        for (i = 0; i < READ_TIMES - 1; i ++) {
+            for (j = i + 1; j < READ_TIMES; j ++) {
+                if (hwbuffer[i] > hwbuffer[j]) {
+                    hwTemp = hwbuffer[i];
+                    hwbuffer[i] = hwbuffer[j];
+                    hwbuffer[j] = hwTemp;
+                }
+            }
+        }
+        for (i = LOST_NUM; i < READ_TIMES - LOST_NUM; i ++) {
+            hwSum += hwbuffer[i];
+        }
+        hwTemp = hwSum / (READ_TIMES - 2 * LOST_NUM);
+
+        return hwTemp;
+    }
+    
+    void xpt2046_init(void);
+    void xpt2046_read_xy(uint16_t *phwXpos, uint16_t *phwYpos);
+    bool xpt2046_twice_read_xy(uint16_t *phwXpos, uint16_t *phwYpos);
+    
+private:
+    DigitalOut tp_cs_pin;
+    DigitalIn tp_irq_pin;
+};
+
+extern uint8_t g_chXcmd, g_chYcmd;
+extern XPT Xpt;
+
+#endif
+
+
+
+