Library files for using Seeed Studio TFT Touch Shield for Arduino (ST7781R controller) together with ELMICRO TestBed for mbed. Featuring a short example program of how to calibrate the touch screen. Some basic drawing functions are also included (circle, rectangle, lines, text).
Revision 0:db0d63650413, committed 2012-06-28
- Comitter:
- elmicro
- Date:
- Thu Jun 28 10:12:07 2012 +0000
- Commit message:
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/2d_draw.c Thu Jun 28 10:12:07 2012 +0000 @@ -0,0 +1,310 @@ +#include "2d_draw.h" +#include "TFT.h" +#include "touch.h" + +//unsigned char DispDir; + +/* =================================================================== + routine: DrawCircle + purpose: Guess what?! + parameters: <posX, posY> Middlepoint of circle (pixel-aligned) + <radius> radius of circle (in pixels) + <color> + date: 2012-06-27 + author: Seeed Studio + co-author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void DrawCircle(unsigned int posX, unsigned int posY, unsigned int radius, unsigned int color) +{ + int x = -radius, y = 0, err = 2 - 2 * radius, e2; + do { + SetPixel(posX - x, posY + y, color); + SetPixel(posX + x, posY + y, color); + SetPixel(posX + x, posY - y, color); + SetPixel(posX - x, posY - y, color); + 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); +} + +/* =================================================================== + routine: DrawHorizontalLine + parameters: <posX, posY> starting point (pixel-aligned) + <length> length of line (in pixels) + <color> + date: 2012-06-27 + author: Seeed Studio + co-author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void DrawHorizontalLine(unsigned int posX, unsigned int posY,unsigned int length,unsigned int color) +{ + SetXY(posX, posY); + SetOrientation(0); + if(length + posX > TFTData.XRes) + { + length = TFTData.XRes - posX; + } + for(unsigned int i=0; i<length; i++) + { + SendData(color); + } +} + + +/* =================================================================== + routine: DrawVerticalLine + parameters: <posX, posY> starting point (pixel-aligned) + <length> length of line (in pixels) + <color> + date: 2012-06-27 + author: Seeed Studio + co-author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void DrawVerticalLine(unsigned int posX, unsigned int posY,unsigned int length,unsigned int color) +{ + SetXY(posX,posY); + SetOrientation(1); + if(length + posY > TFTData.YRes) + { + length = TFTData.YRes - posY; + } + + for(unsigned int i=0; i<length; i++) + { + SendData(color); + } +} + + + /* =================================================================== + routine: DrawLine + purpose: Connects two points by a line with width of 1 pixel + parameters: <xstart, xend> starting point (pixel-aligned) + <xstart, xend> ending point (pixel-aligned) + <iColor> + date: 2012-06-27 + note: Based on the Bresenham-Algorithm for rasterizing + vector elements + author: (C)2006 Stefan Kleinwort (mikrocontroller.net) + co-author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ + +void DrawLine(int xstart, int ystart, int xend ,int yend, int iColor) +{ + int x, y, t, dist, xerr, yerr, dx, dy, incx, incy; + + /* calculate distances of both directions */ + dx = xend - xstart; + dy = yend - ystart; + + /* calculate polarity */ + if(dx<0) + { + incx = -1; + dx = -dx; + } + else + incx = dx ? 1 : 0; + + if(dy < 0) + { + incy = -1; + dy = -dy; + } + else + incy = dy ? 1 : 0; + + /* determine larger distance */ + dist = (dx > dy) ? dx : dy; + + /* loop init */ + x = xstart; + y = ystart; + xerr = yerr = (dist) >> 1; //dx; + + /* Calculate pixel */ + for(t = 0; t < dist; ++t) + { + SetPixel(x,y,iColor); + xerr += dx; + yerr += dy; + if(xerr >= dist) + { + xerr -= dist; + x += incx; + } + + if(yerr >= dist) + { + yerr -= dist; + y += incy; + } + } + SetPixel(x, y, iColor); +} + + +/* =================================================================== + routine: DrawRectangle + purpose: Draws outlined rectangle with width of 1 pixel + parameters: <posX, posY> starting point (pixel-aligned) + <length> length of rectangle (in pixels) + <height> height of rectangle (in pixels) + <color> + date: 2012-06-27 + author: Seeed Studio + co-author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void DrawRectangle(unsigned int posX, unsigned int posY, unsigned int length, unsigned int height, unsigned int color) +{ + DrawHorizontalLine(posX, posY, length, color); + DrawHorizontalLine(posX, posY+height, length, color); + DrawVerticalLine (posX, posY, height, color); + DrawVerticalLine (posX + length, posY, height, color); +} + + +/* =================================================================== + routine: FillRectangle + purpose: Draws solid rectangle + parameters: <posX, posY> starting point (pixel-aligned) + <length> length of rectangle (in pixels) + <height> height of rectangle (in pixels) + <color> + date: 2012-06-27 + author: Seeed Studio + co-author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void FillRectangle(unsigned int posX, unsigned int posY, unsigned int length, unsigned int width, unsigned int color) +{ + for(unsigned int i=0; i<width; i++) + { + switch(DispDir) + { + case DOWN2UP: + DrawHorizontalLine(posX, posY-i, length, color); + break; + case RIGHT2LEFT: + DrawHorizontalLine(posX, posY-i, length, color); + break; + case UP2DOWN: + DrawHorizontalLine(posX, posY+i, length, color); + break; + case LEFT2RIGHT: + default: + DrawHorizontalLine(posX, posY+i, length, color); + } + } +} + +/* =================================================================== + routine: DrawAscii + purpose: Displays single character + parameters: <ascii> character to display + <posX, posY> pixel-aligned starting point + <size> scaling factor of character + (size=1 means no scaling, 2 doubles the size) + <fgcolor> + note: Needs a rastered font definition table with 8 + bytes per character (const unsigned char simpleFont[][8]) + date: 2012-06-27 + author: Seeed Studio + co-author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void DrawAscii(unsigned char ascii,unsigned int posX, unsigned int posY,unsigned int size, unsigned int fgcolor) +{ + SetXY(posX, posY); + + if( (ascii < 0x20) || (ascii > 0x7e) ) //check for valid ASCII char + { + ascii = '?'; //char not supported + } + for(unsigned char i=0; i<8; i++) + { + unsigned char temp = simpleFont[ascii - 0x20][i]; + for(unsigned char f=0; f<8; f++) + { + if( (temp>>f) & 0x01 ) + { + switch(DispDir) + { + case DOWN2UP: + FillRectangle(posX+f*size, posY-i*size, size, size, fgcolor); + break; + case RIGHT2LEFT: + FillRectangle(posX-i*size, posY-f*size, size, size, fgcolor); + break; + case UP2DOWN: + FillRectangle(posX-f*size, posY+i*size, size, size, fgcolor); + break; + case LEFT2RIGHT: + default: + FillRectangle(posX+i*size, posY+f*size, size, size, fgcolor); + } + } + } + } +} + +/* =================================================================== + routine: DrawString + purpose: Displays string of characters + parameters: <*string> pointer to null-terminated (!) character + array + <posX, posY> pixel-aligned starting point + <size> scaling factor of characters (see DrawAscii) + <fgcolor> + note: based on DrawAscii function + date: 2012-06-27 + author: Seeed Studio + co-author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void DrawString(char *string,unsigned int posX, unsigned int posY,unsigned int size,unsigned int fgcolor) +{ + while(*string) + { + DrawAscii(*string, posX, posY, size, fgcolor); + *string++; + switch(DispDir) + { + case DOWN2UP: + if(posY > 0) posY-=8*size; //Change position to next char + break; + case RIGHT2LEFT: + if(posX > 0) posX-=8*size; + break; + case UP2DOWN: + if(posY < TFTData.YRes) posY+=8*size; + break; + case LEFT2RIGHT: + default: + if(posX < TFTData.XRes) posX+=8*size; + } + } +} + + +void DispPolygon2D(int *pIn, int iCorners, int iColor) +{ + int x, x1,y1; + x1=*pIn; + y1=*(pIn+1); + for(x=2; x<=iCorners; x++) + { + DrawLine(*pIn, *(pIn+1), *(pIn+2), *(pIn+3), iColor); + pIn+=2; + } + DrawLine(*pIn, *(pIn+1), x1, y1, iColor); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/2d_draw.h Thu Jun 28 10:12:07 2012 +0000 @@ -0,0 +1,13 @@ +#include "font.c" +#include "TFT.h" + +void DrawAscii (unsigned char ascii,unsigned int posX, unsigned int posY,unsigned int size, unsigned int fgcolor); +void DrawString (char *string,unsigned int posX, unsigned int posY,unsigned int size,unsigned int fgcolor); +void FillRectangle (unsigned int posX, unsigned int posY, unsigned int length, unsigned int height, unsigned int color); +void DrawRectangle (unsigned int posX, unsigned int posY, unsigned int length, unsigned int height, unsigned int color); +void DrawHorizontalLine (unsigned int posX, unsigned int posY, unsigned int length, unsigned int color); +void DrawCircle (unsigned int posX, unsigned int posY, unsigned int radius, unsigned int color); +void DrawVerticalLine (unsigned int posX, unsigned int posY, unsigned int length, unsigned int color); +void DrawLine (int xstart, int ystart, int xend ,int yend, int iColor); +void DispPolygon2D (int *pIn, int iCorners, int iColor); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TFT.cpp Thu Jun 28 10:12:07 2012 +0000 @@ -0,0 +1,400 @@ +#include "TFT.h" +#include "shortcuts.h" +#include "touch.h" + +unsigned char DispDir=0; + + +/* =================================================================== + routine: CtrlOutput + purpose: Sets mbed's I/Os to act as RS, RD, RW, CS output + parameters: none + returns: nothing + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void CtrlOutput(void) +{ + LPC_GPIO0->FIODIR |= BIT15+BIT16+BIT17+BIT18; +} + + +/* =================================================================== + routine: PinOutput + purpose: Sets mbed's I/Os to act as 8 bit data output + parameters: none + returns: nothing + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void PinOutput(void) +{ + LPC_GPIO0->FIODIR |= BIT0+BIT1; + LPC_GPIO2->FIODIR |= BIT0+BIT1+BIT2+BIT3+BIT4+BIT5; +} + + +/* =================================================================== + routine: PinInput + purpose: Sets mbed's I/Os to act as 8 bit data input + parameters: none + returns: nothing + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void PinInput(void) +{ + LPC_GPIO0->FIODIR &= ~(BIT0+BIT1); + LPC_GPIO2->FIODIR &= ~(BIT0+BIT1+BIT2+BIT3+BIT4+BIT5); +} + +/* =================================================================== + routine: PinLow + purpose: Sets 8 bit data output to 0x00 (all outputs low) + parameters: none + returns: nothing + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void PinLow(void) +{ + LPC_GPIO0->FIOCLR = BIT0+BIT1; + LPC_GPIO2->FIOCLR = BIT0+BIT1+BIT2+BIT3+BIT4+BIT5; +} + +/* =================================================================== + routine: PinHigh + purpose: Sets 8 bit data output to 0xff (all outputs high) + parameters: none + returns: nothing + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void PinHigh(void) +{ + LPC_GPIO0->FIOSET = BIT0+BIT1; + LPC_GPIO2->FIOSET = BIT0+BIT1+BIT2+BIT3+BIT4+BIT5; +} + +/* =================================================================== + routine: PushData + purpose: Sets the 8 data outputs corresponding to data byte + which shall be transmitted to LCD + parameters: <data> byte of data for TX + returns: nothing + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void PushData(unsigned char data) +{ + LPC_GPIO0->FIOCLR = 0x03; //set all outputs low + LPC_GPIO2->FIOCLR = 0x3f; + //as the outputs are not in order and are splittet onto two ports, + //the data byte has to be read bit-by-bit and each bit has to set + //a different output pin + LPC_GPIO0->FIOSET = data&BIT0 | (data&BIT2)>>1; + LPC_GPIO2->FIOSET = (data&BIT6) >> 6 | (data&BIT5) >> 4 | (data&BIT7) >> 5 + | (data&BIT4) >> 1 | (data&BIT3) << 1 | (data&BIT1) << 4; +} + +/* NOT YET TESTED */ +unsigned char GetData(void) +{ + unsigned char data = 0; + wait(0.001); + data = (LPC_GPIO0->FIOPIN&BIT0) | (LPC_GPIO0->FIOPIN&BIT2) >> 1; + data |= (LPC_GPIO2->FIOPIN&BIT6) >> 6 | (LPC_GPIO2->FIOPIN&BIT5) >> 4 + | (LPC_GPIO2->FIOPIN&BIT7) >> 5 | (LPC_GPIO2->FIOPIN&BIT4) >> 1 + | (LPC_GPIO2->FIOPIN&BIT3) << 1 | (LPC_GPIO2->FIOPIN&BIT2) << 3; + return data; +} + +/* =================================================================== + routine: SendCommand + purpose: Transmits a command code to the LCD controller + parameters: <command> command byte + returns: nothing + note: Each transmit to the LCD controller has to be 16 bits + wide, which results in 2 bytes per message. + Commands are only 8 bits wide, so the upper bits + have to be all zero + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void SendCommand(unsigned char command) +{ + LPC_GPIO0->FIOCLR = BIT16+BIT18; //CS and RS low + LPC_GPIO0->FIOSET = BIT17+BIT15; //RD and WR high + LPC_GPIO0->FIOCLR = BIT17; //WR low + PushData(0); //commands have only 8 bits + LPC_GPIO0->FIOSET = BIT17; //WR high + for(int x=0; x<3; x++); //wait + + LPC_GPIO0->FIOCLR = BIT17; //WR low + PushData(command); + LPC_GPIO0->FIOSET = BIT17; //WR high + LPC_GPIO0->FIOSET = BIT16; //CS high +} + +/* =================================================================== + routine: SendData + purpose: Transmits 16 data bits to the LCD controller + parameters: <data> data value + returns: nothing + note: Transmit has to be splitted into 2 transfers + as interface is only 8 bits wide + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void SendData(unsigned int data) +{ + LPC_GPIO0->FIOCLR = BIT16; //CS low + LPC_GPIO0->FIOSET = BIT18+BIT15; //RD and RS high + LPC_GPIO0->FIOCLR = BIT17; //WR low + PushData((data&0xff00)>>8); //send first byte + LPC_GPIO0->FIOSET = BIT17; //WR high + for(int x=0; x<3; x++); //wait + + LPC_GPIO0->FIOCLR = BIT17; //WR low + PushData(data&0xff); + LPC_GPIO0->FIOSET = BIT17; //WR high + LPC_GPIO0->FIOSET = BIT16; //CS high +} + + +/* NOT YET TESTED */ +unsigned int ReadRegister(unsigned int reg) +{ + unsigned int data=0; + + LPC_GPIO0->FIOCLR = BIT16+BIT18; //CS and RS low + LPC_GPIO0->FIOSET = BIT15; //RD high + PinOutput(); + LPC_GPIO0->FIOCLR = BIT17; //WR low + PushData(0); + LPC_GPIO0->FIOSET = BIT17; //WR high + LPC_GPIO0->FIOCLR = BIT17; //WR low + PushData(reg); + LPC_GPIO0->FIOSET = BIT17; //WR high + PinInput(); + PinLow(); /* ?Necessary? */ + LPC_GPIO0->FIOSET = BIT18; //RS high + LPC_GPIO0->FIOCLR = BIT15; //RD low + LPC_GPIO0->FIOSET = BIT15; //RD high + data = GetData(); + LPC_GPIO0->FIOSET = BIT16; //CS high + PinOutput(); + return data; +} + + +void ClearScreen(unsigned int color) +{ + for(unsigned char i=0;i<2;i++) + { + for(unsigned int f=0;f<38400;f++) + { + SendData(color); //black + } + } +} + + +void Init(void) +{ + /* PRELOAD TFTData STRUCTURE WITH PRESET/DEFAULT VALUES */ + TFTData.XRes = TFTRESX; + TFTData.YRes = TFTRESY; + TFTData.Xmin = 1250; //should be calculated + TFTData.Xmax = 2800; //for each device! + TFTData.Ymin = 900; + TFTData.Ymax = 3100; + TFTData.Xscale = 6875; + TFTData.Yscale = 6875; + DispDir = LEFT2RIGHT; + + /* SETUP MBED FOR CONNECTION WITH TFT */ + CtrlOutput(); //CS, RD, WR, RS as output + PinOutput(); //8-bit parallel bus + PinLow(); //all output pins are low + + /* INITIALIZATION SEQUENCE */ + wait(0.1); + + SendCommand(0x0001); + SendData(0x0100); + SendCommand(0x0002); + SendData(0x0700); + SendCommand(0x0003); + SendData(0x1030); + SendCommand(0x0004); + SendData(0x0000); + SendCommand(0x0008); + SendData(0x0302); + SendCommand(0x000A); + SendData(0x0000); + SendCommand(0x000C); + SendData(0x0000); + SendCommand(0x000D); + SendData(0x0000); + SendCommand(0x000F); + SendData(0x0000); + wait(0.100); + + SendCommand(0x0030); + SendData(0x0000); + SendCommand(0x0031); + SendData(0x0405); + SendCommand(0x0032); + SendData(0x0203); + SendCommand(0x0035); + SendData(0x0004); + SendCommand(0x0036); + SendData(0x0B07); + SendCommand(0x0037); + SendData(0x0000); + SendCommand(0x0038); + SendData(0x0405); + SendCommand(0x0039); + SendData(0x0203); + SendCommand(0x003c); + SendData(0x0004); + SendCommand(0x003d); + SendData(0x0B07); + SendCommand(0x0020); + SendData(0x0000); + SendCommand(0x0021); + SendData(0x0000); + SendCommand(0x0050); + SendData(0x0000); + SendCommand(0x0051); + SendData(0x00ef); + SendCommand(0x0052); + SendData(0x0000); + SendCommand(0x0053); + SendData(0x013f); + wait(0.100); + + SendCommand(0x0060); + SendData(0xa700); + SendCommand(0x0061); + SendData(0x0001); + SendCommand(0x0090); + SendData(0x003A); + SendCommand(0x0095); + SendData(0x021E); + SendCommand(0x0080); + SendData(0x0000); + SendCommand(0x0081); + SendData(0x0000); + SendCommand(0x0082); + SendData(0x0000); + SendCommand(0x0083); + SendData(0x0000); + SendCommand(0x0084); + SendData(0x0000); + SendCommand(0x0085); + SendData(0x0000); + SendCommand(0x00FF); + SendData(0x0001); + SendCommand(0x00B0); + SendData(0x140D); + SendCommand(0x00FF); + SendData(0x0000); + wait(0.100); + + SendCommand(0x0007); + SendData(0x0133); + + /* WAKEUP TFT FROM STANDBY */ + SendCommand(0x0010); + SendData(0x14E0); + wait(0.100); + + SendCommand(0x0007); + SendData(0x0133); + SendCommand(0x0022); + + /* CLS */ + for(unsigned char i=0;i<2;i++) + { + for(unsigned int f=0;f<38400;f++) + { + SendData(0); //black + } + } +} + + +/* =================================================================== + routine: SetOrientation + purpose: Sets the direction in which the X/Y-position counter + autoincrements (used by DrawRectangle) + parameters: <layout> direction control + returns: nothing + date: 2012-06-27 + author: Seeed Studio + co-author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void SetOrientation(unsigned char layout) +{ + SendCommand(0x03); + SendData((layout==1)?(0x5038):(0x5030)); + SendCommand(0x0022); +} + + +void SetDirection(unsigned char dir) +{ + DispDir = dir; +} + + +/* =================================================================== + routine: SetXY + purpose: Sets virtual "cursor" to specific pixel + parameters: <posX, posY> + returns: nothing + note: In fact, this tells the LCD controller the next + SRAM address to use for the following color value + date: 2012-06-27 + author: Seeed Studio + co-author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void SetXY(unsigned int posX, unsigned int posY) +{ + SendCommand(0x20); //set X + SendData(posX); + SendCommand(0x21); //set Y + SendData(posY); + SendCommand(0x22); //start command for writing into display SRAM +} + + +/* =================================================================== + routine: SetPixel + purpose: Colors a single pixel + parameters: <posX, posY, color> + returns: nothing + note: The most basic function for displaying content onto + the TFT display + date: 2012-06-27 + author: Seeed Studio + co-author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +void SetPixel(unsigned int posX, unsigned int posY, unsigned int color) +{ + SetXY(posX, posY); + SendData(color); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TFT.h Thu Jun 28 10:12:07 2012 +0000 @@ -0,0 +1,47 @@ +#include <mbed.h> + +#ifndef TFT_h +#define TFT_h + +void CtrlOutput (void); +void PinOutput (void); +void PinInput (void); +void PinLow (void); +void PinHigh (void); +void PushData (unsigned char data); +unsigned char GetData (void); +void SendCommand (unsigned char command); +void SendData (unsigned int data); +unsigned int ReadRegister (unsigned int reg); +void Init (void); +void SetPixel (unsigned int posX, unsigned int posY, unsigned int color); +void SetXY (unsigned int posX, unsigned int posY); +void SetOrientation (unsigned char layout); +void SetDirection (unsigned char dir); +void ClearScreen (unsigned int color); + +extern unsigned char DispDir; + +/* TFT HW DEFINITIONS */ +#define TFTRESX 240 +#define TFTRESY 320 +#define LEFT2RIGHT 0 +#define DOWN2UP 1 +#define RIGHT2LEFT 2 +#define UP2DOWN 3 + +/* COLOR DEFINITIONS */ +#define RED 0xf800 +#define GREEN 0x7e00 +#define BLUE 0x001f +#define BLACK 0x0000 +#define YELLOW 0xffe0 +#define WHITE 0xffff +#define CYAN 0x07ff +#define BRIGHT_RED 0xf810 +#define GRAY1 0x8410 +#define GRAY2 0x4208 + + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/font.c Thu Jun 28 10:12:07 2012 +0000 @@ -0,0 +1,111 @@ +/* + ST7781R TFT Library. + + 2011 Copyright (c) Seeed Technology Inc. + +*/ + + +//#include <avr/pgmspace.h> + +const unsigned char simpleFont[][8] = +{ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00}, + {0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00}, + {0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00}, + {0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00}, + {0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00}, + {0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00}, + {0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00}, + {0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00}, + {0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00}, + {0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00}, + {0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00}, + {0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00}, + {0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00}, + {0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00}, + {0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00}, + {0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00}, + {0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00}, + {0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00}, + {0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00}, + {0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00}, + {0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00}, + {0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00}, + {0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00}, + {0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00}, + {0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00}, + {0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00}, + {0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00}, + {0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00}, + {0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00}, + {0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00}, + {0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00}, + {0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00}, + {0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00}, + {0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00}, + {0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00}, + {0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00}, + {0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00}, + {0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00}, + {0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00}, + {0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00}, + {0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00}, + {0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00}, + {0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00}, + {0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00}, + {0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00}, + {0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00}, + {0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00}, + {0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00}, + {0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00}, + {0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00}, + {0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00}, + {0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00}, + {0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00}, + {0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00}, + {0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00}, + {0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00}, + {0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00}, + {0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00}, + {0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00}, + {0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00}, + {0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00}, + {0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00}, + {0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00}, + {0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00}, + {0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00}, + {0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00}, + {0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00}, + {0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00}, + {0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00}, + {0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00}, + {0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00}, + {0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00}, + {0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00}, + {0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00}, + {0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00}, + {0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00}, + {0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00}, + {0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00}, + {0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00}, + {0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00}, + {0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00}, + {0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00}, + {0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00}, + {0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00}, + {0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00}, + {0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00}, + {0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00}, + {0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00}, + {0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00} +}; + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Jun 28 10:12:07 2012 +0000 @@ -0,0 +1,178 @@ +/*########################################################### + Interface library and example program for + Seeed Studio's TFT Touch Shield + + --- + + !DESOLDERING OF TESTBED PARTS NEEDED! + To use the touch input, desolder C3 and R34 + This disables the analogue trimmer R36! + + --- + (C) 2012 Stefan Guenther + Elektronikladen | ELMICRO + ########################################################### */ + +#include "mbed.h" +#include "shortcuts.h" +#include "TFT.h" +#include "2d_draw.h" +#include "touch.h" + + +/* =================================================================== + routine: IntToChars + purpose: Converts integer value into char array with + selectable number base + parameters: <*buffer> pointer to character array + <value> integer value to convert + <spaceonbuffer> max nr. of characters in buffer + <countbase> e.g. 16->HEX formatted string + 2->BIN formatted string + 10->DEC formatted string + date: 2007-05-07 + author: Phantomix + http://www.roboternetz.de/community/archive/index.php + /t-26986.html?s=c3edf0ef1df246f02c67dfa7f316a03f + -------------------------------------------------------------------*/ +void IntToChars (char* buffer, int value, int spaceonbuffer, int countbase) +{ + int workvalue = value; + int i; + int valuetowrite; + int end_i = 0; + + if (value < 0) + { + workvalue = -value; + end_i = 1; + buffer[0] = '-'; + } + + for (i = spaceonbuffer - 1; i >= end_i; i--) + { + valuetowrite = (workvalue % countbase); + if (workvalue == 0) + { + if (i == (spaceonbuffer - 1)) + { + buffer[i] = 48; // ASCII 0 + } else { + buffer[i] = 32; // ASCII SPACE + } + } else { + if (valuetowrite > 9) + { + buffer[i] = valuetowrite + 55; // ASCII A-Z + } else { + buffer[i] = valuetowrite + 48; // ASCII of that character + } + }; + workvalue = (workvalue - valuetowrite) / countbase; + } +} + + + +int main() { + + unsigned int x, y, z; + unsigned int X1, X2, Y1, Y2; + unsigned int x_old = 0; + unsigned int y_old = 0; + + char charX[] = "1111"; //dummy init values + char charY[] = "2222"; + char charZ[] = "2222"; + + Init(); //prepare mbed's I/Os for use with TFT Touch Shield + TouchInit(); //prepare ADC inputs for touch input + + + /* CALIBRATE TOUCH SCREEN */ + /* Alignment of touch input sensor with TFT display + using 2 touch inputs from opposite edges of screen + (10% distance to each borders)*/ + + DrawString("CALIBRATION SEQUENCE", 30, 140, 1, YELLOW); + DrawString("Please tap the circles!", 10, 150, 1, YELLOW); + DrawCircle(24, 32, 10, WHITE); //draw circle 10% right and 10% down from + //upper left corner + int ret = 0; + do //repeat until touch is recognized + { + ret = GetRawTouch(&x, &y, &z); + } while(ret == 0); + + IntToChars(charX, x, 4, 10); //convert raw touch input coordinates + IntToChars(charY, y, 4, 10); //into character string for verbose + IntToChars(charZ, z, 4, 10); //display + + DrawCircle(24, 32, 10, BLACK); //let first circle disappear + X1 = x; //save coordinates of first touch + Y1 = y; + wait(1); + + DrawString(charX, 10, 17, 1, RED); //output read values + DrawString(charY, 10, 32, 1, RED); + DrawString(charZ, 10, 47, 1, RED); + + DrawCircle(216, 288, 10, WHITE); //display next circle, 90% right and 90% down + //from upper left corner + ret=0; + do //do the same for second touch point + { + ret=GetRawTouch(&x, &y, &z); + } while(ret == 0); + + + IntToChars(charX, x, 4, 10); + IntToChars(charY, y, 4, 10); + IntToChars(charZ, z, 4, 10); + + DrawCircle(216, 288, 10, BLACK); + X2 = x; + Y2 = y; + wait(1); + + DrawString(charX, 200,273, 1, RED); + DrawString(charY, 200,288, 1, RED); + DrawString(charZ, 200,303, 1, RED); + + TFTData.Xmin = (9 * X1 - X2) / 8; //start calculation of scale and alignment values + TFTData.Xmax = (9 * X2 - X1) / 8; //and save them into TFT parameter structure + TFTData.Ymin = (9 * Y1 - Y2) / 8; //this structure should be saved into non-volatile + TFTData.Ymax = (9 * Y2 - Y1) / 8; //(e.g. mbed's on-board 2MB flash chip) + + TFTData.Xscale = ( (TFTData.Xmax - TFTData.Xmin) * 1000 ) / TFTData.XRes; + TFTData.Xscale = ( (TFTData.Ymax - TFTData.Ymin) * 1000 ) / TFTData.YRes; + + DrawString("Please tap the circles!", 10, 150, 1, BLACK); + DrawString("COMPLETED", 30, 150, 1, YELLOW); + wait(1); + + ClearScreen(BLACK); + wait(0.3); + + DrawString("DEMO MODE", 30, 140, 1, YELLOW); + DrawString("Touch the screen...", 10, 150, 1, YELLOW); + + + while(1) + { + wait_ms(1); + + if(GetPoint(&x, &y)==1) //check if touch appears + { + DrawCircle(x_old, y_old, 15, BLACK); //clear last touch indicator circle + DrawString("DEMO MODE", 30, 140, 1, YELLOW); + DrawString("Touch the screen...", 10, 150, 1, YELLOW); + DrawCircle(x, y, 15, YELLOW); //set new indicator circle + + x_old=x; //rescue current touch values for next cycle + y_old=y; + } + } +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Jun 28 10:12:07 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shortcuts.h Thu Jun 28 10:12:07 2012 +0000 @@ -0,0 +1,32 @@ +#define BIT31 0x80000000 +#define BIT30 0x40000000 +#define BIT29 0x20000000 +#define BIT28 0x10000000 +#define BIT27 0x08000000 +#define BIT26 0x04000000 +#define BIT25 0x02000000 +#define BIT24 0x01000000 +#define BIT23 0x00800000 +#define BIT22 0x00400000 +#define BIT21 0x00200000 +#define BIT20 0x00100000 +#define BIT19 0x00080000 +#define BIT18 0x00040000 +#define BIT17 0x00020000 +#define BIT16 0x00010000 +#define BIT15 0x00008000 +#define BIT14 0x00004000 +#define BIT13 0x00002000 +#define BIT12 0x00001000 +#define BIT11 0x00000800 +#define BIT10 0x00000400 +#define BIT9 0x00000200 +#define BIT8 0x00000100 +#define BIT7 0x00000080 +#define BIT6 0x00000040 +#define BIT5 0x00000020 +#define BIT4 0x00000010 +#define BIT3 0x00000008 +#define BIT2 0x00000004 +#define BIT1 0x00000002 +#define BIT0 0x00000001
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/touch.cpp Thu Jun 28 10:12:07 2012 +0000 @@ -0,0 +1,251 @@ +#include <LPC17xx.h> +#include "touch.h" +#include "shortcuts.h" + +struct tinit TFTData; + +void TouchInit(void) +{ + LPC_SC->PCONP |= (BIT12); //Enable power to ADC block + LPC_ADC->ADCR = BIT8 | //ADC clock is (25MHz/5) + BIT21; //enable ADC +} + +/* =================================================================== + routine: GetPressure + purpose: Hardware driver for sampling the touch screen using + four ADC-channels + parameters: none + returns: raw value from ADC corresponding to pressure of + touch input + note: "Pressure" actually means how much display area is + supposed to pressure + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned int GetPressure(void) +{ + int tmp; + + LPC_PINCON->PINSEL1 &= ~0x4000; //Y- + LPC_PINCON->PINSEL1 |= 0x10000; //X- + LPC_PINCON->PINSEL1 |= 0x40000; //Y+ + LPC_PINCON->PINSEL1 &= ~0x100000; //X+ + LPC_GPIO0->FIODIR |= BIT23|BIT26; //X- and Y+ as output + LPC_GPIO0->FIOCLR = BIT23; //X- is GND + LPC_GPIO0->FIOSET = BIT26; //Y+ is VCC (3V3) + LPC_ADC->ADCR &= ~0xFF; + LPC_ADC->ADCR |= BIT1; //set X- as ADC input + LPC_ADC->ADCR |= BIT24; //start sampling + while(!(LPC_ADC->ADGDR&BIT31)); //wait for ADC + + tmp = (LPC_ADC->ADGDR&0xFFF0)>>4; //store ADC value + LPC_ADC->ADCR &= ~0xFF; + LPC_ADC->ADCR |= BIT2; //set Y+ as ADC input + LPC_ADC->ADCR |= BIT24; //start another ADC sampling + while(!(LPC_ADC->ADGDR&BIT31)); //wait for it + + //calculate pressure value out of the two samples + //and invert it by subtracting from 2^12 + return(4096 - (tmp - ( (LPC_ADC->ADGDR&0xFFF0) >>4 ) ) ); +} + + +/* =================================================================== + routine: GetTouchX + purpose: Hardware driver for sampling the touch screen using + four ADC-channels + parameters: none + returns: raw value from ADC corresponding to X coordinate of + touch input + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned int GetTouchX(void) +{ + LPC_PINCON->PINSEL1 |= 0x4000; //connects to Y- signal + LPC_PINCON->PINSEL1 &= ~0x10000; // X- + LPC_PINCON->PINSEL1 |= 0x40000; // Y+ + LPC_PINCON->PINSEL1 &= ~0x100000; // X+ + LPC_GPIO0->FIODIR |= BIT24|BIT26; //X+ and X- as output + LPC_GPIO0->FIOCLR = BIT24; //X- set to GND + LPC_GPIO0->FIOSET = BIT26; //X+ set to VCC (3V3) + LPC_ADC->ADCR &= ~0xFF; //clear active ADC channel information + LPC_ADC->ADCR |= BIT2; //set Y- as active ADC channel + LPC_ADC->ADCR |= BIT24; //start ADC sampling + while(!(LPC_ADC->ADGDR&BIT31)); //wait until ADC completes operation + + return((LPC_ADC->ADGDR&0xFFF0)>>4); //extract the 12bit-information +} + + +/* =================================================================== + routine: GetTouchY + purpose: Hardware driver for sampling the touch screen using + four ADC-channels + parameters: none + returns: raw value from ADC corresponding to Y coordinate of + touch input + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned int GetTouchY(void) +{ + LPC_PINCON->PINSEL1 &= ~0x4000; //Y- + LPC_PINCON->PINSEL1 |= 0x10000; //X- + LPC_PINCON->PINSEL1 &= ~0x40000; //Y+ + LPC_PINCON->PINSEL1 |= 0x100000; //X+ + LPC_GPIO0->FIODIR |= BIT23|BIT25; //Y+ and Y- as output + LPC_GPIO0->FIOCLR = BIT23; + LPC_GPIO0->FIOSET = BIT25; + LPC_ADC->ADCR &= ~0xFF; + LPC_ADC->ADCR |= BIT3; + LPC_ADC->ADCR |= BIT24; + while(!(LPC_ADC->ADGDR&BIT31)); + + return((LPC_ADC->ADGDR&0xFFF0)>>4); +} + + +/* =================================================================== + routine: GetRawTouch + purpose: Reads input values from Touchscreen without + processing them (mainly useful for doing a calibration) + parameters: <*x,y,z> pointers to coordinate variables + returns: 1 if touch was recognized + 0 if no touch occured + note: For code explanation, look the GetPoint() function + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned char GetRawTouch(unsigned int *x, unsigned int *y, unsigned int *z) +{ + unsigned int x1, x2, y1, y2, z1, z2; + + z1 = GetPressure(); + + if(z1>1500) + { + x1 = GetTouchX(); + y1 = GetTouchY(); + + z2 = GetPressure(); + if(z2>1500) + { + x2 = GetTouchX(); + y2 = GetTouchY(); + + if( ( (x1>x2-20) && (x1<x2+20) ) && ( (y1>y2-20) && (y1<y2+20) ) ) + { + *x = (x1+x2) / 2; + *y = (y1+y2) / 2; + *z = (z1+z2) / 2; + + return 1; + } + } + } + return 0; +} + + +/* =================================================================== + routine: MapX + purpose: Maps/alligns X-coordinate of touch input onto LCD's + pixel grid + parameters: <x> touch coordinate + returns: pixel coordinate of touch input + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned int MapX(unsigned int x) +{ + if(x>TFTData.Xmin) + { + x = x-TFTData.Xmin; + x = (x*1000) / TFTData.Xscale; + if(x>TFTData.XRes - 1) x = TFTData.XRes - 1; + } else { + x = 0; + } + return x; +} + + +/* =================================================================== + routine: MapY + purpose: Maps/alligns Y-coordinate of touch input onto LCD's + pixel grid + parameters: <x> touch coordinate + returns: pixel coordinate of touch input + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned int MapY(unsigned int y) +{ + if(y>TFTData.Ymin) //Y input larger than the expected minimum? + { + y = y - TFTData.Ymin; //subtract offset from Y coordinate + y = (y*1000) / TFTData.Yscale; //scale according to touch screen's parameter + //(this results in an alignment between touch + //input and output pixel grid) + if(y>TFTData.YRes - 1) y = TFTData.YRes - 1; //prevent "out of pixel boundary" + } else { + y = 0; //sampled Y-coordinate was lower than touch + } //screen's expected minimum, so keep Y in boundary + return y; +} + + +/* =================================================================== + routine: GetPoint + purpose: Reads and processes touch input + parameters: <*x, *y> pointers to coordinate variables + returns: 1 if touch input was recognized + 0 if no touch occured + + note: An oversampling (x2) is done to increase noise + immunity. + A pressure value of 1500 has to be read to trigger + the further processing - a lower value could improve + touch sensitivity but also increases the risk of + sampling noise instead of touch inputs. + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned char GetPoint(unsigned int *x, unsigned int *y) +{ + unsigned int x1, x2, y1, y2, z1, z2; + + z1 = GetPressure(); //check for pressure onto touch screen + if(z1>1500) //pressure above threshold? + { + x1 = MapX(GetTouchX()); //read touch coordinates + y1 = MapY(GetTouchY()); + + z2 = GetPressure(); //oversampling - start second input read + if(z2>1500) //the second pressure was also above threshold? + { + x2 = MapX(GetTouchX()); //sample again + y2 = MapY(GetTouchY()); + + /* check if both samples were nearly the same + increase the '2' to improve sensitivity */ + if( ( (x1>x2 - 2) && (x1<x2+2) ) && ( (y1>y2 - 2) && (y1<y2 + 2) ) ) + { + *x = (x1+x2) / 2; //do a simple meridian calculation + *y = (y1+y2) / 2; //on both samples and both coordinates + + return 1; //touch input was processed! + } + } + } + return 0; //no touch input was processed! +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/touch.h Thu Jun 28 10:12:07 2012 +0000 @@ -0,0 +1,23 @@ + +struct tinit +{ + unsigned short XRes; + unsigned short YRes; + unsigned int Xmin; + unsigned int Xmax; + unsigned int Ymin; + unsigned int Ymax; + unsigned int Xscale; + unsigned int Yscale; +}; + +extern struct tinit TFTData; + +void TouchInit (void); +unsigned char GetPoint (unsigned int *x, unsigned int *y); +unsigned int MapY (unsigned int y); +unsigned int MapX (unsigned int x); +unsigned int GetTouchX (void); +unsigned int GetTouchY (void); +unsigned int GetPressure (void); +unsigned char GetRawTouch (unsigned int *x, unsigned int *y, unsigned int *z);