Add XPT2046 touch controller support

supports esp8266 + RPi displays
This commit is contained in:
Max committed 2017-10-01 00:32:30 +02:00
1 parent ca54325fbc
commit 944e505f36
4 files changed
+195 -32

No files matched your search

+149
View File
@@ -73,6 +73,12 @@ TFT_eSPI::TFT_eSPI(int16_t w, int16_t h)
pinMode(TFT_CS, OUTPUT);
#endif
// Configure chip select for touchscreen controller if present
#ifdef TOUCH_CS
digitalWrite(TOUCH_CS, HIGH); // Chip select high (inactive)
pinMode(TOUCH_CS, OUTPUT);
#endif
#ifdef TFT_WR
digitalWrite(TFT_WR, HIGH); // Set write strobe high (inactive)
pinMode(TFT_WR, OUTPUT);
@@ -3641,6 +3647,149 @@ void spiWriteBlock(uint16_t color, uint32_t repeat)
}
#endif
/***************************************************************************************
** Function name: getTouchRaw
** Description: read raw position of touchpad if pressed. Return false if not pressed.
***************************************************************************************/
#ifdef TOUCH_CS
uint8_t TFT_eSPI::getTouchRaw(uint16_t *x, uint16_t *y){
uint16_t tmp;
CS_H;
T_CS_L;
SPI.setFrequency(SPI_TOUCH_FREQUENCY);
// Start bit + YP sample request for x position
tmp = SPI.transfer(0xd0);
tmp = SPI.transfer(0);
tmp = tmp <<5;
tmp |= 0x1f & (SPI.transfer(0)>>3);
if(tmp == 0 || tmp == 0x3ff){
T_CS_H;
SPI.setFrequency(SPI_FREQUENCY);
return false;
}
*x = tmp;
// Start bit + XP sample request for y position
SPI.transfer(0x90);
tmp = SPI.transfer(0);
tmp = tmp <<5;
tmp |= 0x1f & (SPI.transfer(0)>>3);
*y = tmp;
T_CS_H;
SPI.setFrequency(SPI_FREQUENCY);
if(tmp == 0 || tmp == 0x3ff){
return false;
}
return true;
}
/***************************************************************************************
** Function name: getTouch
** Description: read callibrated position of touchpad if pressed. Return false if not pressed.
***************************************************************************************/
uint8_t TFT_eSPI::getTouch(uint16_t *x, uint16_t *y){
uint8_t retVal;
uint16_t x_tmp, y_tmp;
retVal = getTouchRaw(&x_tmp,&y_tmp);
if(!retVal)
return retVal;
*x=(x_tmp-touchCalibration_x0)*_width/(touchCalibration_x1-touchCalibration_x0);
*y=(y_tmp-touchCalibration_y0)*_height/(touchCalibration_y1-touchCalibration_y0);
return retVal;
}
/***************************************************************************************
** Function name: calibrateTouch
** Description: generates calibration data for touchscreen.
***************************************************************************************/
uint8_t TFT_eSPI::calibrateTouch(uint16_t *data, uint32_t color_bg, uint32_t color_fg, uint8_t size){
uint16_t values[] = {0,0,0,0,0,0,0,0};
uint16_t x_tmp, y_tmp;
for(uint8_t i = 0; i<4; i++){
fillRect(0, 0, size+1, size+1, color_bg);
fillRect(0, _height-size-1, size+1, size+1, color_bg);
fillRect(_width-size-1, 0, size+1, size+1, color_bg);
fillRect(_width-size-1, _height-size-1, size+1, size+1, color_bg);
if (i == 5) break; // used to clear the arrows
switch (i) {
case 0: // up left
drawLine(0, 0, 0, size, color_fg);
drawLine(0, 0, size, 0, color_fg);
drawLine(0, 0, size , size, color_fg);
break;
case 1: // bot left
drawLine(0, _height-size-1, 0, _height-1, color_fg);
drawLine(0, _height-1, size, _height-1, color_fg);
drawLine(size, _height-size-1, 0, _height-1 , color_fg);
break;
case 2: // up right
drawLine(_width-size-1, 0, _width-1, 0, color_fg);
drawLine(_width-size-1, size, _width-1, 0, color_fg);
drawLine(_width-1, size, _width-1, 0, color_fg);
break;
case 3: // bot right
drawLine(_width-size-1, _height-size-1, _width-1, _height-1, color_fg);
drawLine(_width-1, _height-1-size, _width-1, _height-1, color_fg);
drawLine(_width-1-size, _height-1, _width-1, _height-1, color_fg);
break;
}
// user has to get the chance to release
if(i>0) delay(1000);
for(uint8_t j= 0; j<8; j++){
while(!getTouchRaw(&x_tmp, &y_tmp)) delay(100);
values[i*2 ] += x_tmp;
values[i*2+1] += y_tmp;
}
values[i*2 ] /= 8;
values[i*2+1] /= 8;
}
// TODO: build in orientation check!
touchCalibration_x0 = (values[0] + values[2])/2; // calc min x
touchCalibration_x1 = (values[4] + values[6])/2; // calc max x
touchCalibration_y0 = (values[1] + values[5])/2; // calc min y
touchCalibration_y1 = (values[3] + values[7])/2; // calc max y
if(data != NULL){
data[0] = touchCalibration_x0;
data[1] = touchCalibration_x1;
data[2] = touchCalibration_y0;
data[3] = touchCalibration_y1;
}
}
/***************************************************************************************
** Function name: setTouch
** Description: imports calibration data for touchscreen.
***************************************************************************************/
void TFT_eSPI::setTouch(uint16_t *data){
touchCalibration_x0 = data[0];
touchCalibration_x1 = data[1];
touchCalibration_y0 = data[2];
touchCalibration_y1 = data[3];
}
#endif
/***************************************************
The majority of code in this file is "FunWare", the only condition of use of
those portions is that users have fun! Most of the effort has been spent on