Modified to work with two displays
Dependents: touch2 default CANary_9341_test CANary_merge
Fork of Touch_tft by
TOUCH_TFTx2.cpp
- Committer:
- TickTock
- Date:
- 2014-05-18
- Revision:
- 16:bee053b17977
- Parent:
- 15:f2165aa0daa6
File content as of revision 16:bee053b17977:
/* 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"
#include "Arial12x12.h"
#define threshold 0x8000 // threshold to detect pressed
#define accuracy 1000 // noise filter
#define numsamp 16 // number of averaging samples
#if USE_ILI9341== 1
TOUCH_TFTx2::TOUCH_TFTx2(PinName xp, PinName xm, PinName yp, PinName ym,
PinName mosi, PinName miso, PinName sclk, PinName cs0,
PinName cs1, PinName reset, PinName dc,
const char* name):
_xp(xp),_xm(xm),_yp(yp),_ym(ym),_ax(xp),_ay(yp),
SPI_TFTx2_ILI9341(mosi,miso,sclk,cs0,cs1,reset,dc,name) {
xa = xp;
ya = yp;
}
#else
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;
}
#endif
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,160);
//printf("d: %4d x: %5d",dx,p.x);
//locate(1,200);
//printf("d: %4d y: %5d",dy,p.y);
//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
set_font((unsigned char*) Arial12x12);
foreground(White);
background(Black);
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);
}
