Add XPT2046 touch controller support
supports esp8266 + RPi displays
This commit is contained in:
1 parent
ca54325fbc
commit
944e505f36
4 files changed
+195
-32
No files matched your search
+149
@@ -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
|
||||
|
||||
Reference in new issue
Block a user