Fork with support for ILI9341 controller

Dependents:   CANary_9341 CANary

Fork of TOUCH_TFTx2 by Tick Tock

TOUCH_TFTx2.cpp

Committer:
TickTock
Date:
2013-03-03
Revision:
11:ce7ae1584207
Parent:
10:fd7ae99850a9
Child:
13:220e3da2dd00

File content as of revision 11:ce7ae1584207:

/* mbed library for resistive touch pads
 * uses 4 pins - 2 IO and 2 Analog

 * c 2011 Peter Drescher - DC2PD
 *
 * 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.
 */


#include "TOUCH_TFTx2.h"
#include "mbed.h"

#define threshold 0x8000  // threshold to detect pressed
#define accuracy 1000 // noise filter
#define numsamp 16 // number of averaging samples

TOUCH_TFTx2::TOUCH_TFTx2(PinName xp, PinName xm, PinName yp, PinName ym,
                     PinName mosi, PinName miso, PinName sclk, PinName cs0, PinName cs1, PinName reset,const char* name):
        _xp(xp),_xm(xm),_yp(yp),_ym(ym),_ax(xp),_ay(yp),
        SPI_TFTx2(mosi,miso,sclk,cs0,cs1,reset,name) {
    xa = xp;
    ya = yp;

}

point TOUCH_TFTx2::get_touch() {
    unsigned short x1, x2=0, y1, y2=0, i=0, j=0, k;
    unsigned long dy , dx, xs1=0, ys1=0, xs2=0, ys2=0;
    point p;

    for (k=0; j<numsamp; k++) {
        // read y voltage
        _ym.input();        //LAJ y- has to be passive
        _yp.input();        //LAJ y+ has to be passive
        _xp.output();
        _xm.output();
        switch (orientation) {
            case(0):
            case(3):
                _xp = 1;
                _xm = 0;
                break;
            case(1):
            case(2):
                _xp = 0;
                _xm = 1;
                break;
        }
        AnalogIn Ay(ya);    // we have to call the constructor to switch to analog mode
        wait_us(10);
        y1 = Ay.read_u16(); // get y voltage
        dy = (y1 > y2)? (y1-y2) : (y2-y1);
        y2 = y1;

        // read x voltage
        _xm.input();        //LAJ x- has to be passive
        _xp.input();        //LAJ x+ has to be passive
        _yp.output();
        _ym.output();
        switch (orientation) {
            case(0):
            case(1):
                _yp = 1;
                _ym = 0;
                break;
            case(2):
            case(3):
                _yp = 0;
                _ym = 1;
                break;
        }
        AnalogIn Ax(xa);    // we have to call the constructor to switch to analog mode
        wait_us(10);
        x1 = Ax.read_u16(); // get x voltage
        dx = (x1 > x2)? (x1-x2) : (x2-x1);
        x2 = x1;
        if(dy<accuracy && dx<accuracy) {
            if(k<numsamp/2){
                xs1 += x1;
                ys1 += y1;
                i++;
            } else {
                xs2 += x1;
                ys2 += y1;
                j++;
            }
        }
    } // for:next
    xs1 = xs1 / i;
    ys1 = ys1 / i;
    xs2 = xs2 / j;
    ys2 = ys2 / j;
    dy = (ys1 > ys2)? (ys1-ys2) : (ys2-ys1);
    dx = (xs1 > xs2)? (xs1-xs2) : (xs2-xs1);
    if(dy<accuracy && dx<accuracy) {

        switch (orientation) {
            case(0):
            case(2):
                p.y = (xs1+xs2) / 2;  // average
                p.x = (ys1+ys2) / 2;
                break;
            case(1):
            case(3):
                p.x = (xs1+xs2) / 2;  // average
                p.y = (ys1+ys2) / 2;
                break;
        }
    } else { // sample average moved too much so discard
        p.x = 65535;
        p.y = 65535;
    }
    // debug
    //locate(1,80);
    //printf("d: %4d y: %5d",dy,p.y);
    //locate(1,100);
    //printf("d: %4d x: %5d",dx,p.x);
    //wait(0.25);
    wfi(); //enable touchpad input
    return(p);
}//*/



point TOUCH_TFTx2::to_pixel(point a_point) {
    static point p;

    if (a_point.x < x_mid) { // left screen
        p.x = (a_point.x - x0_off) / x0_pp + 3;
        if (p.x > width()-1) p.x = width()-1;
        p.y = (a_point.y - y0_off) / y0_pp + 3;
    }else{ // right screen
        p.x = (a_point.x - x1_off) / x1_pp + 3;
        if (p.x > width()-1) p.x = 2*width()-1;
        else p.x += width(); // add width to indicate right screen
        p.y = (a_point.y - y1_off) / y1_pp + 3;
    }
    if (p.y > height()-1) p.y = height()-1;
    //locate(1,60); //debug
    //printf("x: %d\ty: %d",p.x,p.y);
    return (p);
}

bool TOUCH_TFTx2::is_touched(void) {
    unsigned short y1;
    // read y voltage
    _xm.input();        //x- has to be passive
    _xp.input();        //x+ has to be passive
    _xm.mode(PullDown);
    _xp.mode(PullDown);
    _yp.output();
    _ym.output();
    _yp = 1;            //drive y+ high
    _ym = 1;            //drive y- high
    AnalogIn Ay(xa);    // we have to call the constructor to switch to analog mode
    wait_us(10);
    y1 = Ay.read_u16(); // get y voltage
    return (y1>threshold);
}

void TOUCH_TFTx2::wfi(void) {
    _xm.input();        //x- has to be passive
    _xp.input();        //x+ has to be passive
    _xm.mode(PullDown);
    _xp.mode(PullDown);
    _yp.output();
    _ym.output();
    _yp = 1;            //drive y+ high
    _ym = 1;            //drive y- high
}

void TOUCH_TFTx2::setcal(int _x0off, int _y0off, int _x0pp, int _y0pp, int _x1off, int _y1off, int _x1pp, int _y1pp, int _xmid) {
        x0_off = _x0off;
        y0_off = _y0off;
        x0_pp = _x0pp;
        y0_pp = _y0pp;
        x1_off = _x1off;
        y1_off = _y1off;
        x1_pp = _x1pp;
        y1_pp = _y1pp;
        x_mid = _xmid;
}

void TOUCH_TFTx2::calibrate(void) {
    int i;
    int ulx0 = 0, uly0 = 0, brx0 = 0, bry0 = 0;
    int ulx1 = 0, uly1 = 0, brx1 = 0, bry1 = 0;
    int pos_x, pos_y;
    point p;
    seldisp=1;       // select right display
    cls();
    line(0,3,6,3,White);
    line(3,0,3,6,White);

    // get the center of the screen
    pos_x = columns() / 2 - 3;
    pos_x = pos_x * font[1];
    pos_y = (rows() / 2) - 1;
    pos_y = pos_y * font[2];
    
    //calibrate right screen
    locate(pos_x,pos_y);
    printf("press cross");
    locate(pos_x,pos_y + font[2]);
    printf("to calibrate");
    do {
        wait(0.1);
    } while (!is_touched()); //Wait for touch
    for (i=0; i<5; i++) {
        do {
            p = get_touch();
        } while (p.x==0 && p.y==0);
        ulx1 += p.x;
        uly1 += p.y;
    }
    ulx1 /= 5;
    uly1 /= 5;
    locate(pos_x,pos_y);
    printf("OK         ");
    printf("           ");
    do {
        wait(0.1);
    } while (is_touched()); //Wait for no touch

    cls();
    line(width() -1, height() - 4,width() - 7,height() -4,White);   // paint cross
    line(width() - 4,height() - 1,width() - 4,height() - 7,White);
    locate(pos_x,pos_y);
    printf("press cross");
    locate(pos_x,pos_y + font[2]);
    printf("to calibrate");
    do {
        wait(0.1);
    } while (!is_touched()); //Wait for touch
    for (i=0; i<5; i++) {
        do {
            p = get_touch();
        } while (p.x==0 && p.y==0);        p  = get_touch();
        brx1 += p.x;
        bry1 += p.y;
    }
    brx1 /= 5;
    bry1 /= 5;

    locate(pos_x, pos_y);
    printf("OK         ");
    printf("           ");
    do {
        wait(0.1);
    } while (is_touched()); //Wait for no touch

    cls();
    seldisp=0;       // select left display
    cls();
    line(0,3,6,3,White);
    line(3,0,3,6,White);

    // now calibrate left screen
    locate(pos_x,pos_y);
    printf("press cross");
    locate(pos_x,pos_y + font[2]);
    printf("to calibrate");
    do {
        wait(0.1);
    } while (!is_touched()); //Wait for touch
    for (i=0; i<5; i++) {
        do {
            p = get_touch();
        } while (p.x==0 && p.y==0);
        ulx0 += p.x;
        uly0 += p.y;
    }
    ulx0 /= 5;
    uly0 /= 5;
    locate(pos_x,pos_y);
    printf("OK         ");
    printf("           ");
    do {
        wait(0.1);
    } while (is_touched()); //Wait for no touch

    cls();
    line(width() -1, height() - 4,width() - 7,height() -4,White);   // paint cross
    line(width() - 4,height() - 1,width() - 4,height() - 7,White);
    locate(pos_x,pos_y);
    printf("press cross");
    locate(pos_x,pos_y + font[2]);
    printf("to calibrate");
    do {
        wait(0.1);
    } while (!is_touched()); //Wait for touch
    for (i=0; i<5; i++) {
        do {
            p = get_touch();
        } while (p.x==0 && p.y==0);
        brx0 += p.x;
        bry0 += p.y;
    }
    brx0 /= 5;
    bry0 /= 5;

    locate(pos_x, pos_y);
    printf("OK         ");
    printf("           ");
    do {
        wait(0.1);
    } while (is_touched()); //Wait for no touch

    cls();

    x0_off = ulx0;
    y0_off = uly0;
    x0_pp = (brx0-ulx0) / (width() - 6);
    y0_pp = (bry0-uly0) / (height() - 6);
    
    
    x1_off = ulx1;
    y1_off = uly1;
    x1_pp = (brx1-ulx1) / (width() - 6);
    y1_pp = (bry1-uly1) / (height() - 6);
    x_mid = (brx0 + ulx1) / 2;
    //debug
    //printf("x0_off:%d y0_off:%d x0_pp:%d y0_pp:%d\n",x0_off,y0_off,x0_pp,y0_pp);
    //printf("x1_off:%d y1_off:%d x1_pp:%d y1_pp:%d\n",x1_off,y1_off,x1_pp,y1_pp);
    //printf("x_mid:%d\n",x_mid);
}