touch.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <stdlib.h>
  4. #include "FreeRTOS.h"
  5. #include "chip.h"
  6. #include "board.h"
  7. #include "touch.h"
  8. #if !defined(VG_ONLY) && !defined(AWTK)
  9. #else
  10. typedef int16_t lv_coord_t;
  11. typedef uint8_t lv_indev_state_t;
  12. typedef struct {
  13. lv_coord_t x;
  14. lv_coord_t y;
  15. } lv_point_t;
  16. enum { LV_INDEV_STATE_REL = 0, LV_INDEV_STATE_PR };
  17. enum {
  18. LV_KEY_UP = 17, /*0x11*/
  19. LV_KEY_DOWN = 18, /*0x12*/
  20. LV_KEY_RIGHT = 19, /*0x13*/
  21. LV_KEY_LEFT = 20, /*0x14*/
  22. LV_KEY_ESC = 27, /*0x1B*/
  23. LV_KEY_DEL = 127, /*0x7F*/
  24. LV_KEY_BACKSPACE = 8, /*0x08*/
  25. LV_KEY_ENTER = 10, /*0x0A, '\n'*/
  26. LV_KEY_NEXT = 9, /*0x09, '\t'*/
  27. LV_KEY_PREV = 11, /*0x0B, '*/
  28. LV_KEY_HOME = 2, /*0x02, STX*/
  29. LV_KEY_END = 3, /*0x03, ETX*/
  30. };
  31. typedef struct {
  32. lv_point_t point; /**< For LV_INDEV_TYPE_POINTER the currently pressed point*/
  33. uint32_t key; /**< For LV_INDEV_TYPE_KEYPAD the currently pressed key*/
  34. uint32_t btn_id; /**< For LV_INDEV_TYPE_BUTTON the currently pressed button*/
  35. int16_t enc_diff; /**< For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/
  36. lv_indev_state_t state; /**< LV_INDEV_STATE_REL or LV_INDEV_STATE_PR*/
  37. } lv_indev_data_t;
  38. #endif
  39. #ifdef ADC_TOUCH
  40. #define TOUCH_STATE_IDLE 0
  41. #define TOUCH_STATE_START 1
  42. #define TOUCH_STATE_SAMPLE 2
  43. #define TOUCH_STATE_STOP 3
  44. #define MAX_POINT_POOL_SIZE 2
  45. #define FILTER_MAX 3
  46. #define MAXPANADCLEN 20
  47. typedef struct {
  48. int x;
  49. int y;
  50. } POINT;
  51. typedef struct
  52. {
  53. UINT16 adcX;
  54. UINT16 adcY;
  55. } PAN_DATA;
  56. typedef struct
  57. {
  58. UINT32 *pValue;
  59. UINT32 header;
  60. UINT32 trail;
  61. UINT32 quelen;
  62. } ADCValueQueue;
  63. static calibration cal;
  64. static UINT32 lg_ulTouchMachineState = TOUCH_STATE_IDLE;
  65. static POINT lg_stLastMovePoint;
  66. ADCValueQueue panADCXQueue;
  67. ADCValueQueue panADCYQueue;
  68. UINT32 PANADC_X[MAXPANADCLEN];
  69. UINT32 PANADC_Y[MAXPANADCLEN];
  70. static INT32 Queue_ADCValue_Init(ADCValueQueue *pQueue, UINT32 *pValue, UINT32 quelen)
  71. {
  72. INT32 ret=0;
  73. if((pQueue != 0) && (pValue != 0) && (quelen > 0))
  74. {
  75. pQueue->pValue = pValue;
  76. pQueue->quelen = quelen;
  77. pQueue->header = 0;
  78. pQueue->trail = 0;
  79. ret =1;
  80. }
  81. return ret;
  82. }
  83. static INT32 Queue_ADCValue_Length(ADCValueQueue *pQueue)
  84. {
  85. INT32 queuelen=0;
  86. if(pQueue != 0)
  87. {
  88. if(pQueue->trail < pQueue->header)
  89. {
  90. queuelen = pQueue->quelen +(pQueue->trail- pQueue->header);
  91. }
  92. else
  93. queuelen = pQueue->trail- pQueue->header;
  94. }
  95. return queuelen;
  96. }
  97. static INT32 Queue_ADCValue_Add(ADCValueQueue *pQueue,unsigned int value)
  98. {
  99. INT32 ret=0;
  100. UINT32 *pValue=0;
  101. if(pQueue != 0)
  102. {
  103. pValue = pQueue->pValue + pQueue->trail;
  104. *pValue = value;
  105. pQueue->trail++;
  106. if(pQueue->trail >= pQueue->quelen)
  107. {
  108. pQueue->trail = 0;
  109. }
  110. if(pQueue->trail == pQueue->header)
  111. {
  112. pQueue->header++;
  113. if(pQueue->header >= pQueue->quelen)
  114. {
  115. pQueue->header = 1;
  116. pQueue->trail=0;
  117. }
  118. }
  119. ret=1;
  120. }
  121. return ret;
  122. }
  123. static INT32 Queue_ADCValue_Read(ADCValueQueue *pQueue, UINT32 *pValue)
  124. {
  125. INT32 ret=0;
  126. UINT32 *pHeaderValue=0;
  127. if((pQueue != 0) && (pValue != 0))
  128. {
  129. if(Queue_ADCValue_Length(pQueue) > 0)
  130. {
  131. pHeaderValue = pQueue->pValue + pQueue->header;
  132. *pValue = *pHeaderValue;
  133. pQueue->header++;
  134. if(pQueue->header >= pQueue->quelen)
  135. {
  136. pQueue->header = 0;
  137. }
  138. ret=1;
  139. }
  140. }
  141. return ret;
  142. }
  143. //////////////////////////////////////////////////
  144. static UINT32 GetADCTouch(PAN_DATA *pPan)
  145. {
  146. UINT32 panX;
  147. UINT32 panY;
  148. INT32 ret=0;
  149. if(pPan != 0)
  150. {
  151. ret = Queue_ADCValue_Read(&panADCXQueue,&panX);
  152. if(ret==1)
  153. {
  154. ret = Queue_ADCValue_Read(&panADCYQueue,&panY);
  155. if(ret == 1)
  156. {
  157. pPan->adcX = panX;
  158. pPan->adcY = panY;
  159. }
  160. }
  161. }
  162. return ret;
  163. }
  164. static void CalcCoord(PAN_DATA *pPan, POINT *pPT);
  165. #define TOUCH_DOT_REGION 10
  166. extern void SendTouchInputEventFromISR(lv_indev_data_t *indata);
  167. /***********************************************************************************************
  168. 通过大量试验发现触摸屏存在的问题有
  169. 1: 触摸刚开始的几个点可能任意哪个点或者哪几个点会有较大偏差;
  170. 2: 释放前的采样点很大几率不准确。
  171. 为了应对各种错误情况,采取的措施有
  172. 1: 首先简单地丢弃掉最后一个采样点
  173. 2: 提高采样频率,保证最开始的几个采样点都在一个比较小的范围
  174. 内(即使快速滑动,刚开始不会有很大速度,因此也能保证起始点
  175. 比较聚集)。在这种前提下提取开始采样时的若干个点进行分析,
  176. 找出坐标值比较接近的点数最多的点,其他点则认为是错误点丢
  177. 弃掉,如果找不到的话则认为所有点都不稳定,重新再提取之后
  178. 的若干个点进行分析。
  179. *************************************************************************************************/
  180. #define SCOPE_ADJUST 8
  181. #define ANALYSIS_POINT_SUCCESS 3
  182. #define ANALYSIS_POINT_COUNT 5
  183. #define DISCARD_POINT_COUNT 2
  184. #define POINT_POOL_SIZE (ANALYSIS_POINT_COUNT+DISCARD_POINT_COUNT)
  185. #define MYABS(x) (((x)>=0) ? (x) : (-(x)))
  186. /*
  187. *********************************************************************************************************
  188. * Description: 分析采样最开始的若干点,丢弃错误点
  189. *
  190. * Arguments : point[] : 采样点坐标值数组
  191. num : 用于分析的采样点个数
  192. *
  193. * Returns : 有效点的个数,返回0表示所有点都无效
  194. * Notes : 剩余的有效点重新从原数组起始位置开始依次放置
  195. *********************************************************************************************************
  196. */
  197. static int Touch_Start_Analyse(POINT point[], int num)
  198. {
  199. int i, j;
  200. int key[ANALYSIS_POINT_COUNT] = {0};
  201. int near_by_point[ANALYSIS_POINT_COUNT] = {0};
  202. int effective_near_by_points[ANALYSIS_POINT_COUNT] = {0};
  203. int max = -1;
  204. int samplecnt = 0;
  205. if(num > ANALYSIS_POINT_COUNT)
  206. num = ANALYSIS_POINT_COUNT;
  207. for(i=0; i<num; i++)
  208. {
  209. //计算每个点和其接近的点的个数并记录下距离最近的点
  210. near_by_point[i] = 1;
  211. for(j=0; j<num; j++)
  212. {
  213. if(j == i)
  214. continue;
  215. if(MYABS(point[i].x - point[j].x)<SCOPE_ADJUST && MYABS(point[i].y - point[j].y)<SCOPE_ADJUST)
  216. {
  217. key[i]++;
  218. near_by_point[j] = 1;
  219. }
  220. else
  221. near_by_point[j] = 0;
  222. }
  223. //筛选出相近点数最多的点并记录下与其距离最近的点位置
  224. if(key[i] > max)
  225. {
  226. max = key[i];
  227. for(j=0;j<num;j++)
  228. {
  229. effective_near_by_points[j] = near_by_point[j];
  230. }
  231. }
  232. }
  233. //有效点个数不够,判定所有点都不稳定全部丢弃
  234. if(max < ANALYSIS_POINT_SUCCESS-1)
  235. return 0;
  236. //移除所有无效点,有效点从原数组位置0开始依次放置
  237. for(i=0; i<num; i++)
  238. {
  239. if(effective_near_by_points[i])
  240. {
  241. point[samplecnt] = point[i];
  242. samplecnt++;
  243. }
  244. }
  245. return samplecnt;
  246. }
  247. static void Handler_Touch_IntEvent(UINT32 ulEvent, UINT32 lpParam, UINT32 wParam)
  248. {
  249. static int s_SampleCnt;
  250. static int s_PoolIndex;
  251. static POINT s_PointPool[POINT_POOL_SIZE];
  252. switch(lg_ulTouchMachineState)
  253. {
  254. case TOUCH_STATE_IDLE:
  255. if(ulEvent == TOUCH_START_EVENT)
  256. {
  257. lg_ulTouchMachineState = TOUCH_STATE_START;
  258. s_SampleCnt = 0;
  259. s_PoolIndex = 0;
  260. }
  261. break;
  262. case TOUCH_STATE_START:
  263. if(ulEvent == TOUCH_STOP_EVENT)
  264. {
  265. lg_ulTouchMachineState = TOUCH_STATE_IDLE;
  266. }
  267. else if(ulEvent == TOUCH_SAMPLE_EVENT)
  268. {
  269. POINT pt;
  270. PAN_DATA stPanData;
  271. lv_indev_data_t indata = {0};
  272. int i;
  273. //get cordinate
  274. stPanData.adcX = lpParam;
  275. stPanData.adcY = wParam;
  276. CalcCoord(&stPanData, &pt);
  277. if(pt.x < 0 || pt.y < 0)
  278. return;
  279. if(pt.x < 0 || pt.x >= LCD_WIDTH || pt.y < 0 || pt.y >= LCD_HEIGHT)
  280. return;
  281. //防止ANALYSIS_POINT_START个点内包含最后要丢弃的点,刚开始要暂存
  282. //ANALYSIS_POINT_START + DISCARD_POINT_END个点
  283. if(s_SampleCnt < ANALYSIS_POINT_COUNT + DISCARD_POINT_COUNT)
  284. {
  285. s_PointPool[s_SampleCnt++] = pt;
  286. if(s_SampleCnt < ANALYSIS_POINT_COUNT + DISCARD_POINT_COUNT)
  287. return;
  288. }
  289. s_SampleCnt = Touch_Start_Analyse(s_PointPool, ANALYSIS_POINT_COUNT);
  290. if(s_SampleCnt == 0)
  291. {
  292. for(i=0; i<DISCARD_POINT_COUNT; i++)
  293. s_PointPool[i] = s_PointPool[ANALYSIS_POINT_COUNT+i];
  294. s_SampleCnt = DISCARD_POINT_COUNT;
  295. return;
  296. }
  297. //send press event
  298. indata.point.x = s_PointPool[0].x;
  299. indata.point.y = s_PointPool[0].y;
  300. indata.state = LV_INDEV_STATE_PR;
  301. SendTouchInputEventFromISR(&indata);
  302. lg_ulTouchMachineState = TOUCH_STATE_SAMPLE;
  303. //将为满足最后丢弃任务而暂存的点复制到分析后剩余点之后
  304. for(i=0; i<DISCARD_POINT_COUNT; i++)
  305. s_PointPool[s_SampleCnt + i] = s_PointPool[ANALYSIS_POINT_COUNT+i];
  306. s_PoolIndex = 1;
  307. //计算此时剩余的未操作的有效点数
  308. s_SampleCnt = s_SampleCnt - 1 + DISCARD_POINT_COUNT;
  309. //send move event in the pool
  310. while(s_SampleCnt > DISCARD_POINT_COUNT)
  311. {
  312. int xdiff, ydiff;
  313. unsigned int totaldiff;
  314. xdiff = s_PointPool[s_PoolIndex].x - lg_stLastMovePoint.x;
  315. ydiff = s_PointPool[s_PoolIndex].y - lg_stLastMovePoint.y;
  316. totaldiff = xdiff * xdiff + ydiff * ydiff;
  317. if(totaldiff > 4)
  318. {
  319. indata.point.x = s_PointPool[s_PoolIndex].x;
  320. indata.point.y = s_PointPool[s_PoolIndex].y;
  321. indata.state = LV_INDEV_STATE_PR;
  322. SendTouchInputEventFromISR(&indata);
  323. lg_stLastMovePoint.x = s_PointPool[s_PoolIndex].x;
  324. lg_stLastMovePoint.y = s_PointPool[s_PoolIndex].y;
  325. }
  326. s_PoolIndex++;
  327. s_SampleCnt--;
  328. }
  329. }
  330. break;
  331. case TOUCH_STATE_SAMPLE:
  332. if(ulEvent == TOUCH_SAMPLE_EVENT)
  333. {
  334. //caculate move center cordinate
  335. //if move, then send move event
  336. PAN_DATA stPanData;
  337. POINT pt;
  338. int xDiff = 0, yDiff = 0;
  339. unsigned int totalDiff = 0;
  340. //get cordinate
  341. stPanData.adcX = lpParam;
  342. stPanData.adcY = wParam;
  343. CalcCoord(&stPanData, &pt);
  344. if(pt.x < 0 || pt.y < 0)
  345. return;
  346. if(pt.x < 0 || pt.x >= LCD_WIDTH || pt.y < 0 || pt.y >= LCD_HEIGHT)
  347. return;
  348. if(s_SampleCnt < DISCARD_POINT_COUNT)
  349. {
  350. int index = (s_PoolIndex+s_SampleCnt++) % POINT_POOL_SIZE;
  351. s_PointPool[index] = pt;
  352. return;
  353. }
  354. xDiff = s_PointPool[s_PoolIndex].x - lg_stLastMovePoint.x;
  355. yDiff = s_PointPool[s_PoolIndex].y - lg_stLastMovePoint.y;
  356. totalDiff = xDiff * xDiff + yDiff * yDiff;
  357. if(totalDiff > 4)
  358. {
  359. lv_indev_data_t indata = {0};
  360. indata.point.x = s_PointPool[s_PoolIndex].x;
  361. indata.point.y = s_PointPool[s_PoolIndex].y;
  362. indata.state = LV_INDEV_STATE_PR;
  363. SendTouchInputEventFromISR(&indata);
  364. lg_stLastMovePoint.x = s_PointPool[s_PoolIndex].x;
  365. lg_stLastMovePoint.y = s_PointPool[s_PoolIndex].y;
  366. }
  367. s_PointPool[(s_PoolIndex+DISCARD_POINT_COUNT)%POINT_POOL_SIZE] = pt;
  368. s_PoolIndex = (s_PoolIndex+1)%POINT_POOL_SIZE;
  369. }
  370. else if(ulEvent == TOUCH_STOP_EVENT)
  371. {
  372. lv_indev_data_t indata = {0};
  373. //send release event
  374. indata.point.x = lg_stLastMovePoint.x;
  375. indata.point.y = lg_stLastMovePoint.y;
  376. indata.state = LV_INDEV_STATE_REL;
  377. SendTouchInputEventFromISR(&indata);
  378. lg_ulTouchMachineState = TOUCH_STATE_IDLE;
  379. }
  380. break;
  381. case TOUCH_STATE_STOP:
  382. break;
  383. }
  384. }
  385. static volatile UINT32 lg_bTouchStart = 0;
  386. static UINT32 CheckTouchStart()
  387. {
  388. return lg_bTouchStart == 1;
  389. }
  390. static UINT32 CheckTouchStop()
  391. {
  392. return lg_bTouchStart == 0;
  393. }
  394. static UINT32 GetTouchSampleCounter()
  395. {
  396. return Queue_ADCValue_Length(&panADCXQueue);
  397. }
  398. static UINT32 lg_bTouchAdjusted = 0;
  399. void TouchEventHandler(UINT32 ulEvent, UINT32 lpParam, UINT32 wParam)
  400. {
  401. if(lg_bTouchAdjusted)
  402. {
  403. Handler_Touch_IntEvent(ulEvent, lpParam, wParam);
  404. }
  405. else
  406. {
  407. if(ulEvent == TOUCH_START_EVENT)
  408. {
  409. lg_bTouchStart = 1;
  410. Queue_ADCValue_Init(&panADCXQueue, PANADC_X, MAXPANADCLEN);
  411. Queue_ADCValue_Init(&panADCYQueue, PANADC_Y, MAXPANADCLEN);
  412. }
  413. else if(ulEvent == TOUCH_SAMPLE_EVENT)
  414. {
  415. Queue_ADCValue_Add(&panADCXQueue,lpParam);
  416. Queue_ADCValue_Add(&panADCYQueue,wParam);
  417. }
  418. else if(ulEvent == TOUCH_STOP_EVENT)
  419. {
  420. lg_bTouchStart = 0;
  421. }
  422. }
  423. }
  424. /***************************************************************************************
  425. 触摸屏坐标校验代码
  426. ***************************************************************************************/
  427. #define GRID_RANGE 12
  428. #define HIT_RANGE 2
  429. #define ABS_HIT ((GRID_RANGE+HIT_RANGE)*2)
  430. #define TOUCH_HIGH_EXACTION 0
  431. #define TOUCH_MID_EXACTION 0
  432. #define TOUCH_LOW_EXACTION 1
  433. #define TOUCH_REVISE_DEBUG 1
  434. #if TOUCH_REVISE_DEBUG
  435. #define TOUCH_DEBUG_MSG(fmt, args...) printf(fmt, ##args)
  436. #else
  437. #define TOUCH_DEBUG_MSG(fmt, args...)
  438. #endif
  439. #define SYSTEM_ERROR 100.0
  440. #define SCALE_AERROR 2// 3 这里考虑触摸屏的差异修改20130618
  441. #define SCALE_DERROR 5
  442. static double abs_ax,abs_dx,abs_ly,abs_ry;
  443. static double abs_lx,abs_rx;
  444. static double abs_err1,abs_err2,abs_err3,abs_err4,abs_err5;
  445. static double abs_cx,abs_cy;
  446. static int lg_direction = 0;
  447. #if TOUCH_HIGH_EXACTION
  448. #define SYSTEM_ERROR1 100.0
  449. #elif TOUCH_MID_EXACTION
  450. #define SYSTEM_ERROR1 150.0
  451. #elif TOUCH_LOW_EXACTION
  452. #define SYSTEM_ERROR1 200.0
  453. #else
  454. #define SYSTEM_ERROR1 150.0
  455. #endif
  456. /* static void InitializeCalibration(int a0, int a1, int a2, int a3, int a4, int a5, int a6)
  457. {
  458. cal.a[0] = a0;
  459. cal.a[1] = a1;
  460. cal.a[2] = a2;
  461. cal.a[3] = a3;
  462. cal.a[4] = a4;
  463. cal.a[5] = a5;
  464. cal.a[6] = a6;
  465. } */
  466. static void SaveCalibration(calibration *pCalibration)
  467. {
  468. }
  469. static int perform_calibration(calibration *cal) {
  470. int j;
  471. float n, x, y, x2, y2, xy, z, zx, zy;
  472. float det, a, b, c, e, f, i;
  473. float scaling = 65536.0;
  474. // Get sums for matrix
  475. n = x = y = x2 = y2 = xy = 0;
  476. for(j=0;j<5;j++) {
  477. n += 1.0;
  478. x += (float)cal->x[j];
  479. y += (float)cal->y[j];
  480. x2 += (float)(cal->x[j]*cal->x[j]);
  481. y2 += (float)(cal->y[j]*cal->y[j]);
  482. xy += (float)(cal->x[j]*cal->y[j]);
  483. }
  484. // Get determinant of matrix -- check if determinant is too small
  485. det = n*(x2*y2 - xy*xy) + x*(xy*y - x*y2) + y*(x*xy - y*x2);
  486. if(det < 0.1 && det > -0.1) {
  487. printf("ts_calibrate: determinant is too small -- %f\n",det);
  488. return 0;
  489. }
  490. // Get elements of inverse matrix
  491. a = (x2*y2 - xy*xy)/det;
  492. b = (xy*y - x*y2)/det;
  493. c = (x*xy - y*x2)/det;
  494. e = (n*y2 - y*y)/det;
  495. f = (x*y - n*xy)/det;
  496. i = (n*x2 - x*x)/det;
  497. // Get sums for x calibration
  498. z = zx = zy = 0;
  499. for(j=0;j<5;j++) {
  500. z += (float)cal->xfb[j];
  501. zx += (float)(cal->xfb[j]*cal->x[j]);
  502. zy += (float)(cal->xfb[j]*cal->y[j]);
  503. }
  504. // Now multiply out to get the calibration for framebuffer x coord
  505. cal->a[0] = (int)((a*z + b*zx + c*zy)*(scaling));
  506. cal->a[1] = (int)((b*z + e*zx + f*zy)*(scaling));
  507. cal->a[2] = (int)((c*z + f*zx + i*zy)*(scaling));
  508. // Get sums for y calibration
  509. z = zx = zy = 0;
  510. for(j=0;j<5;j++) {
  511. z += (float)cal->yfb[j];
  512. zx += (float)(cal->yfb[j]*cal->x[j]);
  513. zy += (float)(cal->yfb[j]*cal->y[j]);
  514. }
  515. // Now multiply out to get the calibration for framebuffer y coord
  516. cal->a[3] = (int)((a*z + b*zx + c*zy)*(scaling));
  517. cal->a[4] = (int)((b*z + e*zx + f*zy)*(scaling));
  518. cal->a[5] = (int)((c*z + f*zx + i*zy)*(scaling));
  519. // If we got here, we're OK, so assign scaling to a[6] and return
  520. cal->a[6] = (int)scaling;
  521. return 1;
  522. }
  523. void CleanTouchAdjustParameter(void)
  524. {
  525. Queue_ADCValue_Init(&panADCXQueue, PANADC_X, MAXPANADCLEN);
  526. Queue_ADCValue_Init(&panADCYQueue, PANADC_Y, MAXPANADCLEN);
  527. lg_bTouchAdjusted = 0;
  528. }
  529. void TouchInit(void)
  530. {
  531. CleanTouchAdjustParameter();
  532. }
  533. static void CalcCoord(PAN_DATA *pPan, POINT *pPT)
  534. {
  535. pPT->x = (pPan->adcX * cal.a[1] + pPan->adcY * cal.a[2] + cal.a[0])/cal.a[6];
  536. pPT->y = (pPan->adcX * cal.a[4] + pPan->adcY * cal.a[5] + cal.a[3])/cal.a[6];
  537. }
  538. static unsigned int GetTouchHit(PAN_DATA *pPan)
  539. {
  540. unsigned int PanReq;
  541. PAN_DATA Pan[50];
  542. unsigned int i, Count;
  543. for(i = 0; i < 50; i++)
  544. {
  545. Pan[i].adcX = 0xFFFF;
  546. Pan[i].adcY = 0xFFFF;
  547. }
  548. ReStartCheck:
  549. while(!CheckTouchStart());
  550. while(!CheckTouchStop());
  551. if(GetTouchSampleCounter() < 16)
  552. goto ReStartCheck;
  553. gicd_Interrupt_disable(ADC_IRQn);
  554. while(1)
  555. {
  556. PanReq = GetADCTouch(&Pan[49]);
  557. if(PanReq==0)
  558. {
  559. break;
  560. }
  561. for(i = 0; i < 49; i++)
  562. {
  563. Pan[i].adcX = Pan[i+1].adcX;
  564. Pan[i].adcY = Pan[i+1].adcY;
  565. }
  566. }
  567. gicd_Interrupt_enable(ADC_IRQn);
  568. Count = 0;
  569. for(i = 0; i < 49; i++)
  570. {
  571. if(Pan[i].adcY < 0xFFF)
  572. {
  573. Count++;
  574. }
  575. }
  576. pPan->adcX = Pan[49-Count/2].adcX;
  577. pPan->adcY = Pan[49-Count/2].adcY;
  578. TOUCH_DEBUG_MSG("Hit Count = %d\n", Count);
  579. TOUCH_DEBUG_MSG("pPan->adcX=%d\n",pPan->adcX);
  580. TOUCH_DEBUG_MSG("pPan->adcY=%d\n",pPan->adcY);
  581. return TRUE;
  582. }
  583. static void ClearBitmap(lv_color_t color, const lv_area_t * area, lv_color_t * color_p)
  584. {
  585. /*Truncate the area to the screen*/
  586. int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
  587. int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
  588. int32_t act_x2 = area->x2 > LCD_WIDTH - 1 ? LCD_WIDTH - 1 : area->x2;
  589. int32_t act_y2 = area->y2 > LCD_HEIGHT - 1 ? LCD_HEIGHT - 1 : area->y2;
  590. /*32 or 24 bit per pixel*/
  591. if(LCD_BPP == 32) {
  592. uint32_t * fbp32 = (uint32_t *)color_p;
  593. int32_t x, y;
  594. for(y = act_y1; y <= act_y2; y++) {
  595. fbp32 = (uint32_t *)color_p + y * LCD_WIDTH;
  596. for (x = act_x1; x <= act_x2; x++)
  597. fbp32[x] = color.full;
  598. }
  599. }
  600. /*16 bit per pixel*/
  601. else if(LCD_BPP == 16) {
  602. uint16_t * fbp16 = (uint16_t *)color_p;
  603. int32_t x, y;
  604. for(y = act_y1; y <= act_y2; y++) {
  605. fbp16 = (uint16_t *)color_p + y * LCD_WIDTH;
  606. for (x = act_x1; x <= act_x2; x++)
  607. fbp16[x] = color.full;
  608. }
  609. }
  610. }
  611. static void PutHitCursor(int x, int y)
  612. {
  613. lv_area_t area;
  614. area.x1 = x - GRID_RANGE;
  615. area.y1 = y;
  616. area.x2 = x + GRID_RANGE + HIT_RANGE - 1;
  617. area.y2 = y + HIT_RANGE - 1;
  618. ClearBitmap(LV_COLOR_WHITE, &area, (lv_color_t*)ark_lcd_get_virt_addr());
  619. area.x1 = x;
  620. area.y1 = y - GRID_RANGE;
  621. area.x2 = x + HIT_RANGE - 1;
  622. area.y2 = y + GRID_RANGE + HIT_RANGE - 1;
  623. ClearBitmap(LV_COLOR_WHITE, &area, (lv_color_t*)ark_lcd_get_virt_addr());
  624. area.x1 = x;
  625. area.y1 = y;
  626. area.x2 = x + HIT_RANGE - 1;
  627. area.y2 = y + HIT_RANGE - 1;
  628. ClearBitmap(LV_COLOR_BLACK, &area, (lv_color_t*)ark_lcd_get_virt_addr());
  629. CP15_clean_dcache_for_dma((uint32_t)(lv_color_t*)ark_lcd_get_virt_addr(),
  630. (uint32_t)(lv_color_t*)ark_lcd_get_virt_addr() + FB_SIZE);
  631. }
  632. static void ClrHitCursor(int x, int y)
  633. {
  634. lv_area_t area;
  635. area.x1 = x - GRID_RANGE;
  636. area.y1 = y - GRID_RANGE;
  637. area.x2 = x + GRID_RANGE + HIT_RANGE - 1;
  638. area.y2 = y + GRID_RANGE + HIT_RANGE - 1;
  639. ClearBitmap(LV_COLOR_BLACK, &area, (lv_color_t*)ark_lcd_get_virt_addr());
  640. CP15_clean_dcache_for_dma((uint32_t)(lv_color_t*)ark_lcd_get_virt_addr(),
  641. (uint32_t)(lv_color_t*)ark_lcd_get_virt_addr() + FB_SIZE);
  642. }
  643. static int compare_data(calibration *cal)
  644. {
  645. int ret=0;
  646. int diff_x;
  647. int diff_y;
  648. diff_x = (int)fabs(cal->x[0] - cal->x[1]);
  649. diff_y = (int)fabs(cal->y[0] - cal->y[1]);
  650. if(diff_x > diff_y)
  651. lg_direction = 0;
  652. else
  653. lg_direction = 1;
  654. TOUCH_DEBUG_MSG("lg_direction = %d\r\n", lg_direction);
  655. if(lg_direction == 0)
  656. {
  657. if((cal->x [0]<cal->x [1])&&(cal->x [3]<cal->x [2]))
  658. ret=1;
  659. if((cal->x [0]>cal->x [1])&&(cal->x [3]>cal->x [2]))
  660. ret=1;
  661. }
  662. else
  663. {
  664. if((cal->y[0]<cal->y[1])&&(cal->y[3]<cal->y[2]))
  665. ret=1;
  666. if((cal->y[0]>cal->y[1])&&(cal->y[3]>cal->y[2]))
  667. ret=1;
  668. }
  669. return ret;
  670. }
  671. static int square_judge(calibration *cal)
  672. {
  673. int ret=0;
  674. if(lg_direction == 0)
  675. {
  676. abs_ax=fabs(cal->x [0] - cal->x [1]);
  677. abs_dx=fabs(cal->x [2]-cal->x [3]);
  678. abs_err1=fabs(abs_ax -abs_dx);
  679. 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);
  680. abs_lx=fabs(cal->x [0]-cal->x [4]);
  681. abs_rx=fabs(cal->x[3]-cal->x [4]);
  682. abs_err2=fabs(abs_lx -abs_rx);
  683. TOUCH_DEBUG_MSG("***abs_lx=%d,abs_rx=%d,abs_err2=%d****2\n", (int)abs_lx, (int)abs_rx, (int)abs_err2);
  684. abs_ly=fabs(cal->y [0]-cal->y [3]);
  685. abs_ry=fabs(cal->y [1]-cal->y [2]);
  686. abs_err3=fabs(abs_ly -abs_ry);
  687. TOUCH_DEBUG_MSG("***abs_ly=%d, abs_ry=%d, abs_err3=%d****2\n", (int)abs_ly, (int)abs_ry, (int)abs_err3);
  688. if(abs_err1<SYSTEM_ERROR1&&abs_err2<SYSTEM_ERROR1&&abs_err3<SYSTEM_ERROR1)
  689. ret=1;
  690. }
  691. else
  692. {
  693. abs_ax=fabs(cal->y[0] - cal->y[1]);
  694. abs_dx=fabs(cal->y[2]-cal->y[3]);
  695. abs_err1=fabs(abs_ax -abs_dx);
  696. 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);
  697. abs_lx=fabs(cal->y[0]-cal->y[4]);
  698. abs_rx=fabs(cal->y[3]-cal->y[4]);
  699. abs_err2=fabs(abs_lx -abs_rx);
  700. TOUCH_DEBUG_MSG("***abs_lx=%d, abs_rx=%d, abs_err2=%d****2\n", (int)abs_lx, (int)abs_rx, (int)abs_err2);
  701. abs_ly=fabs(cal->x[0]-cal->x[3]);
  702. abs_ry=fabs(cal->x[1]-cal->x[2]);
  703. abs_err3=fabs(abs_ly -abs_ry);
  704. TOUCH_DEBUG_MSG("***abs_ly=%d, abs_ry=%d, abs_err3=%d****2\n", (int)abs_ly, (int)abs_ry, (int)abs_err3);
  705. if(abs_err1<SYSTEM_ERROR1&&abs_err2<SYSTEM_ERROR1&&abs_err3<SYSTEM_ERROR1)
  706. ret=1;
  707. }
  708. TOUCH_DEBUG_MSG("***ret=%d****4\n",ret);
  709. return ret;
  710. }
  711. static int judge_center(calibration *cal)
  712. {
  713. int ret=0;
  714. if(lg_direction == 0)
  715. {
  716. abs_cx=fabs(cal->x [4]-cal->x [0])*2;
  717. abs_cy=fabs(cal->y [4]-cal->y [0])*2;
  718. abs_err4=fabs(abs_cx -abs_ax);
  719. abs_err5=fabs(abs_cy -abs_ly);
  720. 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);
  721. if(abs_err4<SYSTEM_ERROR1&&abs_err5<SYSTEM_ERROR1)
  722. ret=1;
  723. }
  724. else
  725. {
  726. abs_cx=fabs(cal->y[4]-cal->y[0])*2;
  727. abs_cy=fabs(cal->x[4]-cal->x[0])*2;
  728. abs_err4=fabs(abs_cx -abs_ax);
  729. abs_err5=fabs(abs_cy -abs_ly);
  730. 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);
  731. if(abs_err4<SYSTEM_ERROR1&&abs_err5<SYSTEM_ERROR1)
  732. ret=1;
  733. }
  734. return ret;
  735. }
  736. static int filter_data(calibration *cal)
  737. {
  738. int ret=0;
  739. float abs_lcd;
  740. int scale;
  741. int i;
  742. TOUCH_DEBUG_MSG("***filter_data****1\n");
  743. for(i=0;i<5;i++)
  744. {
  745. TOUCH_DEBUG_MSG("cal->x[%d] = %d, cal->y[%d] = %d\r\n", i, (int)cal->x[i], i, (int)cal->y[i]);
  746. }
  747. if(compare_data( cal))
  748. {
  749. TOUCH_DEBUG_MSG("*** Pass compare_data ****\n");
  750. if(square_judge(cal))
  751. {
  752. TOUCH_DEBUG_MSG("*** Pass square_judge ****\n");
  753. abs_lcd=fabs(cal->xfb[1] -cal->xfb[0]);
  754. TOUCH_DEBUG_MSG("***abs_ax=%d, abs_lcd=%d****\n", (int)abs_ax, (int)abs_lcd);
  755. scale=(int)(abs_ax/abs_lcd);
  756. TOUCH_DEBUG_MSG("***scale=%d****4\n",scale);
  757. if(SCALE_AERROR<scale&&SCALE_DERROR>scale)
  758. {
  759. TOUCH_DEBUG_MSG("*** Scale check ok ****\n");
  760. if(judge_center(cal))
  761. {
  762. ret=1;
  763. }
  764. else
  765. {
  766. TOUCH_DEBUG_MSG("*** Failed at judge_center****\n");
  767. }
  768. }
  769. }
  770. }
  771. TOUCH_DEBUG_MSG("*** filter_data ret=%d****\n",ret);
  772. return ret;
  773. }
  774. static void get_sample (calibration *cal,
  775. int index, int x, int y, char *name)
  776. {
  777. PAN_DATA ts_cord;
  778. PutHitCursor(x, y);
  779. // getxy (ts, &cal->x [index], &cal->y [index]);
  780. GetTouchHit(&ts_cord);
  781. cal->x [index] = ts_cord.adcX;
  782. cal->y [index] = ts_cord.adcY;
  783. ClrHitCursor(x, y);
  784. cal->xfb [index] = x;
  785. cal->yfb [index] = y;
  786. TOUCH_DEBUG_MSG("get_sample %s : X = %4d Y = %4d\n", name, cal->x [index], cal->y [index]);
  787. }
  788. unsigned int AdjustTouch(void)
  789. {
  790. unsigned int i;
  791. #if 0
  792. cal.a[0]=56822272;
  793. cal.a[1]=-14948;
  794. cal.a[2]=36;
  795. cal.a[3]=38820672;
  796. cal.a[4]=-59;
  797. cal.a[5]=-11704;
  798. cal.a[6]=65536;
  799. lg_bTouchAdjusted = 1;
  800. #else
  801. while(1)
  802. {
  803. get_sample (&cal, 0, 50, 50, "Top left");
  804. get_sample (&cal, 1, LCD_WIDTH - 50, 50, "Top right");
  805. get_sample (&cal, 2, LCD_WIDTH - 50, LCD_HEIGHT - 50, "Bot right");
  806. get_sample (&cal, 3, 50, LCD_HEIGHT - 50, "Bot left");
  807. get_sample (&cal, 4, LCD_WIDTH / 2, LCD_HEIGHT / 2, "Center");
  808. if(filter_data(&cal))
  809. {
  810. perform_calibration (&cal);
  811. for(i=0;i<7;i++)
  812. {
  813. printf("the result cal->a[%d]=%d\n", i, cal.a[i]);
  814. }
  815. SaveCalibration(&cal);
  816. break;
  817. }
  818. }
  819. #endif
  820. lg_bTouchAdjusted = 1;
  821. return 0; // 5次均无效, 取默认值
  822. }
  823. int LoadTouchConfigure(void)
  824. {
  825. return -1;
  826. }
  827. #endif