MAX_CARLINK_A270S/MXC_A27-PCB4.5-270T/ArkmicroFiles/libboard-amt630hv100/source/touch.c

998 lines
24 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "FreeRTOS.h"
#include "chip.h"
#include "board.h"
#include "touch.h"
#if !defined(VG_ONLY) && !defined(AWTK)
#include "lvgl/lvgl.h"
#else
typedef int16_t lv_coord_t;
typedef uint8_t lv_indev_state_t;
typedef struct {
lv_coord_t x;
lv_coord_t y;
} lv_point_t;
enum { LV_INDEV_STATE_REL = 0, LV_INDEV_STATE_PR };
enum {
LV_KEY_UP = 17, /*0x11*/
LV_KEY_DOWN = 18, /*0x12*/
LV_KEY_RIGHT = 19, /*0x13*/
LV_KEY_LEFT = 20, /*0x14*/
LV_KEY_ESC = 27, /*0x1B*/
LV_KEY_DEL = 127, /*0x7F*/
LV_KEY_BACKSPACE = 8, /*0x08*/
LV_KEY_ENTER = 10, /*0x0A, '\n'*/
LV_KEY_NEXT = 9, /*0x09, '\t'*/
LV_KEY_PREV = 11, /*0x0B, '*/
LV_KEY_HOME = 2, /*0x02, STX*/
LV_KEY_END = 3, /*0x03, ETX*/
};
typedef struct {
lv_point_t point; /**< For LV_INDEV_TYPE_POINTER the currently pressed point*/
uint32_t key; /**< For LV_INDEV_TYPE_KEYPAD the currently pressed key*/
uint32_t btn_id; /**< For LV_INDEV_TYPE_BUTTON the currently pressed button*/
int16_t enc_diff; /**< For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/
lv_indev_state_t state; /**< LV_INDEV_STATE_REL or LV_INDEV_STATE_PR*/
} lv_indev_data_t;
#endif
#ifdef ADC_TOUCH
#define TOUCH_STATE_IDLE 0
#define TOUCH_STATE_START 1
#define TOUCH_STATE_SAMPLE 2
#define TOUCH_STATE_STOP 3
#define MAX_POINT_POOL_SIZE 2
#define FILTER_MAX 3
#define MAXPANADCLEN 20
typedef struct {
int x;
int y;
} POINT;
typedef struct
{
UINT16 adcX;
UINT16 adcY;
} PAN_DATA;
typedef struct
{
UINT32 *pValue;
UINT32 header;
UINT32 trail;
UINT32 quelen;
} ADCValueQueue;
static calibration cal;
static UINT32 lg_ulTouchMachineState = TOUCH_STATE_IDLE;
static POINT lg_stLastMovePoint;
ADCValueQueue panADCXQueue;
ADCValueQueue panADCYQueue;
UINT32 PANADC_X[MAXPANADCLEN];
UINT32 PANADC_Y[MAXPANADCLEN];
static INT32 Queue_ADCValue_Init(ADCValueQueue *pQueue, UINT32 *pValue, UINT32 quelen)
{
INT32 ret=0;
if((pQueue != 0) && (pValue != 0) && (quelen > 0))
{
pQueue->pValue = pValue;
pQueue->quelen = quelen;
pQueue->header = 0;
pQueue->trail = 0;
ret =1;
}
return ret;
}
static INT32 Queue_ADCValue_Length(ADCValueQueue *pQueue)
{
INT32 queuelen=0;
if(pQueue != 0)
{
if(pQueue->trail < pQueue->header)
{
queuelen = pQueue->quelen +(pQueue->trail- pQueue->header);
}
else
queuelen = pQueue->trail- pQueue->header;
}
return queuelen;
}
static INT32 Queue_ADCValue_Add(ADCValueQueue *pQueue,unsigned int value)
{
INT32 ret=0;
UINT32 *pValue=0;
if(pQueue != 0)
{
pValue = pQueue->pValue + pQueue->trail;
*pValue = value;
pQueue->trail++;
if(pQueue->trail >= pQueue->quelen)
{
pQueue->trail = 0;
}
if(pQueue->trail == pQueue->header)
{
pQueue->header++;
if(pQueue->header >= pQueue->quelen)
{
pQueue->header = 1;
pQueue->trail=0;
}
}
ret=1;
}
return ret;
}
static INT32 Queue_ADCValue_Read(ADCValueQueue *pQueue, UINT32 *pValue)
{
INT32 ret=0;
UINT32 *pHeaderValue=0;
if((pQueue != 0) && (pValue != 0))
{
if(Queue_ADCValue_Length(pQueue) > 0)
{
pHeaderValue = pQueue->pValue + pQueue->header;
*pValue = *pHeaderValue;
pQueue->header++;
if(pQueue->header >= pQueue->quelen)
{
pQueue->header = 0;
}
ret=1;
}
}
return ret;
}
//////////////////////////////////////////////////
static UINT32 GetADCTouch(PAN_DATA *pPan)
{
UINT32 panX;
UINT32 panY;
INT32 ret=0;
if(pPan != 0)
{
ret = Queue_ADCValue_Read(&panADCXQueue,&panX);
if(ret==1)
{
ret = Queue_ADCValue_Read(&panADCYQueue,&panY);
if(ret == 1)
{
pPan->adcX = panX;
pPan->adcY = panY;
}
}
}
return ret;
}
static void CalcCoord(PAN_DATA *pPan, POINT *pPT);
#define TOUCH_DOT_REGION 10
extern void SendTouchInputEventFromISR(lv_indev_data_t *indata);
/***********************************************************************************************
通过大量试验发现触摸屏存在的问题有
1: 触摸刚开始的几个点可能任意哪个点或者哪几个点会有较大偏差;
2: 释放前的采样点很大几率不准确。
为了应对各种错误情况,采取的措施有
1: 首先简单地丢弃掉最后一个采样点
2: 提高采样频率,保证最开始的几个采样点都在一个比较小的范围
内(即使快速滑动,刚开始不会有很大速度,因此也能保证起始点
比较聚集)。在这种前提下提取开始采样时的若干个点进行分析,
找出坐标值比较接近的点数最多的点,其他点则认为是错误点丢
弃掉,如果找不到的话则认为所有点都不稳定,重新再提取之后
的若干个点进行分析。
*************************************************************************************************/
#define SCOPE_ADJUST 8
#define ANALYSIS_POINT_SUCCESS 3
#define ANALYSIS_POINT_COUNT 5
#define DISCARD_POINT_COUNT 2
#define POINT_POOL_SIZE (ANALYSIS_POINT_COUNT+DISCARD_POINT_COUNT)
#define MYABS(x) (((x)>=0) ? (x) : (-(x)))
/*
*********************************************************************************************************
* Description: 分析采样最开始的若干点,丢弃错误点
*
* Arguments : point[] : 采样点坐标值数组
num : 用于分析的采样点个数
*
* Returns : 有效点的个数返回0表示所有点都无效
* Notes : 剩余的有效点重新从原数组起始位置开始依次放置
*********************************************************************************************************
*/
static int Touch_Start_Analyse(POINT point[], int num)
{
int i, j;
int key[ANALYSIS_POINT_COUNT] = {0};
int near_by_point[ANALYSIS_POINT_COUNT] = {0};
int effective_near_by_points[ANALYSIS_POINT_COUNT] = {0};
int max = -1;
int samplecnt = 0;
if(num > ANALYSIS_POINT_COUNT)
num = ANALYSIS_POINT_COUNT;
for(i=0; i<num; i++)
{
//计算每个点和其接近的点的个数并记录下距离最近的点
near_by_point[i] = 1;
for(j=0; j<num; j++)
{
if(j == i)
continue;
if(MYABS(point[i].x - point[j].x)<SCOPE_ADJUST && MYABS(point[i].y - point[j].y)<SCOPE_ADJUST)
{
key[i]++;
near_by_point[j] = 1;
}
else
near_by_point[j] = 0;
}
//筛选出相近点数最多的点并记录下与其距离最近的点位置
if(key[i] > max)
{
max = key[i];
for(j=0;j<num;j++)
{
effective_near_by_points[j] = near_by_point[j];
}
}
}
//有效点个数不够,判定所有点都不稳定全部丢弃
if(max < ANALYSIS_POINT_SUCCESS-1)
return 0;
//移除所有无效点有效点从原数组位置0开始依次放置
for(i=0; i<num; i++)
{
if(effective_near_by_points[i])
{
point[samplecnt] = point[i];
samplecnt++;
}
}
return samplecnt;
}
static void Handler_Touch_IntEvent(UINT32 ulEvent, UINT32 lpParam, UINT32 wParam)
{
static int s_SampleCnt;
static int s_PoolIndex;
static POINT s_PointPool[POINT_POOL_SIZE];
switch(lg_ulTouchMachineState)
{
case TOUCH_STATE_IDLE:
if(ulEvent == TOUCH_START_EVENT)
{
lg_ulTouchMachineState = TOUCH_STATE_START;
s_SampleCnt = 0;
s_PoolIndex = 0;
}
break;
case TOUCH_STATE_START:
if(ulEvent == TOUCH_STOP_EVENT)
{
lg_ulTouchMachineState = TOUCH_STATE_IDLE;
}
else if(ulEvent == TOUCH_SAMPLE_EVENT)
{
POINT pt;
PAN_DATA stPanData;
lv_indev_data_t indata = {0};
int i;
//get cordinate
stPanData.adcX = lpParam;
stPanData.adcY = wParam;
CalcCoord(&stPanData, &pt);
if(pt.x < 0 || pt.y < 0)
return;
if(pt.x < 0 || pt.x >= LCD_WIDTH || pt.y < 0 || pt.y >= LCD_HEIGHT)
return;
//防止ANALYSIS_POINT_START个点内包含最后要丢弃的点刚开始要暂存
//ANALYSIS_POINT_START + DISCARD_POINT_END个点
if(s_SampleCnt < ANALYSIS_POINT_COUNT + DISCARD_POINT_COUNT)
{
s_PointPool[s_SampleCnt++] = pt;
if(s_SampleCnt < ANALYSIS_POINT_COUNT + DISCARD_POINT_COUNT)
return;
}
s_SampleCnt = Touch_Start_Analyse(s_PointPool, ANALYSIS_POINT_COUNT);
if(s_SampleCnt == 0)
{
for(i=0; i<DISCARD_POINT_COUNT; i++)
s_PointPool[i] = s_PointPool[ANALYSIS_POINT_COUNT+i];
s_SampleCnt = DISCARD_POINT_COUNT;
return;
}
//send press event
indata.point.x = s_PointPool[0].x;
indata.point.y = s_PointPool[0].y;
indata.state = LV_INDEV_STATE_PR;
SendTouchInputEventFromISR(&indata);
lg_ulTouchMachineState = TOUCH_STATE_SAMPLE;
//将为满足最后丢弃任务而暂存的点复制到分析后剩余点之后
for(i=0; i<DISCARD_POINT_COUNT; i++)
s_PointPool[s_SampleCnt + i] = s_PointPool[ANALYSIS_POINT_COUNT+i];
s_PoolIndex = 1;
//计算此时剩余的未操作的有效点数
s_SampleCnt = s_SampleCnt - 1 + DISCARD_POINT_COUNT;
//send move event in the pool
while(s_SampleCnt > DISCARD_POINT_COUNT)
{
int xdiff, ydiff;
unsigned int totaldiff;
xdiff = s_PointPool[s_PoolIndex].x - lg_stLastMovePoint.x;
ydiff = s_PointPool[s_PoolIndex].y - lg_stLastMovePoint.y;
totaldiff = xdiff * xdiff + ydiff * ydiff;
if(totaldiff > 4)
{
indata.point.x = s_PointPool[s_PoolIndex].x;
indata.point.y = s_PointPool[s_PoolIndex].y;
indata.state = LV_INDEV_STATE_PR;
SendTouchInputEventFromISR(&indata);
lg_stLastMovePoint.x = s_PointPool[s_PoolIndex].x;
lg_stLastMovePoint.y = s_PointPool[s_PoolIndex].y;
}
s_PoolIndex++;
s_SampleCnt--;
}
}
break;
case TOUCH_STATE_SAMPLE:
if(ulEvent == TOUCH_SAMPLE_EVENT)
{
//caculate move center cordinate
//if move, then send move event
PAN_DATA stPanData;
POINT pt;
int xDiff = 0, yDiff = 0;
unsigned int totalDiff = 0;
//get cordinate
stPanData.adcX = lpParam;
stPanData.adcY = wParam;
CalcCoord(&stPanData, &pt);
if(pt.x < 0 || pt.y < 0)
return;
if(pt.x < 0 || pt.x >= LCD_WIDTH || pt.y < 0 || pt.y >= LCD_HEIGHT)
return;
if(s_SampleCnt < DISCARD_POINT_COUNT)
{
int index = (s_PoolIndex+s_SampleCnt++) % POINT_POOL_SIZE;
s_PointPool[index] = pt;
return;
}
xDiff = s_PointPool[s_PoolIndex].x - lg_stLastMovePoint.x;
yDiff = s_PointPool[s_PoolIndex].y - lg_stLastMovePoint.y;
totalDiff = xDiff * xDiff + yDiff * yDiff;
if(totalDiff > 4)
{
lv_indev_data_t indata = {0};
indata.point.x = s_PointPool[s_PoolIndex].x;
indata.point.y = s_PointPool[s_PoolIndex].y;
indata.state = LV_INDEV_STATE_PR;
SendTouchInputEventFromISR(&indata);
lg_stLastMovePoint.x = s_PointPool[s_PoolIndex].x;
lg_stLastMovePoint.y = s_PointPool[s_PoolIndex].y;
}
s_PointPool[(s_PoolIndex+DISCARD_POINT_COUNT)%POINT_POOL_SIZE] = pt;
s_PoolIndex = (s_PoolIndex+1)%POINT_POOL_SIZE;
}
else if(ulEvent == TOUCH_STOP_EVENT)
{
lv_indev_data_t indata = {0};
//send release event
indata.point.x = lg_stLastMovePoint.x;
indata.point.y = lg_stLastMovePoint.y;
indata.state = LV_INDEV_STATE_REL;
SendTouchInputEventFromISR(&indata);
lg_ulTouchMachineState = TOUCH_STATE_IDLE;
}
break;
case TOUCH_STATE_STOP:
break;
}
}
static volatile UINT32 lg_bTouchStart = 0;
static UINT32 CheckTouchStart()
{
return lg_bTouchStart == 1;
}
static UINT32 CheckTouchStop()
{
return lg_bTouchStart == 0;
}
static UINT32 GetTouchSampleCounter()
{
return Queue_ADCValue_Length(&panADCXQueue);
}
static UINT32 lg_bTouchAdjusted = 0;
void TouchEventHandler(UINT32 ulEvent, UINT32 lpParam, UINT32 wParam)
{
if(lg_bTouchAdjusted)
{
Handler_Touch_IntEvent(ulEvent, lpParam, wParam);
}
else
{
if(ulEvent == TOUCH_START_EVENT)
{
lg_bTouchStart = 1;
Queue_ADCValue_Init(&panADCXQueue, PANADC_X, MAXPANADCLEN);
Queue_ADCValue_Init(&panADCYQueue, PANADC_Y, MAXPANADCLEN);
}
else if(ulEvent == TOUCH_SAMPLE_EVENT)
{
Queue_ADCValue_Add(&panADCXQueue,lpParam);
Queue_ADCValue_Add(&panADCYQueue,wParam);
}
else if(ulEvent == TOUCH_STOP_EVENT)
{
lg_bTouchStart = 0;
}
}
}
/***************************************************************************************
触摸屏坐标校验代码
***************************************************************************************/
#define GRID_RANGE 12
#define HIT_RANGE 2
#define ABS_HIT ((GRID_RANGE+HIT_RANGE)*2)
#define TOUCH_HIGH_EXACTION 0
#define TOUCH_MID_EXACTION 0
#define TOUCH_LOW_EXACTION 1
#define TOUCH_REVISE_DEBUG 1
#if TOUCH_REVISE_DEBUG
#define TOUCH_DEBUG_MSG(fmt, args...) printf(fmt, ##args)
#else
#define TOUCH_DEBUG_MSG(fmt, args...)
#endif
#define SYSTEM_ERROR 100.0
#define SCALE_AERROR 2// 3 这里考虑触摸屏的差异修改20130618
#define SCALE_DERROR 5
static double abs_ax,abs_dx,abs_ly,abs_ry;
static double abs_lx,abs_rx;
static double abs_err1,abs_err2,abs_err3,abs_err4,abs_err5;
static double abs_cx,abs_cy;
static int lg_direction = 0;
#if TOUCH_HIGH_EXACTION
#define SYSTEM_ERROR1 100.0
#elif TOUCH_MID_EXACTION
#define SYSTEM_ERROR1 150.0
#elif TOUCH_LOW_EXACTION
#define SYSTEM_ERROR1 200.0
#else
#define SYSTEM_ERROR1 150.0
#endif
/* static void InitializeCalibration(int a0, int a1, int a2, int a3, int a4, int a5, int a6)
{
cal.a[0] = a0;
cal.a[1] = a1;
cal.a[2] = a2;
cal.a[3] = a3;
cal.a[4] = a4;
cal.a[5] = a5;
cal.a[6] = a6;
} */
static void SaveCalibration(calibration *pCalibration)
{
}
static int perform_calibration(calibration *cal) {
int j;
float n, x, y, x2, y2, xy, z, zx, zy;
float det, a, b, c, e, f, i;
float scaling = 65536.0;
// Get sums for matrix
n = x = y = x2 = y2 = xy = 0;
for(j=0;j<5;j++) {
n += 1.0;
x += (float)cal->x[j];
y += (float)cal->y[j];
x2 += (float)(cal->x[j]*cal->x[j]);
y2 += (float)(cal->y[j]*cal->y[j]);
xy += (float)(cal->x[j]*cal->y[j]);
}
// Get determinant of matrix -- check if determinant is too small
det = n*(x2*y2 - xy*xy) + x*(xy*y - x*y2) + y*(x*xy - y*x2);
if(det < 0.1 && det > -0.1) {
printf("ts_calibrate: determinant is too small -- %f\n",det);
return 0;
}
// Get elements of inverse matrix
a = (x2*y2 - xy*xy)/det;
b = (xy*y - x*y2)/det;
c = (x*xy - y*x2)/det;
e = (n*y2 - y*y)/det;
f = (x*y - n*xy)/det;
i = (n*x2 - x*x)/det;
// Get sums for x calibration
z = zx = zy = 0;
for(j=0;j<5;j++) {
z += (float)cal->xfb[j];
zx += (float)(cal->xfb[j]*cal->x[j]);
zy += (float)(cal->xfb[j]*cal->y[j]);
}
// Now multiply out to get the calibration for framebuffer x coord
cal->a[0] = (int)((a*z + b*zx + c*zy)*(scaling));
cal->a[1] = (int)((b*z + e*zx + f*zy)*(scaling));
cal->a[2] = (int)((c*z + f*zx + i*zy)*(scaling));
// Get sums for y calibration
z = zx = zy = 0;
for(j=0;j<5;j++) {
z += (float)cal->yfb[j];
zx += (float)(cal->yfb[j]*cal->x[j]);
zy += (float)(cal->yfb[j]*cal->y[j]);
}
// Now multiply out to get the calibration for framebuffer y coord
cal->a[3] = (int)((a*z + b*zx + c*zy)*(scaling));
cal->a[4] = (int)((b*z + e*zx + f*zy)*(scaling));
cal->a[5] = (int)((c*z + f*zx + i*zy)*(scaling));
// If we got here, we're OK, so assign scaling to a[6] and return
cal->a[6] = (int)scaling;
return 1;
}
void CleanTouchAdjustParameter(void)
{
Queue_ADCValue_Init(&panADCXQueue, PANADC_X, MAXPANADCLEN);
Queue_ADCValue_Init(&panADCYQueue, PANADC_Y, MAXPANADCLEN);
lg_bTouchAdjusted = 0;
}
void TouchInit(void)
{
CleanTouchAdjustParameter();
}
static void CalcCoord(PAN_DATA *pPan, POINT *pPT)
{
pPT->x = (pPan->adcX * cal.a[1] + pPan->adcY * cal.a[2] + cal.a[0])/cal.a[6];
pPT->y = (pPan->adcX * cal.a[4] + pPan->adcY * cal.a[5] + cal.a[3])/cal.a[6];
}
static unsigned int GetTouchHit(PAN_DATA *pPan)
{
unsigned int PanReq;
PAN_DATA Pan[50];
unsigned int i, Count;
for(i = 0; i < 50; i++)
{
Pan[i].adcX = 0xFFFF;
Pan[i].adcY = 0xFFFF;
}
ReStartCheck:
while(!CheckTouchStart());
while(!CheckTouchStop());
if(GetTouchSampleCounter() < 16)
goto ReStartCheck;
AIC_DisableIT(ADC_IRQn);
while(1)
{
PanReq = GetADCTouch(&Pan[49]);
if(PanReq==0)
{
break;
}
for(i = 0; i < 49; i++)
{
Pan[i].adcX = Pan[i+1].adcX;
Pan[i].adcY = Pan[i+1].adcY;
}
}
AIC_EnableIT(ADC_IRQn);
Count = 0;
for(i = 0; i < 49; i++)
{
if(Pan[i].adcY < 0xFFF)
{
Count++;
}
}
pPan->adcX = Pan[49-Count/2].adcX;
pPan->adcY = Pan[49-Count/2].adcY;
TOUCH_DEBUG_MSG("Hit Count = %d\n", Count);
TOUCH_DEBUG_MSG("pPan->adcX=%d\n",pPan->adcX);
TOUCH_DEBUG_MSG("pPan->adcY=%d\n",pPan->adcY);
return TRUE;
}
static void ClearBitmap(lv_color_t color, const lv_area_t * area, lv_color_t * color_p)
{
/*Truncate the area to the screen*/
int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
int32_t act_x2 = area->x2 > LCD_WIDTH - 1 ? LCD_WIDTH - 1 : area->x2;
int32_t act_y2 = area->y2 > LCD_HEIGHT - 1 ? LCD_HEIGHT - 1 : area->y2;
/*32 or 24 bit per pixel*/
if(LCD_BPP == 32) {
uint32_t * fbp32 = (uint32_t *)color_p;
int32_t x, y;
for(y = act_y1; y <= act_y2; y++) {
fbp32 = (uint32_t *)color_p + y * LCD_WIDTH;
for (x = act_x1; x <= act_x2; x++)
fbp32[x] = color.full;
}
}
/*16 bit per pixel*/
else if(LCD_BPP == 16) {
uint16_t * fbp16 = (uint16_t *)color_p;
int32_t x, y;
for(y = act_y1; y <= act_y2; y++) {
fbp16 = (uint16_t *)color_p + y * LCD_WIDTH;
for (x = act_x1; x <= act_x2; x++)
fbp16[x] = color.full;
}
}
}
static void PutHitCursor(int x, int y)
{
lv_area_t area;
area.x1 = x - GRID_RANGE;
area.y1 = y;
area.x2 = x + GRID_RANGE + HIT_RANGE - 1;
area.y2 = y + HIT_RANGE - 1;
ClearBitmap(LV_COLOR_WHITE, &area, (lv_color_t*)ark_lcd_get_virt_addr());
area.x1 = x;
area.y1 = y - GRID_RANGE;
area.x2 = x + HIT_RANGE - 1;
area.y2 = y + GRID_RANGE + HIT_RANGE - 1;
ClearBitmap(LV_COLOR_WHITE, &area, (lv_color_t*)ark_lcd_get_virt_addr());
area.x1 = x;
area.y1 = y;
area.x2 = x + HIT_RANGE - 1;
area.y2 = y + HIT_RANGE - 1;
ClearBitmap(LV_COLOR_BLACK, &area, (lv_color_t*)ark_lcd_get_virt_addr());
CP15_clean_dcache_for_dma((uint32_t)(lv_color_t*)ark_lcd_get_virt_addr(),
(uint32_t)(lv_color_t*)ark_lcd_get_virt_addr() + FB_SIZE);
}
static void ClrHitCursor(int x, int y)
{
lv_area_t area;
area.x1 = x - GRID_RANGE;
area.y1 = y - GRID_RANGE;
area.x2 = x + GRID_RANGE + HIT_RANGE - 1;
area.y2 = y + GRID_RANGE + HIT_RANGE - 1;
ClearBitmap(LV_COLOR_BLACK, &area, (lv_color_t*)ark_lcd_get_virt_addr());
CP15_clean_dcache_for_dma((uint32_t)(lv_color_t*)ark_lcd_get_virt_addr(),
(uint32_t)(lv_color_t*)ark_lcd_get_virt_addr() + FB_SIZE);
}
static int compare_data(calibration *cal)
{
int ret=0;
int diff_x;
int diff_y;
diff_x = (int)fabs(cal->x[0] - cal->x[1]);
diff_y = (int)fabs(cal->y[0] - cal->y[1]);
if(diff_x > diff_y)
lg_direction = 0;
else
lg_direction = 1;
TOUCH_DEBUG_MSG("lg_direction = %d\r\n", lg_direction);
if(lg_direction == 0)
{
if((cal->x [0]<cal->x [1])&&(cal->x [3]<cal->x [2]))
ret=1;
if((cal->x [0]>cal->x [1])&&(cal->x [3]>cal->x [2]))
ret=1;
}
else
{
if((cal->y[0]<cal->y[1])&&(cal->y[3]<cal->y[2]))
ret=1;
if((cal->y[0]>cal->y[1])&&(cal->y[3]>cal->y[2]))
ret=1;
}
return ret;
}
static int square_judge(calibration *cal)
{
int ret=0;
if(lg_direction == 0)
{
abs_ax=fabs(cal->x [0] - cal->x [1]);
abs_dx=fabs(cal->x [2]-cal->x [3]);
abs_err1=fabs(abs_ax -abs_dx);
TOUCH_DEBUG_MSG("***abs_ax=%d, abs_dx=%d, abs_err1=%d, SYSTEM_ERROR1=%d*******\n", (int)abs_ax, (int)abs_dx, (int)abs_err1, (int)SYSTEM_ERROR1);
abs_lx=fabs(cal->x [0]-cal->x [4]);
abs_rx=fabs(cal->x[3]-cal->x [4]);
abs_err2=fabs(abs_lx -abs_rx);
TOUCH_DEBUG_MSG("***abs_lx=%d,abs_rx=%d,abs_err2=%d****2\n", (int)abs_lx, (int)abs_rx, (int)abs_err2);
abs_ly=fabs(cal->y [0]-cal->y [3]);
abs_ry=fabs(cal->y [1]-cal->y [2]);
abs_err3=fabs(abs_ly -abs_ry);
TOUCH_DEBUG_MSG("***abs_ly=%d, abs_ry=%d, abs_err3=%d****2\n", (int)abs_ly, (int)abs_ry, (int)abs_err3);
if(abs_err1<SYSTEM_ERROR1&&abs_err2<SYSTEM_ERROR1&&abs_err3<SYSTEM_ERROR1)
ret=1;
}
else
{
abs_ax=fabs(cal->y[0] - cal->y[1]);
abs_dx=fabs(cal->y[2]-cal->y[3]);
abs_err1=fabs(abs_ax -abs_dx);
TOUCH_DEBUG_MSG("***abs_ax=%d, abs_dx=%d, abs_err1=%d, SYSTEM_ERROR1=%d*******\n", (int)abs_ax, (int)abs_dx, (int)abs_err1, (int)SYSTEM_ERROR1);
abs_lx=fabs(cal->y[0]-cal->y[4]);
abs_rx=fabs(cal->y[3]-cal->y[4]);
abs_err2=fabs(abs_lx -abs_rx);
TOUCH_DEBUG_MSG("***abs_lx=%d, abs_rx=%d, abs_err2=%d****2\n", (int)abs_lx, (int)abs_rx, (int)abs_err2);
abs_ly=fabs(cal->x[0]-cal->x[3]);
abs_ry=fabs(cal->x[1]-cal->x[2]);
abs_err3=fabs(abs_ly -abs_ry);
TOUCH_DEBUG_MSG("***abs_ly=%d, abs_ry=%d, abs_err3=%d****2\n", (int)abs_ly, (int)abs_ry, (int)abs_err3);
if(abs_err1<SYSTEM_ERROR1&&abs_err2<SYSTEM_ERROR1&&abs_err3<SYSTEM_ERROR1)
ret=1;
}
TOUCH_DEBUG_MSG("***ret=%d****4\n",ret);
return ret;
}
static int judge_center(calibration *cal)
{
int ret=0;
if(lg_direction == 0)
{
abs_cx=fabs(cal->x [4]-cal->x [0])*2;
abs_cy=fabs(cal->y [4]-cal->y [0])*2;
abs_err4=fabs(abs_cx -abs_ax);
abs_err5=fabs(abs_cy -abs_ly);
TOUCH_DEBUG_MSG("***abs_cx=%d, abs_cy=%d, abs_err4=%d, abs_err5=%d****2\n", (int)abs_cx, (int)abs_cy, (int)abs_err4, (int)abs_err5);
if(abs_err4<SYSTEM_ERROR1&&abs_err5<SYSTEM_ERROR1)
ret=1;
}
else
{
abs_cx=fabs(cal->y[4]-cal->y[0])*2;
abs_cy=fabs(cal->x[4]-cal->x[0])*2;
abs_err4=fabs(abs_cx -abs_ax);
abs_err5=fabs(abs_cy -abs_ly);
TOUCH_DEBUG_MSG("***abs_cx=%d, abs_cy=%d, abs_err4=%d, abs_err5=%d****2\n", (int)abs_cx, (int)abs_cy, (int)abs_err4, (int)abs_err5);
if(abs_err4<SYSTEM_ERROR1&&abs_err5<SYSTEM_ERROR1)
ret=1;
}
return ret;
}
static int filter_data(calibration *cal)
{
int ret=0;
float abs_lcd;
int scale;
int i;
TOUCH_DEBUG_MSG("***filter_data****1\n");
for(i=0;i<5;i++)
{
TOUCH_DEBUG_MSG("cal->x[%d] = %d, cal->y[%d] = %d\r\n", i, (int)cal->x[i], i, (int)cal->y[i]);
}
if(compare_data( cal))
{
TOUCH_DEBUG_MSG("*** Pass compare_data ****\n");
if(square_judge(cal))
{
TOUCH_DEBUG_MSG("*** Pass square_judge ****\n");
abs_lcd=fabs(cal->xfb[1] -cal->xfb[0]);
TOUCH_DEBUG_MSG("***abs_ax=%d, abs_lcd=%d****\n", (int)abs_ax, (int)abs_lcd);
scale=(int)(abs_ax/abs_lcd);
TOUCH_DEBUG_MSG("***scale=%d****4\n",scale);
if(SCALE_AERROR<scale&&SCALE_DERROR>scale)
{
TOUCH_DEBUG_MSG("*** Scale check ok ****\n");
if(judge_center(cal))
{
ret=1;
}
else
{
TOUCH_DEBUG_MSG("*** Failed at judge_center****\n");
}
}
}
}
TOUCH_DEBUG_MSG("*** filter_data ret=%d****\n",ret);
return ret;
}
static void get_sample (calibration *cal,
int index, int x, int y, char *name)
{
PAN_DATA ts_cord;
PutHitCursor(x, y);
// getxy (ts, &cal->x [index], &cal->y [index]);
GetTouchHit(&ts_cord);
cal->x [index] = ts_cord.adcX;
cal->y [index] = ts_cord.adcY;
ClrHitCursor(x, y);
cal->xfb [index] = x;
cal->yfb [index] = y;
TOUCH_DEBUG_MSG("get_sample %s : X = %4d Y = %4d\n", name, cal->x [index], cal->y [index]);
}
unsigned int AdjustTouch(void)
{
unsigned int i;
#if 0
cal.a[0]=56822272;
cal.a[1]=-14948;
cal.a[2]=36;
cal.a[3]=38820672;
cal.a[4]=-59;
cal.a[5]=-11704;
cal.a[6]=65536;
lg_bTouchAdjusted = 1;
#else
while(1)
{
get_sample (&cal, 0, 50, 50, "Top left");
get_sample (&cal, 1, LCD_WIDTH - 50, 50, "Top right");
get_sample (&cal, 2, LCD_WIDTH - 50, LCD_HEIGHT - 50, "Bot right");
get_sample (&cal, 3, 50, LCD_HEIGHT - 50, "Bot left");
get_sample (&cal, 4, LCD_WIDTH / 2, LCD_HEIGHT / 2, "Center");
if(filter_data(&cal))
{
perform_calibration (&cal);
for(i=0;i<7;i++)
{
printf("the result cal->a[%d]=%d\n", i, cal.a[i]);
}
SaveCalibration(&cal);
break;
}
}
#endif
lg_bTouchAdjusted = 1;
return 0; // 5次均无效, 取默认值
}
int LoadTouchConfigure(void)
{
return -1;
}
#endif