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 GraphicsDisplay

Files at this revision

API Documentation at this revision

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

TouchADS7843/Touch.cpp Show annotated file Show diff for this revision Revisions of this file
TouchADS7843/Touch.h Show annotated file Show diff for this revision Revisions of this file
TouchADS7843/readme.txt Show annotated file Show diff for this revision Revisions of this file
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