drv_adc_touch.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. /**************************************************************************//**
  2. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-04-20 Wayne First version
  9. *
  10. ******************************************************************************/
  11. #include <rtconfig.h>
  12. #if defined(BSP_USING_ADC_TOUCH)
  13. #include "NuMicro.h"
  14. #include <rtdevice.h>
  15. #include <dfs_posix.h>
  16. #include "drv_adc.h"
  17. #include "touch.h"
  18. #if !defined(PATH_CALIBRATION_FILE)
  19. #define PATH_CALIBRATION_FILE "/mnt/filesystem/ts_calibration"
  20. #endif
  21. typedef struct
  22. {
  23. struct rt_touch_device dev;
  24. rt_uint32_t x_range;
  25. rt_uint32_t y_range;
  26. } nu_adc_touch;
  27. typedef nu_adc_touch *nu_adc_touch_t;
  28. static nu_adc_touch s_NuAdcTouch = {0};
  29. #if (BSP_LCD_WIDTH==320) && (BSP_LCD_HEIGHT==240)
  30. static S_CALIBRATION_MATRIX g_sCalMat = { 43, -5839, 21672848, 4193, -11, -747882, 65536 };
  31. static volatile uint32_t g_u32Calibrated = 1;
  32. #else
  33. static S_CALIBRATION_MATRIX g_sCalMat = { 1, 0, 0, 0, 1, 0, 1 };
  34. static volatile uint32_t g_u32Calibrated = 0;
  35. #endif
  36. static int nu_adc_touch_readfile(void);
  37. static const S_CALIBRATION_MATRIX g_sCalZero = { 1, 0, 0, 0, 1, 0, 1 };
  38. static int nu_adc_cal_mat_get(const S_COORDINATE_POINT *psDispCP, S_COORDINATE_POINT *psADCCP, S_CALIBRATION_MATRIX *psCM)
  39. {
  40. #if (DEF_CAL_POINT_NUM==3)
  41. psCM->div = ((psADCCP[0].x - psADCCP[2].x) * (psADCCP[1].y - psADCCP[2].y)) -
  42. ((psADCCP[1].x - psADCCP[2].x) * (psADCCP[0].y - psADCCP[2].y)) ;
  43. if (psCM->div == 0)
  44. {
  45. return -1;
  46. }
  47. else
  48. {
  49. psCM->a = ((psDispCP[0].x - psDispCP[2].x) * (psADCCP[1].y - psADCCP[2].y)) -
  50. ((psDispCP[1].x - psDispCP[2].x) * (psADCCP[0].y - psADCCP[2].y)) ;
  51. psCM->b = ((psADCCP[0].x - psADCCP[2].x) * (psDispCP[1].x - psDispCP[2].x)) -
  52. ((psDispCP[0].x - psDispCP[2].x) * (psADCCP[1].x - psADCCP[2].x)) ;
  53. psCM->c = (psADCCP[2].x * psDispCP[1].x - psADCCP[1].x * psDispCP[2].x) * psADCCP[0].y +
  54. (psADCCP[0].x * psDispCP[2].x - psADCCP[2].x * psDispCP[0].x) * psADCCP[1].y +
  55. (psADCCP[1].x * psDispCP[0].x - psADCCP[0].x * psDispCP[1].x) * psADCCP[2].y ;
  56. psCM->d = ((psDispCP[0].y - psDispCP[2].y) * (psADCCP[1].y - psADCCP[2].y)) -
  57. ((psDispCP[1].y - psDispCP[2].y) * (psADCCP[0].y - psADCCP[2].y)) ;
  58. psCM->e = ((psADCCP[0].x - psADCCP[2].x) * (psDispCP[1].y - psDispCP[2].y)) -
  59. ((psDispCP[0].y - psDispCP[2].y) * (psADCCP[1].x - psADCCP[2].x)) ;
  60. psCM->f = (psADCCP[2].x * psDispCP[1].y - psADCCP[1].x * psDispCP[2].y) * psADCCP[0].y +
  61. (psADCCP[0].x * psDispCP[2].y - psADCCP[2].x * psDispCP[0].y) * psADCCP[1].y +
  62. (psADCCP[1].x * psDispCP[0].y - psADCCP[0].x * psDispCP[1].y) * psADCCP[2].y ;
  63. }
  64. #elif (DEF_CAL_POINT_NUM==5)
  65. int i;
  66. float n, x, y, xx, yy, xy, z, zx, zy;
  67. float a, b, c, d, e, f, g;
  68. float scaling = 65536.0f;
  69. n = x = y = xx = yy = xy = 0;
  70. for (i = 0; i < DEF_CAL_POINT_NUM; i++)
  71. {
  72. n += 1.0;
  73. x += (float)psADCCP[i].x;
  74. y += (float)psADCCP[i].y;
  75. xx += (float)psADCCP[i].x * psADCCP[i].x;
  76. yy += (float)psADCCP[i].y * psADCCP[i].y;
  77. xy += (float)psADCCP[i].x * psADCCP[i].y;
  78. }
  79. d = n * (xx * yy - xy * xy) + x * (xy * y - x * yy) + y * (x * xy - y * xx);
  80. if (d < 0.1 && d > -0.1)
  81. {
  82. return -1;
  83. }
  84. a = (xx * yy - xy * xy) / d;
  85. b = (xy * y - x * yy) / d;
  86. c = (x * xy - y * xx) / d;
  87. e = (n * yy - y * y) / d;
  88. f = (x * y - n * xy) / d;
  89. g = (n * xx - x * x) / d;
  90. z = zx = zy = 0;
  91. for (i = 0; i < DEF_CAL_POINT_NUM; i++)
  92. {
  93. z += (float)psDispCP[i].x;
  94. zx += (float)psDispCP[i].x * psADCCP[i].x;
  95. zy += (float)psDispCP[i].x * psADCCP[i].y;
  96. }
  97. psCM->c = (int32_t)((a * z + b * zx + c * zy) * scaling);
  98. psCM->a = (int32_t)((b * z + e * zx + f * zy) * scaling);
  99. psCM->b = (int32_t)((c * z + f * zx + g * zy) * scaling);
  100. z = zx = zy = 0;
  101. for (i = 0; i < DEF_CAL_POINT_NUM; i++)
  102. {
  103. z += (float)psDispCP[i].y;
  104. zx += (float)psDispCP[i].y * psADCCP[i].x;
  105. zy += (float)psDispCP[i].y * psADCCP[i].y;
  106. }
  107. psCM->f = (int32_t)((a * z + b * zx + c * zy) * scaling);
  108. psCM->d = (int32_t)((b * z + e * zx + f * zy) * scaling);
  109. psCM->e = (int32_t)((c * z + f * zx + g * zy) * scaling);
  110. psCM->div = (int32_t)scaling;
  111. #else
  112. #error "Not supported calibration method"
  113. #endif
  114. return 0;
  115. }
  116. static void nu_adc_touch_cal(int32_t *sumx, int32_t *sumy)
  117. {
  118. int32_t xtemp, ytemp;
  119. xtemp = *sumx;
  120. ytemp = *sumy;
  121. *sumx = (g_sCalMat.c +
  122. g_sCalMat.a * xtemp +
  123. g_sCalMat.b * ytemp) / g_sCalMat.div;
  124. *sumy = (g_sCalMat.f +
  125. g_sCalMat.d * xtemp +
  126. g_sCalMat.e * ytemp) / g_sCalMat.div;
  127. }
  128. static rt_size_t nu_adc_touch_readpoint(struct rt_touch_device *device, void *buf, rt_size_t read_num)
  129. {
  130. static uint32_t last_report_x = 0, last_report_y = 0;
  131. struct rt_touch_data *pPoint = (struct rt_touch_data *)buf;
  132. nu_adc_touch_t psNuAdcTouch = (nu_adc_touch_t)device;
  133. RT_ASSERT(device != RT_NULL);
  134. RT_ASSERT(buf != RT_NULL);
  135. int i;
  136. for (i = 0; i < read_num; i++)
  137. {
  138. uint32_t bufZ0 = 0, bufZ1 = 0;
  139. int32_t sumx = 0, sumy = 0;
  140. pPoint[i].timestamp = rt_touch_get_ts();
  141. pPoint[i].track_id = 0;
  142. if (nu_adc_touch_read_xyz((uint32_t *)&sumx, (uint32_t *)&sumy, &bufZ0, &bufZ1, 1) != 1)
  143. break;
  144. if (bufZ0 == 0)
  145. {
  146. /* Workaround: In this case, x, y values are unstable. so, report last point's coordinate.*/
  147. pPoint[i].event = RT_TOUCH_EVENT_UP;
  148. pPoint[i].x_coordinate = (uint16_t)last_report_x;
  149. pPoint[i].y_coordinate = (uint16_t)last_report_y;
  150. }
  151. else
  152. {
  153. if (g_u32Calibrated)
  154. {
  155. nu_adc_touch_cal(&sumx, &sumy);
  156. }
  157. last_report_x = sumx;
  158. last_report_y = sumy;
  159. pPoint[i].event = RT_TOUCH_EVENT_DOWN;
  160. pPoint[i].x_coordinate = (uint16_t)sumx;
  161. pPoint[i].y_coordinate = (uint16_t)sumy;
  162. }
  163. if (g_u32Calibrated)
  164. {
  165. bufZ0 = bufZ0 >> 3;
  166. pPoint[i].width = (bufZ0 > 255) ? 255 : bufZ0;
  167. //Limit max x, y coordinate if value is over its range.
  168. pPoint[i].x_coordinate = (pPoint[i].x_coordinate > psNuAdcTouch->x_range) ? psNuAdcTouch->x_range : pPoint[i].x_coordinate;
  169. pPoint[i].y_coordinate = (pPoint[i].y_coordinate > psNuAdcTouch->y_range) ? psNuAdcTouch->y_range : pPoint[i].y_coordinate;
  170. }
  171. }
  172. return (rt_size_t)i;
  173. }
  174. static rt_err_t nu_adc_touch_control(struct rt_touch_device *device, int cmd, void *data)
  175. {
  176. nu_adc_touch_t psNuAdcTouch = (nu_adc_touch_t)device;
  177. RT_ASSERT(psNuAdcTouch != RT_NULL);
  178. switch (cmd)
  179. {
  180. case RT_TOUCH_CTRL_SET_X_RANGE: /* set x range */
  181. psNuAdcTouch->x_range = *((rt_int32_t *)data);
  182. break;
  183. case RT_TOUCH_CTRL_SET_Y_RANGE: /* set y range */
  184. psNuAdcTouch->y_range = *((rt_int32_t *)data);
  185. break;
  186. case RT_TOUCH_CTRL_ENABLE_INT: /* enable pen_down interrupt */
  187. nu_adc_touch_detect(RT_TRUE);
  188. break;
  189. case RT_TOUCH_CTRL_DISABLE_INT: /* disable pen_down interrupt */
  190. nu_adc_touch_detect(RT_FALSE);
  191. break;
  192. case RT_TOUCH_CTRL_POWER_ON: /* Touch Power On */
  193. return nu_adc_touch_enable(device);
  194. case RT_TOUCH_CTRL_POWER_OFF: /* Touch Power Off */
  195. return nu_adc_touch_disable();
  196. default:
  197. return -RT_ERROR;
  198. }
  199. return RT_EOK;
  200. }
  201. static struct rt_touch_ops touch_ops =
  202. {
  203. .touch_readpoint = nu_adc_touch_readpoint,
  204. .touch_control = nu_adc_touch_control,
  205. };
  206. static void nu_adc_touch_update_calmat(S_CALIBRATION_MATRIX *psNewCalMat)
  207. {
  208. if (psNewCalMat &&
  209. psNewCalMat->div != 0)
  210. {
  211. rt_memcpy(&g_sCalMat, psNewCalMat, sizeof(S_CALIBRATION_MATRIX));
  212. g_u32Calibrated = 1;
  213. rt_kprintf("Applied calibration data: %d, %d, %d, %d, %d, %d, %d\n",
  214. g_sCalMat.a,
  215. g_sCalMat.b,
  216. g_sCalMat.c,
  217. g_sCalMat.d,
  218. g_sCalMat.e,
  219. g_sCalMat.f,
  220. g_sCalMat.div);
  221. }
  222. }
  223. static void nu_adc_touch_reset_calmat(void)
  224. {
  225. rt_memcpy(&g_sCalMat, &g_sCalZero, sizeof(S_CALIBRATION_MATRIX));
  226. g_u32Calibrated = 0;
  227. }
  228. int rt_hw_adc_touch_init(void)
  229. {
  230. /* Register touch device */
  231. s_NuAdcTouch.dev.info.type = RT_TOUCH_TYPE_RESISTANCE;
  232. s_NuAdcTouch.dev.info.vendor = RT_TOUCH_VENDOR_UNKNOWN;
  233. s_NuAdcTouch.dev.info.point_num = 1;
  234. s_NuAdcTouch.dev.info.range_x = BSP_LCD_WIDTH;
  235. s_NuAdcTouch.dev.info.range_y = BSP_LCD_HEIGHT;
  236. s_NuAdcTouch.dev.ops = &touch_ops;
  237. return (int)rt_hw_touch_register(&s_NuAdcTouch.dev, "adc_touch", RT_DEVICE_FLAG_INT_RX, RT_NULL);
  238. }
  239. INIT_DEVICE_EXPORT(rt_hw_adc_touch_init);
  240. static rt_thread_t adc_touch_thread = RT_NULL;
  241. static rt_sem_t adc_touch_sem = RT_NULL;
  242. static int adc_touch_worker_run = 0;
  243. static rt_err_t adc_touch_rx_callback(rt_device_t dev, rt_size_t size)
  244. {
  245. //rt_kprintf("[%s %d] %d\n", __func__, __LINE__, size);
  246. return rt_sem_release(adc_touch_sem);
  247. }
  248. static rt_err_t adc_request_point(rt_device_t pdev, struct rt_touch_data *psTouchPoint)
  249. {
  250. rt_err_t ret = -RT_ERROR;
  251. if ((ret = rt_sem_take(adc_touch_sem, rt_tick_from_millisecond(500))) == RT_EOK)
  252. {
  253. rt_memset(psTouchPoint, 0, sizeof(struct rt_touch_data));
  254. if (rt_device_read(pdev, 0, psTouchPoint, s_NuAdcTouch.dev.info.point_num) == s_NuAdcTouch.dev.info.point_num)
  255. {
  256. ret = RT_EOK;
  257. }
  258. }
  259. return ret;
  260. }
  261. RT_WEAK void nu_touch_inputevent_cb(rt_int16_t x, rt_int16_t y, rt_uint8_t event)
  262. {
  263. }
  264. static rt_device_t lcd_device = 0;
  265. static struct rt_device_graphic_info info;
  266. static void lcd_cleanscreen(void)
  267. {
  268. if (info.framebuffer != RT_NULL)
  269. {
  270. /* Rendering */
  271. struct rt_device_rect_info rect;
  272. rt_memset(info.framebuffer, 0, (info.pitch * info.height));
  273. rect.x = 0;
  274. rect.y = 0;
  275. rect.width = info.width;
  276. rect.height = info.height;
  277. rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, &rect);
  278. }
  279. else
  280. {
  281. // TODO
  282. }
  283. }
  284. #define DEF_DOT_NUMBER 9
  285. #define DOTS_NUMBER (DEF_DOT_NUMBER*DEF_DOT_NUMBER)
  286. static void nu_draw_bots(int x, int y)
  287. {
  288. if (info.framebuffer != RT_NULL)
  289. {
  290. /* Rendering */
  291. struct rt_device_rect_info rect;
  292. int i, j;
  293. int start_x = x - (DEF_DOT_NUMBER / 2);
  294. int start_y = y - (DEF_DOT_NUMBER / 2);
  295. if (info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
  296. {
  297. uint16_t *pu16Start = (uint16_t *)((uint32_t)info.framebuffer + (start_y) * info.pitch + (start_x * 2));
  298. for (j = 0; j < DEF_DOT_NUMBER; j++)
  299. {
  300. for (i = 0; i < DEF_DOT_NUMBER; i++)
  301. pu16Start[i] = 0x07E0; //Green, RGB
  302. pu16Start += info.width;
  303. }
  304. }
  305. else if (info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
  306. {
  307. uint32_t *pu32Start = (uint32_t *)((uint32_t)info.framebuffer + (start_y) * info.pitch + (start_x * 4));
  308. for (j = 0; j < DEF_DOT_NUMBER; j++)
  309. {
  310. for (i = 0; i < DEF_DOT_NUMBER; i++)
  311. pu32Start[i] = 0xff00ff00; //Green, ARGB
  312. pu32Start += info.width;
  313. }
  314. }
  315. else
  316. {
  317. //Not supported
  318. }
  319. rect.x = 0;
  320. rect.y = 0;
  321. rect.width = info.width;
  322. rect.height = info.height;
  323. rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, &rect);
  324. }
  325. else
  326. {
  327. // TODO
  328. }
  329. }
  330. #if (DEF_CAL_POINT_NUM==3)
  331. const S_COORDINATE_POINT sDispPoints[DEF_CAL_POINT_NUM] =
  332. {
  333. {BSP_LCD_WIDTH / 4, BSP_LCD_HEIGHT / 2},
  334. {BSP_LCD_WIDTH - BSP_LCD_WIDTH / 4, BSP_LCD_HEIGHT / 4},
  335. {BSP_LCD_WIDTH / 2, BSP_LCD_HEIGHT - BSP_LCD_HEIGHT / 4}
  336. };
  337. #elif (DEF_CAL_POINT_NUM==5)
  338. const static S_COORDINATE_POINT sDispPoints[DEF_CAL_POINT_NUM] =
  339. {
  340. #define DEF_CUT_PIECES 8
  341. {BSP_LCD_WIDTH / DEF_CUT_PIECES, BSP_LCD_HEIGHT / DEF_CUT_PIECES},
  342. {BSP_LCD_WIDTH - BSP_LCD_WIDTH / DEF_CUT_PIECES, BSP_LCD_HEIGHT / DEF_CUT_PIECES},
  343. {BSP_LCD_WIDTH - BSP_LCD_WIDTH / DEF_CUT_PIECES, BSP_LCD_HEIGHT - BSP_LCD_HEIGHT / DEF_CUT_PIECES},
  344. {BSP_LCD_WIDTH / DEF_CUT_PIECES, BSP_LCD_HEIGHT - BSP_LCD_HEIGHT / DEF_CUT_PIECES},
  345. {BSP_LCD_WIDTH / 2, BSP_LCD_HEIGHT / 2}
  346. };
  347. #endif
  348. static int nu_adc_touch_readfile(void)
  349. {
  350. int fd;
  351. S_CALIBRATION_MATRIX sCalMat;
  352. if ((fd = open(PATH_CALIBRATION_FILE, O_RDONLY, 0)) < 0)
  353. {
  354. goto exit_nu_adc_touch_readfile;
  355. }
  356. else if (read(fd, &sCalMat, sizeof(S_CALIBRATION_MATRIX)) == sizeof(S_CALIBRATION_MATRIX))
  357. {
  358. rt_kprintf("[%s] %s\n", __func__, PATH_CALIBRATION_FILE);
  359. }
  360. close(fd);
  361. nu_adc_touch_update_calmat(&sCalMat);
  362. return 0;
  363. exit_nu_adc_touch_readfile:
  364. return -1;
  365. }
  366. static int nu_adc_touch_writefile(void *buf, int buf_len)
  367. {
  368. int fd;
  369. if ((fd = open(PATH_CALIBRATION_FILE, O_WRONLY | O_CREAT, 0)) < 0)
  370. {
  371. goto exit_nu_adc_touch_writefile;
  372. }
  373. else if (write(fd, buf, buf_len) == buf_len)
  374. {
  375. rt_kprintf("[%s] %s\n", __func__, PATH_CALIBRATION_FILE);
  376. }
  377. close(fd);
  378. return 0;
  379. exit_nu_adc_touch_writefile:
  380. return -1;
  381. }
  382. static void nu_touch_do_calibration(rt_device_t pdev)
  383. {
  384. int i;
  385. rt_err_t result;
  386. S_CALIBRATION_MATRIX sCalMat;
  387. S_COORDINATE_POINT sADCPoints[DEF_CAL_POINT_NUM];
  388. lcd_device = rt_device_find("lcd");
  389. if (!lcd_device)
  390. {
  391. rt_kprintf("Not supported graphics ops\n");
  392. return;
  393. }
  394. result = rt_device_control(lcd_device, RTGRAPHIC_CTRL_GET_INFO, &info);
  395. if (result != RT_EOK)
  396. {
  397. rt_kprintf("error!");
  398. return;
  399. }
  400. result = rt_device_open(lcd_device, 0);
  401. if (result != RT_EOK)
  402. {
  403. rt_kprintf("opened?");
  404. }
  405. rt_device_control(lcd_device, RTGRAPHIC_CTRL_PAN_DISPLAY, info.framebuffer);
  406. rt_device_control(lcd_device, RTGRAPHIC_CTRL_POWERON, RT_NULL);
  407. for (i = 0; i < DEF_CAL_POINT_NUM; i++)
  408. {
  409. struct rt_touch_data sTouchPoint;
  410. int count = 0;
  411. lcd_cleanscreen();
  412. /* Drain RX queue before doing calibrate. */
  413. while (adc_request_point(pdev, &sTouchPoint) == RT_EOK);
  414. rt_thread_mdelay(100);
  415. /* Ready to calibrate */
  416. nu_draw_bots(sDispPoints[i].x, sDispPoints[i].y);
  417. #define DEF_MAX_GET_POINT_NUM 5
  418. sADCPoints[i].x = 0;
  419. sADCPoints[i].y = 0;
  420. while (count < DEF_MAX_GET_POINT_NUM)
  421. {
  422. if (adc_request_point(pdev, &sTouchPoint) == RT_EOK)
  423. {
  424. sADCPoints[i].x += (int32_t)sTouchPoint.x_coordinate;
  425. sADCPoints[i].y += (int32_t)sTouchPoint.y_coordinate;
  426. rt_kprintf("[%d %d] - Disp:[%d, %d] -> ADC:[%d, %d]\n", i, count, sDispPoints[i].x, sDispPoints[i].y, sADCPoints[i].x, sADCPoints[i].y);
  427. count++;
  428. }
  429. }
  430. sADCPoints[i].x = (int32_t)((float)sADCPoints[i].x / DEF_MAX_GET_POINT_NUM);
  431. sADCPoints[i].y = (int32_t)((float)sADCPoints[i].y / DEF_MAX_GET_POINT_NUM);
  432. rt_kprintf("[%d] - Disp:[%d, %d], ADC:[%d, %d]\n", i, sDispPoints[i].x, sDispPoints[i].y, sADCPoints[i].x, sADCPoints[i].y);
  433. rt_thread_mdelay(300);
  434. }
  435. lcd_cleanscreen();
  436. /* Get calibration matrix. */
  437. if (nu_adc_cal_mat_get(&sDispPoints[0], &sADCPoints[0], &sCalMat) == 0)
  438. {
  439. /* Finally, update calibration matrix to drivers. */
  440. nu_adc_touch_update_calmat(&sCalMat);
  441. nu_adc_touch_writefile(&sCalMat, sizeof(sCalMat));
  442. for (i = 0; i < DEF_CAL_POINT_NUM; i++)
  443. {
  444. rt_kprintf("[%d] - Disp:[%d, %d], ADC:[%d, %d]\n", i, sDispPoints[i].x, sDispPoints[i].y, sADCPoints[i].x, sADCPoints[i].y);
  445. }
  446. }
  447. else
  448. {
  449. rt_kprintf("Failed to calibrate.\n");
  450. }
  451. rt_device_control(lcd_device, RTGRAPHIC_CTRL_POWEROFF, RT_NULL);
  452. rt_device_close(lcd_device);
  453. return;
  454. }
  455. static void adc_touch_entry(void *parameter)
  456. {
  457. struct rt_touch_data touch_point;
  458. rt_err_t result;
  459. rt_device_t pdev;
  460. int max_range;
  461. adc_touch_sem = rt_sem_create("adc_touch_sem", 0, RT_IPC_FLAG_FIFO);
  462. RT_ASSERT(adc_touch_sem != RT_NULL);
  463. pdev = rt_device_find("adc_touch");
  464. if (!pdev)
  465. {
  466. rt_kprintf("Not found\n");
  467. return ;
  468. }
  469. nu_adc_touch_readfile();
  470. result = rt_device_open(pdev, RT_DEVICE_FLAG_INT_RX);
  471. RT_ASSERT(result == RT_EOK);
  472. result = rt_device_set_rx_indicate(pdev, adc_touch_rx_callback);
  473. RT_ASSERT(result == RT_EOK);
  474. max_range = BSP_LCD_WIDTH;
  475. result = rt_device_control(pdev, RT_TOUCH_CTRL_SET_X_RANGE, (void *)&max_range);
  476. RT_ASSERT(result == RT_EOK);
  477. max_range = BSP_LCD_HEIGHT;
  478. result = rt_device_control(pdev, RT_TOUCH_CTRL_SET_Y_RANGE, (void *)&max_range);
  479. RT_ASSERT(result == RT_EOK);
  480. result = rt_device_control(pdev, RT_TOUCH_CTRL_POWER_ON, RT_NULL);
  481. RT_ASSERT(result == RT_EOK);
  482. while (adc_touch_worker_run)
  483. {
  484. if (!g_u32Calibrated)
  485. {
  486. rt_kprintf("Start ADC touching calibration.\n");
  487. nu_touch_do_calibration(pdev);
  488. rt_kprintf("Stop ADC touching calibration.\n");
  489. continue;
  490. }
  491. if (adc_request_point(pdev, &touch_point) == RT_EOK)
  492. {
  493. if (touch_point.event == RT_TOUCH_EVENT_DOWN
  494. || touch_point.event == RT_TOUCH_EVENT_UP
  495. || touch_point.event == RT_TOUCH_EVENT_MOVE)
  496. {
  497. nu_touch_inputevent_cb(touch_point.x_coordinate, touch_point.y_coordinate, touch_point.event);
  498. rt_kprintf("x=%d y=%d event=%s%s%s\n",
  499. touch_point.x_coordinate,
  500. touch_point.y_coordinate,
  501. (touch_point.event == RT_TOUCH_EVENT_DOWN) ? "DOWN" : "",
  502. (touch_point.event == RT_TOUCH_EVENT_UP) ? "UP" : "",
  503. (touch_point.event == RT_TOUCH_EVENT_MOVE) ? "MOVE" : "");
  504. }
  505. }
  506. }
  507. result = rt_device_control(pdev, RT_TOUCH_CTRL_POWER_OFF, RT_NULL);
  508. RT_ASSERT(result == RT_EOK);
  509. result = rt_device_close(pdev);
  510. RT_ASSERT(result == RT_EOK);
  511. }
  512. /* Support "nu_touch_start" command line in msh mode */
  513. static rt_err_t nu_touch_start(int argc, char **argv)
  514. {
  515. if (adc_touch_thread == RT_NULL)
  516. {
  517. adc_touch_thread = rt_thread_create("adc_touch_thread",
  518. adc_touch_entry,
  519. RT_NULL,
  520. 4096,
  521. 25,
  522. 5);
  523. adc_touch_worker_run = 1;
  524. if (adc_touch_thread != RT_NULL)
  525. rt_thread_startup(adc_touch_thread);
  526. }
  527. return 0;
  528. }
  529. MSH_CMD_EXPORT(nu_touch_start, e.g: start adc touch);
  530. /* Support "nu_touch_stop" command line in msh mode */
  531. static rt_err_t nu_touch_stop(int argc, char **argv)
  532. {
  533. adc_touch_worker_run = 0;
  534. adc_touch_thread = RT_NULL;
  535. return 0;
  536. }
  537. MSH_CMD_EXPORT(nu_touch_stop, e.g: stop adc touch);
  538. static int nu_touch_autostart(void)
  539. {
  540. return nu_touch_start(0, RT_NULL);
  541. }
  542. INIT_APP_EXPORT(nu_touch_autostart);
  543. static rt_err_t nu_touch_calibration(int argc, char **argv)
  544. {
  545. /* Clean calibration matrix data for getting raw adc value. */
  546. nu_adc_touch_reset_calmat();
  547. return 0;
  548. }
  549. MSH_CMD_EXPORT(nu_touch_calibration, for adc touch);
  550. #endif //#if defined(BSP_USING_ADC_TOUCH)