mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
add Auto set TS calibration Function
This commit is contained in:
@@ -597,4 +597,16 @@ config TOUCHSCREEN_PCAP
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called pcap_ts.
|
||||
|
||||
choice
|
||||
prompt "Touch panel resolution"
|
||||
default TP_800x480
|
||||
|
||||
config TP_800x480
|
||||
bool "800x480"
|
||||
|
||||
config TP_1024x600
|
||||
bool "1024x600"
|
||||
|
||||
endchoice
|
||||
endif
|
||||
|
||||
@@ -44,7 +44,7 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_XPT2046_SPI) += xpt2046_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI) += xpt2046_cbn_ts.o calibration_ts.o largenum_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI) += xpt2046_cbn_ts.o calibration_ts.o largenum_ts.o calib_iface_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_XPT2046_320X480_SPI) += xpt2046_ts_320X480.o
|
||||
#obj-$(CONFIG_TOUCHSCREEN_XPT2046_320X480_CBN_SPI) += xpt2046_cbn_ts.o calibration_ts.o largenum_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_IT7250) += ctp_it7250.o
|
||||
|
||||
@@ -38,8 +38,24 @@ typedef struct {
|
||||
CALIBRATION_PARAMETER, *PCALIBRATION_PARAMETER;
|
||||
|
||||
static unsigned char v_Calibrated = 0;
|
||||
static CALIBRATION_PARAMETER v_CalcParam;
|
||||
|
||||
static CALIBRATION_PARAMETER v_CalcParam ={
|
||||
.a1 =18670 ,
|
||||
.b1 =98,
|
||||
.c1 = -2230109,
|
||||
.a2 = 291,
|
||||
.b2 = 12758,
|
||||
.c2 = -5118934,
|
||||
.delta = 91931,
|
||||
};
|
||||
static CALIBRATION_PARAMETER v_CalcParam_bak = {
|
||||
.a1=17704 ,
|
||||
.b1=-20,
|
||||
.c1= -1460283,
|
||||
.a2 = 382,
|
||||
.b2 = 12685,
|
||||
.c2 = -5595261,
|
||||
.delta = 88403,
|
||||
};
|
||||
unsigned char
|
||||
ErrorAnalysis(
|
||||
int cCalibrationPoints, //@PARM The number of calibration points
|
||||
@@ -320,26 +336,30 @@ TouchPanelCalibrateAPoint(
|
||||
{
|
||||
int x, y;
|
||||
|
||||
if ( !v_Calibrated )
|
||||
if ( v_Calibrated )
|
||||
{
|
||||
*pCalX = 200; //UncalX;
|
||||
*pCalY = 160; //UncalY;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Note the *4 in the expression below. This is a workaround
|
||||
// on behalf of gwe. It provides a form of
|
||||
// sub-pixel accuracy desirable for inking
|
||||
//
|
||||
x = (v_CalcParam.a1 * UncalX + v_CalcParam.b1 * UncalY +
|
||||
v_CalcParam.c1) * 4 / v_CalcParam.delta;
|
||||
y = (v_CalcParam.a2 * UncalX + v_CalcParam.b2 * UncalY +
|
||||
v_CalcParam.c2) * 4 / v_CalcParam.delta;
|
||||
x = (v_CalcParam.a1 * UncalX + v_CalcParam.b1 * UncalY +
|
||||
v_CalcParam.c1) * 4 / v_CalcParam.delta;
|
||||
y = (v_CalcParam.a2 * UncalX + v_CalcParam.b2 * UncalY +
|
||||
v_CalcParam.c2) * 4 / v_CalcParam.delta;
|
||||
}
|
||||
else{
|
||||
x = (v_CalcParam_bak.a1 * UncalX + v_CalcParam_bak.b1 * UncalY +
|
||||
v_CalcParam_bak.c1) * 4 / v_CalcParam_bak.delta;
|
||||
y = (v_CalcParam_bak.a2 * UncalX + v_CalcParam_bak.b2 * UncalY +
|
||||
v_CalcParam_bak.c2) * 4 / v_CalcParam_bak.delta;
|
||||
}
|
||||
if ( x < 0 ){
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if ( y < 0 ){
|
||||
if (y < 0 ){
|
||||
y = 0;
|
||||
}
|
||||
|
||||
@@ -409,6 +429,7 @@ ErrorAnalysis(
|
||||
x,
|
||||
y
|
||||
);
|
||||
|
||||
dx = x - pScreenXBuffer[i];
|
||||
dy = y - pScreenYBuffer[i];
|
||||
err = dx * dx + dy * dy;
|
||||
@@ -422,17 +443,150 @@ ErrorAnalysis(
|
||||
|
||||
if (maxErr < (errThreshold * errThreshold))
|
||||
{
|
||||
printk(" v_CalcParam.a1=%d \n"
|
||||
"v_CalcParam.b1=%d\n"
|
||||
"v_CalcParam.c1= %d\n"
|
||||
" v_CalcParam.a2 = %d\n"
|
||||
" v_CalcParam.b2 = %d\n"
|
||||
" v_CalcParam.c2 = %d\n"
|
||||
"v_CalcParam.delta = %d\n",
|
||||
v_CalcParam.a1 , \
|
||||
v_CalcParam.b1 , \
|
||||
v_CalcParam.c1 , \
|
||||
v_CalcParam.a2 , \
|
||||
v_CalcParam.b2, \
|
||||
v_CalcParam.c2 , \
|
||||
v_CalcParam.delta);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&v_CalcParam, 0, sizeof(v_CalcParam));
|
||||
v_Calibrated = 0;
|
||||
|
||||
memset(&v_CalcParam, 0, sizeof(v_CalcParam));
|
||||
v_Calibrated = 0;
|
||||
v_CalcParam.a1 = v_CalcParam_bak.a1;
|
||||
v_CalcParam.b1 = v_CalcParam_bak.b1 ;
|
||||
v_CalcParam.c1= v_CalcParam_bak.c1;
|
||||
v_CalcParam.a2 = v_CalcParam_bak.a2;
|
||||
v_CalcParam.b2 = v_CalcParam_bak.b2;
|
||||
v_CalcParam.c2 = v_CalcParam_bak.c2;
|
||||
v_CalcParam.delta= v_CalcParam_bak.delta;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define FILTER_BUF_LEN 8
|
||||
typedef struct
|
||||
{
|
||||
unsigned short x;
|
||||
unsigned short y;
|
||||
}P;
|
||||
static P sTouchFilterBuff[FILTER_BUF_LEN];
|
||||
static int sBuffIndex = 0;
|
||||
static P sReportFilter = {0,0};
|
||||
void ClearBuff(void)
|
||||
{
|
||||
memset(sTouchFilterBuff,0,FILTER_BUF_LEN*sizeof(P));
|
||||
sReportFilter.x = 0;
|
||||
sReportFilter.y = 0;
|
||||
sBuffIndex = 0;
|
||||
}
|
||||
void addToBuff(int* x,int* y)
|
||||
{
|
||||
int index;
|
||||
index=sBuffIndex++%FILTER_BUF_LEN;
|
||||
sTouchFilterBuff[index].x = *x;
|
||||
sTouchFilterBuff[index].y = *y;
|
||||
}
|
||||
#define TS_ERR_TDOWN -1
|
||||
#define TS_ERR_LOWBUF -2
|
||||
//#define TS_MINX 138
|
||||
//#define TS_MINY 375
|
||||
//#define TS_MAXX 3935
|
||||
//#define TS_MAXY 3920
|
||||
//#define TS_xISVALID(x) (x>=TS_MINX&&x<=TS_MAXX)
|
||||
#define TS_isINVALID(X,Y) (X==4095||Y==4095||X==0||Y==0)
|
||||
#define ABS(x) ((x)>0?(x):-(x))
|
||||
static P spoint;
|
||||
int TouchFilter(unsigned short* x,unsigned short* y,bool isdown)
|
||||
{
|
||||
#if 1
|
||||
int ret = 0;
|
||||
if(isdown==0&&sBuffIndex==0)
|
||||
{
|
||||
spoint.x = *x;
|
||||
spoint.y = *y;
|
||||
ClearBuff();
|
||||
ret=TS_ERR_TDOWN;
|
||||
}
|
||||
if(!TS_isINVALID(x,y))
|
||||
addToBuff(x,y);
|
||||
if(sBuffIndex<FILTER_BUF_LEN)
|
||||
ret=TS_ERR_LOWBUF;
|
||||
if(ret==0)
|
||||
{
|
||||
P *p = sTouchFilterBuff;
|
||||
P *p1 = p+1;
|
||||
int index =0;
|
||||
while(1)
|
||||
{
|
||||
if(ABS(p->x-p1->x)<60||ABS(p->y-p1->y)<60)
|
||||
{
|
||||
*x=spoint.x;
|
||||
*y=spoint.y;
|
||||
//printk("p(%d,%d) p1(%d,%d)\n",p->x,p->y,p1->x,p1->y);
|
||||
//ret=-3;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
p1++;
|
||||
if(++index>=FILTER_BUF_LEN-1)break;
|
||||
}
|
||||
spoint.x=*x;
|
||||
spoint.y=*y;
|
||||
}
|
||||
|
||||
#else
|
||||
int ret = 0;
|
||||
if(isdown==0&&sBuffIndex==0)
|
||||
{
|
||||
ClearBuff();
|
||||
ret=TS_ERR_TDOWN;
|
||||
}
|
||||
if(!TS_isINVALID(x,y))
|
||||
addToBuff(x,y);
|
||||
if(sBuffIndex<FILTER_BUF_LEN)
|
||||
ret=TS_ERR_LOWBUF;
|
||||
if(ret==0)
|
||||
{
|
||||
P adp;
|
||||
int index =0;
|
||||
while(1)
|
||||
{
|
||||
adp.x+=sTouchFilterBuff[index].x;
|
||||
adp.y+=sTouchFilterBuff[index].y;
|
||||
if(++index>=FILTER_BUF_LEN)break;
|
||||
}
|
||||
*x = adp.x/FILTER_BUF_LEN;
|
||||
*y = adp.y/FILTER_BUF_LEN;
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
#define SLAP_X 2
|
||||
#define SLAP_Y 0
|
||||
void TouchReportFilter(unsigned short* x,unsigned short* y)
|
||||
{
|
||||
if((sReportFilter.x==0&&sReportFilter.y==0)||
|
||||
(ABS(sReportFilter.x - *x)>SLAP_X&&ABS(sReportFilter.y - *y)>SLAP_Y))
|
||||
{
|
||||
sReportFilter.x = *x;
|
||||
sReportFilter.y = *y;
|
||||
}
|
||||
*x = sReportFilter.x;
|
||||
*y = sReportFilter.y;
|
||||
}
|
||||
#if 0
|
||||
int main(void)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
#ifndef __DRIVERS_TOUCHSCREEN_CALIBRATION_TS_H
|
||||
#define __DRIVERS_TOUCHSCREEN_CALIBRATION_TS_H
|
||||
|
||||
struct adc_point
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
#define TWO_DIMENSIONAL_CALIBRATION 1
|
||||
|
||||
#define ADC_PRECISION 12 // Precision of ADC output (in bits)
|
||||
|
||||
@@ -201,110 +201,14 @@ typedef struct
|
||||
s16 y;
|
||||
}POINT;
|
||||
|
||||
#if (0)
|
||||
static struct xpt2046_platform_data xpt2046_info = {
|
||||
.model = 2046,
|
||||
.keep_vref_on = 1,
|
||||
.swap_xy = 0,
|
||||
.x_min = 0,
|
||||
.x_max = 800,
|
||||
.y_min = 0,
|
||||
.y_max = 480,
|
||||
.debounce_max = 7,
|
||||
.debounce_rep = DEBOUNCE_REPTIME,
|
||||
.debounce_tol = 20,
|
||||
.gpio_pendown = RK2818_PIN_PE3,
|
||||
.penirq_recheck_delay_usecs = 1,
|
||||
|
||||
};
|
||||
#endif /* (0) */
|
||||
static void xpt2046_enable(struct xpt2046 *ts);
|
||||
static void xpt2046_disable(struct xpt2046 *ts);
|
||||
|
||||
static POINT gADPoint;
|
||||
int screen_x[] = { 50, 750, 50, 750, 400};
|
||||
int screen_y[] = { 40, 40, 440, 440, 240};
|
||||
int uncali_x[] = {329, 3750, 331, 3757, 2046};
|
||||
int uncali_y[] = {593, 532, 3675, 3655, 2121};
|
||||
volatile struct adc_point gADPoint;
|
||||
|
||||
// This code is touch check
|
||||
static ssize_t xpt2046_mode_show(struct device_driver *drv,char *buf)
|
||||
{
|
||||
int count;
|
||||
|
||||
count = sprintf(buf,"xpt2046_mode_show:%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
|
||||
uncali_x[0], uncali_y[0],
|
||||
uncali_x[1], uncali_y[1],
|
||||
uncali_x[2], uncali_y[2],
|
||||
uncali_x[3], uncali_y[3],
|
||||
uncali_x[4], uncali_y[4]);
|
||||
|
||||
printk("buf: %s", buf);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t xpt2046_mode_store(struct device_driver * drv, const char * buf, size_t count)
|
||||
{
|
||||
int i, j = 0;
|
||||
char temp[5];
|
||||
|
||||
printk("xpt2046_mode_store: %s\n", buf);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
strncpy(temp, buf + 5 * (j++), 4);
|
||||
uncali_x[i] = simple_strtol(temp, NULL, 10);
|
||||
strncpy(temp, buf + 5 * (j++), 4);
|
||||
uncali_y[i] = simple_strtol(temp, NULL, 10);
|
||||
printk("SN=%d uncali_x=%d uncali_y=%d\n",
|
||||
i, uncali_x[i], uncali_y[i]);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
//This code is Touch adc simple value
|
||||
static ssize_t xpt2046_adc_show(struct device_driver *drv,char *buf)
|
||||
{
|
||||
printk("xpt2046_adc_show: x=%d y=%d\n", gADPoint.x, gADPoint.y);
|
||||
|
||||
return sprintf(buf, "%d,%d\n", gADPoint.x, gADPoint.y);
|
||||
}
|
||||
|
||||
static ssize_t xpt2046_cali_status(struct device_driver *drv, char *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = TouchPanelSetCalibration(4, screen_x, screen_y, uncali_x, uncali_y);
|
||||
if (ret == 1)
|
||||
ret = sprintf(buf, "successful\n");
|
||||
else
|
||||
ret = sprintf(buf, "fail\n");
|
||||
|
||||
printk("xpt2046_cali_status: buf=<%s", buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//static DEVICE_ATTR(adc, 0666, xpt2046_adc_show, NULL);
|
||||
//static DEVICE_ATTR(calistatus, 0666, xpt2046_cali_status, NULL);
|
||||
//static DEVICE_ATTR(mode, 0666, xpt2046_mode_show, xpt2046_mode_store);
|
||||
static DRIVER_ATTR(touchadc, 0666, xpt2046_adc_show, NULL);
|
||||
static DRIVER_ATTR(calistatus, 0666, xpt2046_cali_status, NULL);
|
||||
static DRIVER_ATTR(touchcheck, 0666, xpt2046_mode_show, xpt2046_mode_store);
|
||||
#if (0)
|
||||
static struct attribute *xpt2046_attributes[] = {
|
||||
&dev_attr_touchadc.attr,
|
||||
&dev_attr_calistatus.attr,
|
||||
&dev_attr_touchcheck.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group xpt2046_attr_group = {
|
||||
.attrs = xpt2046_attributes,
|
||||
};
|
||||
#endif /* (0) */
|
||||
|
||||
static int device_suspended(struct device *dev)
|
||||
{
|
||||
@@ -1028,31 +932,29 @@ static struct spi_driver xpt2046_driver = {
|
||||
|
||||
static int __init xpt2046_init(void)
|
||||
{
|
||||
//return spi_register_driver(&xpt2046_driver);
|
||||
int ret = spi_register_driver(&xpt2046_driver);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
gADPoint.x = 0;
|
||||
gADPoint.y = 0;
|
||||
ret = driver_create_file(&xpt2046_driver.driver, &driver_attr_touchcheck);
|
||||
ret += driver_create_file(&xpt2046_driver.driver, &driver_attr_touchadc);
|
||||
ret += driver_create_file(&xpt2046_driver.driver, &driver_attr_calistatus);
|
||||
}
|
||||
xpt2046printk("Touch panel drive XPT2046 driver init...\n");
|
||||
|
||||
return ret;
|
||||
gADPoint.x = 0;
|
||||
gADPoint.y = 0;
|
||||
|
||||
int ret = spi_register_driver(&xpt2046_driver);
|
||||
if (ret)
|
||||
{
|
||||
printk("Register XPT2046 driver failed.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
module_init(xpt2046_init);
|
||||
|
||||
|
||||
static void __exit xpt2046_exit(void)
|
||||
{
|
||||
//spi_unregister_driver(&xpt2046_driver);
|
||||
driver_remove_file(&xpt2046_driver.driver, &driver_attr_touchcheck);
|
||||
driver_remove_file(&xpt2046_driver.driver, &driver_attr_touchadc);
|
||||
driver_remove_file(&xpt2046_driver.driver, &driver_attr_calistatus);
|
||||
|
||||
xpt2046printk("Touch panel drive XPT2046 driver exit...\n");
|
||||
spi_unregister_driver(&xpt2046_driver);
|
||||
}
|
||||
module_init(xpt2046_init);
|
||||
module_exit(xpt2046_exit);
|
||||
|
||||
MODULE_DESCRIPTION("rk2818 spi xpt2046 TouchScreen Driver");
|
||||
|
||||
Reference in New Issue
Block a user