Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
--- /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) ;
+}
--- /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
--- /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
    