add Auto set TS calibration Function

This commit is contained in:
srt
2010-09-14 10:17:18 +08:00
parent 3e6d5cc590
commit faafe749f4
5 changed files with 205 additions and 131 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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)

View File

@@ -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");