Hi, I have a project using an arduino and a TJCTM24024-SPI touch LCD.
The resistive touch screen uses the (ftp://imall.iteadstudio.com/LCD_Panel/IM120905004/DS_XPT2046.pdf) XPT2046 Touch Screen Controller chip to allow SPI access to the touches.
I have exhausted the amount of pins on my arduino with other sensors and so I need to use the hardware SPI to work with both the LCD and the touch chip.
I have searched high and low for a hardware SPI library for the XPT2046 chip but only found the UTouch Library which uses bit banging.
Having come across bit banging before but never really understood it I decided that I should convert the UTouch library to use hardware SPI, this will aid my understanding and give me a hardware SPI touch library.
So, I have started to rework it, my efforts I have included below in Fig 1.
Being a bit green, I would like others feedback on whether I am on the right track with this, it obviousely doesn't work in its current form but once done, it should be useful to many others. Please could you guys give me a hand to get this working.
Thank you, Rick.
Fig 1
/************please see original github repo for forword, omited here for brevity ************/
#include "UTouch.h"
#include "UTouchCD.h"
UTouch::UTouch(byte tclk, byte tcs, byte din, byte dout, byte irq)
{
//T_CLK = tclk;
T_CS = tcs;
//T_DIN = din;
//T_DOUT = dout;
T_IRQ = irq;
}
void UTouch::InitTouch(byte orientation)
{
orient = orientation;
_default_orientation = CAL_S>>31;
touch_x_left = (CAL_X>>14) & 0x3FFF;
touch_x_right = CAL_X & 0x3FFF;
touch_y_top = (CAL_Y>>14) & 0x3FFF;
touch_y_bottom = CAL_Y & 0x3FFF;
disp_x_size = (CAL_S>>12) & 0x0FFF;
disp_y_size = CAL_S & 0x0FFF;
prec = 10;
//pinMode(T_CLK, OUTPUT);
pinMode(T_CS, OUTPUT);
//pinMode(T_DIN, OUTPUT);
//pinMode(T_DOUT, INPUT);
pinMode(T_IRQ, OUTPUT);
digitalWrite(T_CS, HIGH);
//digitalWrite(T_CLK, HIGH);
//digitalWrite(T_DIN, HIGH);
//digitalWrite(T_CLK, HIGH);
}
// transmit byte serially, MSB first
void UTouch::touch_WriteData(byte data)
{
/*
byte temp;
byte nop;
temp=data;
digitalWrite(T_CLK,LOW);
// send bits 7..0
for(byte count=0; count<8; count++)
{
// consider leftmost bit
// set line high if bit is 1, low if bit is 0
if(temp & 0x80)
digitalWrite(T_DIN, HIGH);
else
digitalWrite(T_DIN, LOW);
// shift byte left so next bit will be leftmost
temp = temp << 1;
// pulse clock to indicate that bit value should be read
digitalWrite(T_CLK, LOW);
nop++;
digitalWrite(T_CLK, HIGH);
nop++;
}
*/
}
word UTouch::touch_ReadData(byte b)
{
//the d_out will return 12 bits of data for every 8 bit command ?
//so we need to send the 8 bit command plus some garbage ?
return word(SPI.transfere(b), SPI.transfere(0x00));
/*
byte nop;
word data = 0;
// read bits 11..0
for(byte count=0; count<12; count++)
{
// shift byte left so next bit will be leftmost
data <<= 1;
// pulse clock to indicate that bit value should be read
digitalWrite(T_CLK, HIGH);
nop++;
digitalWrite(T_CLK, LOW);
nop++;
//if T_DOUT is high, this position in data will be 1, else it will be 0
if (digitalRead(T_DOUT))
data++;
}
return(data);
*/
}
void UTouch::read()
{
unsigned long tx=0, temp_x=0;
unsigned long ty=0, temp_y=0;
int datacount=0;
digitalWrite(T_CS,LOW);
for (int i=0; i<prec; i++)
{
//touch_WriteData(0x90);
//digitalWrite(T_CLK,HIGH);
//digitalWrite(T_CLK,LOW);
//temp_x=touch_ReadData();
temp_x=touch_ReadData(0x90);
//touch_WriteData(0xD0);
//digitalWrite(T_CLK,HIGH);
//digitalWrite(T_CLK,LOW);
//temp_y=touch_ReadData(0x90, 0xD0);
temp_y=touch_ReadData(0xD0);
if (!((temp_x>max(touch_x_left, touch_x_right)) or (temp_x==0) or (temp_y>max(touch_y_top, touch_y_bottom)) or (temp_y==0)))
{
ty+=temp_x;
tx+=temp_y;
datacount++;
}
}
digitalWrite(T_CS,HIGH);
if (datacount>0)
{
if (orient == _default_orientation)
{
TP_X=tx/datacount;
TP_Y=ty/datacount;
}
else
{
TP_X=ty/datacount;
TP_Y=tx/datacount;
}
}
else
{
TP_X=-1;
TP_Y=-1;
}
}
bool UTouch::dataAvailable()
{
bool avail;
pinMode(T_IRQ, INPUT);
avail = !digitalRead(T_IRQ);
pinMode(T_IRQ, OUTPUT);
return avail;
}
int UTouch::getX()
{
long c;
if (orient == _default_orientation)
{
c = long(long(TP_X - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
if (c<0)
c = 0;
if (c>disp_x_size)
c = disp_x_size;
}
else
{
if (_default_orientation == PORTRAIT)
c = long(long(TP_X - touch_y_top) * (-disp_y_size)) / long(touch_y_bottom - touch_y_top) + long(disp_y_size);
else
c = long(long(TP_X - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
if (c<0)
c = 0;
if (c>disp_y_size)
c = disp_y_size;
}
return c;
}
int UTouch::getY()
{
int c;
if (orient == _default_orientation)
{
c = long(long(TP_Y - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
if (c<0)
c = 0;
if (c>disp_y_size)
c = disp_y_size;
}
else
{
if (_default_orientation == PORTRAIT)
c = long(long(TP_Y - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
else
c = long(long(TP_Y - touch_x_left) * (-disp_x_size)) / long(touch_x_right - touch_x_left) + long(disp_x_size);
if (c<0)
c = 0;
if (c>disp_x_size)
c = disp_x_size;
}
return c;
}
void UTouch::setPrecision(byte precision)
{
switch (precision)
{
case PREC_LOW:
prec=1;
break;
case PREC_MEDIUM:
prec=10;
break;
case PREC_HI:
prec=25;
break;
case PREC_EXTREME:
prec=100;
break;
default:
prec=10;
break;
}
}