Basically i glued Peter Drescher and Simon Ford libs in a GraphicsDisplay class, then derived TFT or LCD class (which inherits Protocols class), then the most derived ones (Inits), which are per-display and are the only part needed to be adapted to diff hw.
Fork of UniGraphic by
Revision 22:62f3bed03503, committed 2015-05-06
- Comitter:
- rakware
- Date:
- Wed May 06 16:52:07 2015 +0000
- Parent:
- 21:ae0a4eedfc90
- Commit message:
- added touch for ADS7843 bound to TFT class
Changed in this revision
diff -r ae0a4eedfc90 -r 62f3bed03503 TouchADS7843/Touch.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TouchADS7843/Touch.cpp Wed May 06 16:52:07 2015 +0000 @@ -0,0 +1,290 @@ +/************************************************************************************************** + ***** ***** + ***** Name: Touch.cpp ***** + ***** Ver.: 1.0 ***** + ***** Date: 04/01/2013 ***** + ***** Auth: Frank Vannieuwkerke ***** + ***** Erik Olieman ***** + ***** Func: Touch driver for use with ADS7843 ***** + ***** ***** + ***** Code based on Carlos E. Vidales tutorial : ***** + ***** How To Calibrate Touch Screens ***** + ***** www.embedded.com/design/configurable-systems/4023968/How-To-Calibrate-Touch-Screens ***** + ***** ***** + **************************************************************************************************/ + +#include "Touch.h" +#include "mbed.h" +#include "Arial12x12.h" + +#define THRESHOLD 2 + +TouchScreenADS7843::TouchScreenADS7843(PinName tp_mosi, PinName tp_miso, PinName tp_sclk, PinName tp_cs, PinName tp_irq, TFT *_LCD) + : LCD(_LCD), _tp_spi(tp_mosi, tp_miso, tp_sclk), _tp_cs(tp_cs), _tp_irq(tp_irq) + { + DisplaySample[0].x=45; + DisplaySample[0].y=45; + DisplaySample[1].x=45; + DisplaySample[1].y=270; + DisplaySample[2].x=190; + DisplaySample[2].y=190; + ScreenSample[0].x=45; + ScreenSample[0].y=45; + ScreenSample[1].x=45; + ScreenSample[1].y=270; + ScreenSample[2].x=190; + ScreenSample[2].y=190; + _tp_cs=1; + _tp_spi.frequency(500000); + _tp_spi.format(8,0); // 8 bit spi mode 0 + } + +int TouchScreenADS7843::Read_XY(unsigned char XY) +{ + unsigned char msb, lsb; + unsigned int Temp; + + Temp=0; + _tp_cs=0; + wait_us(SPI_RD_DELAY); + _tp_spi.write(XY); + wait_us(SPI_RD_DELAY); + msb = _tp_spi.write(0x00); // msb + wait_us(SPI_RD_DELAY); + lsb = _tp_spi.write(0x00); // lsb + _tp_cs=1; + Temp = ((msb << 8 ) | lsb); + Temp >>= 3; + Temp &= 0xfff; + Temp /= 4; // Scaling : return value range must be between 0 and 1024 + return(Temp); +} + + +void TouchScreenADS7843::TP_GetAdXY(int *x,int *y) +{ + int adx,ady; + adx = Read_XY(CHX); + wait_us(1); + ady = Read_XY(CHY); + *x = adx; + *y = ady; +} + +void TouchScreenADS7843::TP_DrawPoint(unsigned int Xpos,unsigned int Ypos, unsigned int color) +{ +// LCD->wr_reg(0x03, 0x1030); +// LCD->WindowMax(); + LCD->pixel(Xpos,Ypos,color); + LCD->pixel(Xpos+1,Ypos,color); + LCD->pixel(Xpos,Ypos+1,color); + LCD->pixel(Xpos+1,Ypos+1,color); +} + +void TouchScreenADS7843::DrawCross(unsigned int Xpos,unsigned int Ypos) +{ +// LCD->rect(Xpos-7,Ypos+7,Xpos+7,Ypos-7, Red); + + LCD->line(Xpos-15,Ypos,Xpos-2,Ypos,White); //left + LCD->line(Xpos+2,Ypos,Xpos+15,Ypos,White); + LCD->line(Xpos,Ypos-15,Xpos,Ypos-2,White); + LCD->line(Xpos,Ypos+2,Xpos,Ypos+15,White); + + LCD->line(Xpos-15,Ypos+15,Xpos-7,Ypos+15,DarkGrey); + LCD->line(Xpos-15,Ypos+7,Xpos-15,Ypos+15,DarkGrey); + + LCD->line(Xpos-15,Ypos-15,Xpos-7,Ypos-15,DarkGrey); + LCD->line(Xpos-15,Ypos-7,Xpos-15,Ypos-15,DarkGrey); + + LCD->line(Xpos+7,Ypos+15,Xpos+15,Ypos+15,DarkGrey); + LCD->line(Xpos+15,Ypos+7,Xpos+15,Ypos+15,DarkGrey); + + LCD->line(Xpos+7,Ypos-15,Xpos+15,Ypos-15,DarkGrey); + LCD->line(Xpos+15,Ypos-15,Xpos+15,Ypos-7,DarkGrey); +} + +unsigned char TouchScreenADS7843::Read_Ads7843(Coordinate * screenPtr) +{ + int m0,m1,m2,TP_X[1],TP_Y[1],temp[3]; + uint8_t count=0; + int buffer[2][9]={{0},{0}}; + if (screenPtr == NULL) screenPtr = &screen; + do + { + TP_GetAdXY(TP_X,TP_Y); + buffer[0][count]=TP_X[0]; + buffer[1][count]=TP_Y[0]; + count++; + } + while(!_tp_irq && (count < 9)); + if(count==9) + { + temp[0]=(buffer[0][0]+buffer[0][1]+buffer[0][2])/3; + temp[1]=(buffer[0][3]+buffer[0][4]+buffer[0][5])/3; + temp[2]=(buffer[0][6]+buffer[0][7]+buffer[0][8])/3; + m0=temp[0]-temp[1]; + m1=temp[1]-temp[2]; + m2=temp[2]-temp[0]; + m0=m0>0?m0:(-m0); + m1=m1>0?m1:(-m1); + m2=m2>0?m2:(-m2); + if( (m0>THRESHOLD) && (m1>THRESHOLD) && (m2>THRESHOLD) ) return 0; + if(m0<m1) + { + if(m2<m0) + screenPtr->x=(temp[0]+temp[2])/2; + else + screenPtr->x=(temp[0]+temp[1])/2; + } + else if(m2<m1) + screenPtr->x=(temp[0]+temp[2])/2; + else + screenPtr->x=(temp[1]+temp[2])/2; + + temp[0]=(buffer[1][0]+buffer[1][1]+buffer[1][2])/3; + temp[1]=(buffer[1][3]+buffer[1][4]+buffer[1][5])/3; + temp[2]=(buffer[1][6]+buffer[1][7]+buffer[1][8])/3; + m0=temp[0]-temp[1]; + m1=temp[1]-temp[2]; + m2=temp[2]-temp[0]; + m0=m0>0?m0:(-m0); + m1=m1>0?m1:(-m1); + m2=m2>0?m2:(-m2); + if( (m0>THRESHOLD) && (m1>THRESHOLD) && (m2>THRESHOLD) ) return 0; + + if(m0<m1) + { + if(m2<m0) + screenPtr->y=(temp[0]+temp[2])/2; + else + screenPtr->y=(temp[0]+temp[1])/2; + } + else if(m2<m1) + screenPtr->y=(temp[0]+temp[2])/2; + else + screenPtr->y=(temp[1]+temp[2])/2; + return 1; + } + return 0; +} + +uint8_t TouchScreenADS7843::setCalibrationMatrix( Coordinate * displayPtr, + Coordinate * screenPtr, + Matrix * matrixPtr) +{ + uint8_t retTHRESHOLD = 0 ; + // K = (Xs0 - Xs2)*(Ys1 - Ys2) - (Xs1 - Xs2)*(Ys0 - Ys2) + matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - + ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; + if( matrixPtr->Divider == 0 ) + { + retTHRESHOLD = 1; + } + else + { + // (Xd0 - Xd2)*(Ys1 - Ys2) - (Xd1 - Xd2)*(Ys0 - Ys2) + // A = --------------------------------------------------- + // K + matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - + ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; + // (Xs0 - Xs2)*(Xd1 - Xd2) - (Xd0 - Xd2)*(Xs1 - Xs2) + // B = --------------------------------------------------- + // K + matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) - + ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ; + // Ys0*(Xs2*Xd1 - Xs1*Xd2) + Ys1*(Xs0*Xd2 - Xs2*Xd0) + Ys2*(Xs1*Xd0 - Xs0*Xd1) + // C = ---------------------------------------------------------------------------- + // K + matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y + + (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y + + (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ; + // (Yd0 - Yd2)*(Ys1 - Ys2) - (Yd1 - Yd2)*(Ys0 - Ys2) + // D = --------------------------------------------------- + // K + matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) - + ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ; + // (Xs0 - Xs2)*(Yd1 - Yd2) - (Yd0 - Yd2)*(Xs1 - Xs2) + // E = --------------------------------------------------- + // K + matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) - + ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ; + // Ys0*(Xs2*Yd1 - Xs1*Yd2) + Ys1*(Xs0*Yd2 - Xs2*Yd0) + Ys2*(Xs1*Yd0 - Xs0*Yd1) + // F = ---------------------------------------------------------------------------- + // K + matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y + + (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y + + (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ; + } + return( retTHRESHOLD ) ; +} + +uint8_t TouchScreenADS7843::getDisplayPoint(void) +{ + uint8_t retTHRESHOLD = 0 ; + + if( matrix.Divider != 0 ) + { + // XD = AX+BY+C + display.x = ( (matrix.An * screen.x) + + (matrix.Bn * screen.y) + + matrix.Cn + ) / matrix.Divider ; + // YD = DX+EY+F + display.y = ( (matrix.Dn * screen.x) + + (matrix.En * screen.y) + + matrix.Fn + ) / matrix.Divider ; + } + else + { + retTHRESHOLD = 1; + } + return(retTHRESHOLD); +} + +void TouchScreenADS7843::TouchPanel_Calibrate(void) +{ + uint8_t i; + Coordinate screen_cal; + setCalibrationMatrix( &DisplaySample[0],&ScreenSample[0],&matrix) ; + LCD->set_font((unsigned char*) Arial12x12); + for(i=0;i<3;i++) + { + LCD->cls(); + LCD->locate(10,10); + LCD->printf("Touch crosshair to calibrate"); + wait_ms(500); + DrawCross(DisplaySample[i].x,DisplaySample[i].y); + do {} while (!Read_Ads7843(&screen_cal)); + ScreenSample[i].x= screen_cal.x;ScreenSample[i].y= screen_cal.y; + } + setCalibrationMatrix( &DisplaySample[0],&ScreenSample[0],&matrix) ; + LCD->cls(); +} + +void TouchScreenADS7843::GetCalibration(Matrix * matrixPtr, Coordinate * screenPtr) +{ + uint8_t i; + Matrix * mp1; + mp1 = &matrix; + *matrixPtr = *mp1; + for(i=0;i<3;i++) + { + screenPtr[i].x = ScreenSample[i].x; + screenPtr[i].y = ScreenSample[i].y; + } +} + +void TouchScreenADS7843::SetCalibration(Matrix * matrixPtr, Coordinate * screenPtr) +{ + uint8_t i; + Matrix * mp1; + mp1 = &matrix; + *mp1 = *matrixPtr; + for(i=0;i<3;i++) + { + ScreenSample[i].x = screenPtr[i].x; + ScreenSample[i].y = screenPtr[i].y; + } + setCalibrationMatrix( &DisplaySample[0],&ScreenSample[0],&matrix) ; +}
diff -r ae0a4eedfc90 -r 62f3bed03503 TouchADS7843/Touch.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TouchADS7843/Touch.h Wed May 06 16:52:07 2015 +0000 @@ -0,0 +1,175 @@ +/****************************************************************** + ***** ***** + ***** Name: Touch.h ***** + ***** Ver.: 1.0 ***** + ***** Date: 04/01/2013 ***** + ***** Auth: Frank Vannieuwkerke ***** + ***** Erik Olieman ***** + ***** Func: Touch driver for use with ADS7843 ***** + ***** ***** + ******************************************************************/ + +#ifndef MBED_Touch_H +#define MBED_Touch_H + +#include "TFT.h" +#include "mbed.h" + + typedef struct + { + int x; + int y; + } Coordinate; + + typedef struct + { + int An, + Bn, + Cn, + Dn, + En, + Fn, + Divider ; + } Matrix; + +class TouchScreenADS7843 { +public: + Coordinate display; + Coordinate screen; + + /* + * Create a Touchscreen object connected to SPI and two pins. + * + * @param mosi,miso,sclk SPI + * @param cs pin connected to CS of ADS7843 + * @param irq pin connected to IRQ of ADS7843 + * @param pointer to SPI_TFT constructor + * + */ + TouchScreenADS7843(PinName tp_mosi, PinName tp_miso, PinName tp_sclk, PinName tp_cs, PinName tp_irq, TFT *_LCD); + + /* + * Draw a 2 by 2 dot on the LCD screen. + * + * @param x (horizontal position) + * @param y (vertical position) + * @param color (16 bit pixel color) + * + */ + void TP_DrawPoint(unsigned int Xpos,unsigned int Ypos,unsigned int color); + + /* + * Obtain averaged data from ADS7846. + * does 9 consecutive reads and only stores averaged data + * when the 9 points are within the treshold limits. + * + * @param screenPTR (pointer to store data) + * @returns 1 on success + * @returns 0 on failure + * + * If called with screenPTR = NULL - 'screen' variable is used, otherwise (parameter) is used. + * + */ + unsigned char Read_Ads7843(Coordinate * screenPtr = NULL); + + /* + * Calibrate the touch panel. + * Three crosshairs are drawn and need to be touched in sequence. + * A calibration matrix is set accordingly. + * + */ + void TouchPanel_Calibrate(void); + + /* + * Obtain real x,y coordinates. + * The x,y coordinates are calculated using the calibration matrix. + * + */ + unsigned char getDisplayPoint(void); + + /* + * Read touchpanel screensample and matrix values. + * + * In your code, create 2 structures using Matrix and screenPtr + * and call this function with these structures. + * the calibration values are returned into these structures. + * Example: + * Matrix matrix; + * Coordinate ScreenSample[3]; + * GetCalibration(&matrix, &ScreenSample[0]); + */ + void GetCalibration(Matrix * matrixPtr, Coordinate * screenPtr); + + /* + * Set touchpanel calibration using screensample and matrix values. + * + * In your code, create 2 structures based on Matrix and screenPtr, + * copy saved calibration values into these structures + * and call this function with these structures. + * Example: + * Matrix matrix; + * Coordinate ScreenSample[3]; + * <pseudocode> load matrix with values from external storage (eg eeprom). + * <pseudocode> load ScreenSample with values from external storage (eg eeprom). + * SetCalibration(&matrix, &ScreenSample[0]); + */ + void SetCalibration(Matrix * matrixPtr, Coordinate * screenPtr); + + TFT *LCD; + SPI _tp_spi; + DigitalOut _tp_cs; + DigitalIn _tp_irq; + +protected: + + #define SPI_RD_DELAY 1 + #define CHX 0xd0 // 12 bit mode + #define CHY 0x90 + + Coordinate DisplaySample[3]; + Coordinate ScreenSample[3]; + Matrix matrix; + + /* + * Obtain raw x,y data from ADS7846 + * + * @param pointer to raw x and y coordinates (pointer to store data) + * @returns x (horizontal position) + * @returns y (vertical position) + * + */ + void TP_GetAdXY(int *x,int *y); + + /* + * Obtain raw single channel data from ADS7846 (Called by TP_GetADXY) + * + * @param channel to be read (CHX or CHY) + * @returns raw scaled down value (return value range must be between 0 and 1024) + * + */ + int Read_XY(unsigned char XY); + + /* + * Draw a calibration crosshair on the LCD screen + * + * @param x (horizontal position) + * @param y (vertical position) + * + */ + void DrawCross(unsigned int Xpos,unsigned int Ypos); + + /* + * Set the calibration matrix + * + * @param displayPTR (pointer to display data) + * @param screenPTR (pointer to screen data) + * @param matrixPTR (pointer to calibration matrix) + * + * @returns 0 when matrix.divider != 0 + * @returns 1 when matrix.divider = 0 + * + */ + unsigned char setCalibrationMatrix( Coordinate * displayPtr,Coordinate * screenPtr,Matrix * matrixPtr); + +}; +#endif
diff -r ae0a4eedfc90 -r 62f3bed03503 TouchADS7843/readme.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TouchADS7843/readme.txt Wed May 06 16:52:07 2015 +0000 @@ -0,0 +1,40 @@ +#include "mbed.h" +#include "ILI9341.h" +#include "Touch.h" + +ILI9341 TFT(SPI_16, 12000000, D11, D12, D13, D10, D9, D8, "TFT"); // Spi 16bit, 12MHz, mosi, miso, sclk, cs, reset, dc + +TouchScreenADS7843 TP(D11, D12, D13, D14, D15, &TFT); // ADS7843 -> mosi, miso, sclk, cs, irq, SPI_TFT + +int main() +{ + TFT.claim(stdout); + Matrix matrix; + Coordinate ScreenSample[3]; + TP.TouchPanel_Calibrate(); + TP.GetCalibration(&matrix, &ScreenSample[0]); + TP.SetCalibration(&matrix, &ScreenSample[0]); + for(;;) { + + if (!TP._tp_irq) { + if (TP.Read_Ads7843()) { + TP.getDisplayPoint() ; + TP.TP_DrawPoint(TP.display.x,TP.display.y, Blue); + TFT.locate(25,0); + printf("%03d",TP.display.x); + TFT.locate(95,0); + printf("%03d",TP.display.y); + // Touchscreen area is larger than LCD area. + // We use the bottom area outside the LCD area to clear the screen (y value > 320). + if (TP.display.y > 320) { + TFT.cls(); + TFT.locate(0,0); + printf(" X:"); + TFT.locate(70,0); + printf(" Y:"); + } + } + } + + } +} \ No newline at end of file