TFT Touch base

Dependencies:   TFTv2 mbed

Fork of TFT_test_NUCLEO-F411RE by Motoo Tanaka

main.cpp

Committer:
richnash
Date:
2018-07-30
Revision:
1:0a7005226e61
Parent:
0:cd5e3d371b54

File content as of revision 1:0a7005226e61:

/* Adapted from other examples to work on a F767ZI
 */
 
/* mbed main.cpp to test adafruit 2.8" TFT LCD shiled w Touchscreen
 * Copyright (c) 2014, 2015 Motoo Tanaka @ Design Methodology Lab
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
 
 /* 
  * Note: This program is derived from the SeeeStudioTFTv2 program.
  * Although both program share same ILI9341 TFT driver,
  * the touch sensor was not same with the Display I purchased from Akizuki.
  * http://akizukidenshi.com/catalog/g/gM-07747/
  * The touch sensor on the display is STMPE610,
  * so I hacked the minimum spi driver for it (polling mode only).
  */

#include "mbed.h"
#include <math.h>
#include "ILI9341.h"
#include "SPI_STMPE610.h"
#include "Arial12x12.h"
#include "Arial24x23.h"
#include "Arial28x28.h"
#include "Arial43x48_numb.h"

#define PIN_RESET_TFT   PC_13 /* place holder */

// ------------- FROM WORKING VERSION

#define PIN_MOSI        D11
#define PIN_MISO        D12
#define PIN_SCLK        D13
#define PIN_CS_TFT      D5
#define PIN_DC_TFT      D6
#define PIN_BL_TFT      D7
#define PIN_CS_SD       D4

// =====================================

#define PIN_XP          A2
#define PIN_XM          A0
#define PIN_YP          A3
#define PIN_YM          A1


struct point {
    int x;
    int y;
};

void calibrate(void);
bool getPixel(point& p);
point toPixel(point p);

typedef enum { YES, MAYBE, NO } TOUCH;

TOUCH getTouch(point& p);

int readTouch(PinName p, PinName m, PinName a, PinName i);


int x_off = 22071;
int y_off = 18707;
int pp_tx = 373;
int pp_ty = 297;

// =====================================

DigitalOut backlight(PIN_BL_TFT) ;

ILI9341 TFT(SPI_8, 10000000, PIN_MOSI, PIN_MISO, PIN_SCLK, PIN_CS_TFT, PIN_RESET_TFT, PIN_DC_TFT, "Seeed2.8") ;

int page = 1 ;
int numPage = 3 ;

Serial logger(SERIAL_TX, SERIAL_RX);


/// ================================================================================================


int readTouch(PinName p, PinName m, PinName a, PinName i)
{
    DigitalOut _p(p);
    _p = 1;
    DigitalOut _m(m);
    _m = 0;
    AnalogIn   _a(a);
    AnalogIn   _i(i); // this pin has to be high Z (DigitalIn may also work)
    wait_us(10);
    return _a.read_u16();
}

TOUCH getTouch(point& p)
{
    int y2 = readTouch(PIN_XP,PIN_XM,PIN_YP,PIN_YM);
    int x2 = readTouch(PIN_YP,PIN_YM,PIN_XP,PIN_XM);
    int y1 = readTouch(PIN_XP,PIN_XM,PIN_YP,PIN_YM);
    int x1 = readTouch(PIN_YP,PIN_YM,PIN_XP,PIN_XM);
    int xd = x1 - x2;
    int yd = y1 - y2;
    xd = (xd > 0) ? xd : -xd;
    yd = (yd > 0) ? xd : -xd;
    p.x = x1 + x2;
    p.y = y1 + y2;
    
    const int th = 8000;
    const int df =  100;
    TOUCH touch;
    if (x1 < th || x2 < th ||
            y1 < th || y2 < th) {
        p.x = 0;
        p.y = 0;
        touch = NO;
    } else if (xd > df || yd > df) {
        touch = MAYBE;
    } else {
        touch = YES;
    }
    //TFT.locate(0,50);
    //TFT.printf("x: %6i y: %6i",p.x,p.y);
    return touch;
}

void calibrate(void)
{
    int i;
    int a = 0,b = 0,c = 0, d = 0;
    int pos_x = 0, pos_y = 0;
    point p;
    
    backlight = 0 ;
    //TFT.BusEnable(true) ;
    
    TFT.background(Black);
    wait(0.1) ;
    TFT.foreground(White);
    wait(0.1) ;
    TFT.cls() ;
    wait(0.1) ;
    TFT.set_font((unsigned char*) Arial12x12);
    TFT.locate(90,0);
    TFT.printf("Graphics");
    
    TFT.line(0,3,6,3,White);
    TFT.line(3,0,3,6,White);
    
    backlight = 1 ;
    
    //if (font)
    //{
        // get the center of the screen
        pos_x = TFT.columns() / 2 - 3;
        pos_x = pos_x * Arial12x12[1];
        pos_y = (TFT.rows() / 2) - 1;
        pos_y = pos_y * Arial12x12[2];
        TFT.locate(pos_x,pos_y);
        TFT.printf("press cross    ");
        TFT.locate(pos_x,pos_y + Arial12x12[2]);
        TFT.printf("to calibrate   ");
    //}
    
    for (i=0; i<5; i++) {
        while (getTouch(p) != YES)
            /*nothing*/;
        a += p.x;
        b += p.y;
    }
    a = a / 5;
    b = b / 5;
    //if (font)
    //{
        TFT.locate(pos_x,pos_y);
        TFT.printf("ok             ");
        TFT.locate(pos_x,pos_y + Arial12x12[2]);
        TFT.printf("release touch  ");
    //}
    while (getTouch(p) != NO)
        /*nothing*/;
    
    TFT.cls();
    TFT.line(TFT.width() -5, TFT.height() - 8,TFT.width() - 5,TFT.height() -1,White);   // paint cross
    TFT.line(TFT.width() - 8,TFT.height() - 5,TFT.width() - 1,TFT.height() - 5,White);
    //if (font)
    //{
        TFT.locate(pos_x,pos_y);
        TFT.printf("press cross    ");
        TFT.locate(pos_x,pos_y + Arial12x12[2]);
        TFT.printf("to calibrate   ");
    //}
    for (i=0; i<5; i++) {
        while (getTouch(p) != YES)
            /*nothing*/;
        c+= p.x;
        d+= p.y;
    }
    c = c / 5;
    d = d / 5;
    x_off = a;
    y_off = b;
    i = c-a;  // delta x
    pp_tx = i / (TFT.width() - 6);
    i = d-b;  // delta y
    pp_ty = i / (TFT.height() - 6);
    //if (font)
    //{
        TFT.locate(pos_x,pos_y);
        TFT.printf("Calibrated     ");
        TFT.locate(pos_x,pos_y + Arial12x12[2]);
        TFT.printf("x %6i %4i", x_off, pp_tx);
        TFT.locate(pos_x,pos_y + 2*Arial12x12[2]);
        TFT.printf("y %6i %4i", y_off, pp_ty);
    //}
    while (getTouch(p) != NO)
        /*nothing*/;
    TFT.cls();
    
    //TFT.BusEnable(false) ;
    
    printf("x_off:%6i pp_tx:%4i \n\r", x_off, pp_tx);
    printf("y_off:%6i pp_ty:%4i \n\r", y_off, pp_ty);
}

point toPixel(point p)
{
    p.x -= x_off;
    p.x /= pp_tx;
    int w = TFT.width();
    if (p.x > w) p.x = w;
    if (p.x < 0) p.x = 0;
    p.y -= y_off;
    p.y /= pp_ty;
    int h = TFT.height();
    if (p.y > h) p.y = h;
    if (p.y < 0) p.y = 0;
    return (p);
}

bool getPixel(point& p)
{
    TOUCH touch = getTouch(p);
    p = toPixel(p);
    return touch == YES;
}


// ===================================================

void initTFT(void)
{
    //Configure the display driver
    //TFT.BusEnable(true) ;
    TFT.FastWindow(true) ;
    TFT.background(Black);
    TFT.foreground(White);
    wait(0.01) ;
    TFT.cls();
    //TFT.BusEnable(false) ;
}

void screen1(void) // Welcome Screen
{
    //TFT.BusEnable(true) ;
    backlight = 0 ;
    TFT.background(White) ;
    wait(0.1) ;
    TFT.cls() ;
    wait(0.1) ;
    
    TFT.set_font((unsigned char*) Arial24x23);
    TFT.foreground(Red) ;
    TFT.locate(80, 40) ;
    TFT.printf("MBED") ;
    TFT.foreground(Blue);
    TFT.locate(60, 80) ;
    TFT.printf("2.8\"TFT") ; 
    TFT.locate(40, 120) ;
    TFT.printf("with touch") ;
    TFT.foreground(Black);
    TFT.set_font((unsigned char*) Arial12x12);
    TFT.foreground(Blue) ;
    TFT.locate(30, 180) ;
    TFT.printf("This program is running on") ;
    TFT.locate(30, 200) ;
    TFT.printf("ST Nucleo F411RE with") ;
    TFT.locate(30, 220) ;
    TFT.printf("a program developed in mbed") ;
    TFT.foreground(Green) ;
    TFT.locate(30, 260) ;
    TFT.printf("To advance demo page, touch") ;
    TFT.locate(30, 280) ;
    TFT.printf("and hold right side of screen") ;
    TFT.locate(30, 300) ;
    TFT.printf("until the next screen starts") ;
    //TFT.BusEnable(false) ;
    backlight = 1 ;
}

void screen2(void) // Graphics
{
    //Draw some graphics
    int i, x[2], y[2] ;
    backlight = 0 ;
    //TFT.BusEnable(true) ;
    TFT.background(Black);
    wait(0.1) ;
    TFT.foreground(White);
    wait(0.1) ;
    TFT.cls() ;
    wait(0.1) ;
    TFT.set_font((unsigned char*) Arial12x12);
    TFT.locate(90,0);
    TFT.printf("Graphics");
    
    x[0] = 25 ; x[1] = 224 ;
    y[0] = 20 ; y[1] = 219 ;
    for (i = 20 ; i < 220 ; i += 10) {
        TFT.line(i+5, y[0], i+5, y[1], Blue) ;
        TFT.line(x[0], i, x[1], i, Blue) ;
    }
    TFT.line(125, y[0], 125, y[1], Green) ;
    TFT.line(x[0], 120, x[1], 120, Green) ;
    TFT.rect(x[0],y[0], x[1], y[1], Green) ;
    TFT.locate(10, 20) ;
    TFT.printf("V") ;
    TFT.locate(0, 115) ;
    TFT.printf("0.0") ;
    TFT.locate(115, 225) ;
    TFT.printf("0.0") ;
    TFT.locate(215, 225) ;
    TFT.printf("T") ;

    double s;
    for (int i = x[0]; i < 225; i++) {
        s = 40 * sin((long double)i / 20);
        TFT.pixel(i, 120 + (int)s, White);
    }
    
    TFT.fillrect(10, 240, 229, 309, White) ;
    TFT.rect(10, 240, 229, 309, Red) ;
    TFT.rect(11, 241, 228, 308, Red) ;
    
    TFT.background(White) ;
    TFT.foreground(Black) ;
    TFT.locate(20, 250) ;
    TFT.printf("With QVGA resolution") ;
    TFT.locate(20, 270) ;
    TFT.printf("simple graphics drawing") ;
    TFT.locate(20, 290) ;
    TFT.printf("capability is provided") ;
    //TFT.BusEnable(false) ;
    backlight = 1 ;
}    

void screen3(void) // Graphics
{
    //int rowX;
    int rowY;
    //int x = Terminal6x8[1];
    int y = Terminal6x8[2];
    
    //Draw some text
    backlight = 0 ;
    
    TFT.background(Black);
    wait(0.1) ;
    TFT.foreground(White);
    wait(0.1) ;
    TFT.cls() ;
    wait(0.1) ;
    
    backlight = 1 ;
    
    TFT.set_font((unsigned char*) Terminal6x8);
    
    for( rowY=0; rowY<100; ++rowY )
        {
        TFT.locate(0, (rowY%25)*y);
        TFT.printf("%3d TFT width = %d, height = %d", rowY, TFT.width(), TFT.height()) ;
        }
    
}

void incPage(void)
{
    page++ ;
    if (page >= numPage) {
        page = 0 ;
    }
}

void decPage(void) 
{
    page-- ;
    if (page < 0) {
        page = numPage - 1 ;
    }
}
    
int main()
{
    point p;
    
    // setup the pc serial logger
    logger.baud(115200);
    logger.printf("\r\n\r\n<<<<<<<<< TFT SCREEN TEST >>>>>>>>>>>\r\n" );
    
    int prevPage = 99 ;
    bool waitTouch = false ;
    
    initTFT() ;
    
    printf("Program Started!\n\r") ;
    printf("TFT width = %d, height = %d\n\r", TFT.width(), TFT.height()) ;
    
    //calibrate();
    
    for(;;) {
        
        printf("page %d of %d\r\n", page, numPage );
        
        switch(page) {
        case 0:
            if (prevPage != page) {
                screen1() ;
            }
            waitTouch = true ;
            break ;
        case 1:
            if (prevPage != page) {
                screen2() ; 
            }
            waitTouch = true ;
            break ;
        case 2:
            if (prevPage != page) {
                screen3() ; 
            }
            waitTouch = true ;
            break ;
        default:
            page = 0 ; 
            break ;
        }
        prevPage = page ;
        
        do  {
            if( getPixel(p) ) 
                {
                printf("TFT Touch x = %d, y = %d\n\r", p.x, p.y) ;
                
                if (p.x < 100) 
                    { // left
                    decPage() ;
                    } 
                else if (p.x > 150) 
                    { // right
                    incPage() ;
                    }
                waitTouch = false ;
                }
            } while(waitTouch != false) ;
    }
}