Fork with support for ILI9341 controller

Dependents:   CANary_9341 CANary

Fork of TOUCH_TFTx2 by Tick Tock

TOUCH_TFTx2.cpp

Committer:
TickTock
Date:
2013-02-19
Revision:
7:9cc43f20e365
Parent:
6:a91b668b058a
Child:
8:fd0abf6a7f59

File content as of revision 7:9cc43f20e365:

/* 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<8){
                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::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;
    if(true){ //skip cal for me
        x0_off = 5570;
        y0_off = 34030;
        x0_pp = 80;
        y0_pp = 108;
        x1_off = 33700;
        y1_off = 5780;
        x1_pp = 82;
        y1_pp = 108;
        x_mid = 32500;
    } else {
        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);
    }
}