calibration.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. #include <rtgui/rtgui.h>
  2. #include <rtgui/dc.h>
  3. #include <rtgui/rtgui_system.h>
  4. #include <rtgui/widgets/window.h>
  5. #include <rtgui/rtgui_app.h>
  6. #include "touch.h"
  7. #define CALIBRATION_STEP_LEFTTOP 0
  8. #define CALIBRATION_STEP_RIGHTTOP 1
  9. #define CALIBRATION_STEP_RIGHTBOTTOM 2
  10. #define CALIBRATION_STEP_LEFTBOTTOM 3
  11. #define CALIBRATION_STEP_CENTER 4
  12. #define TOUCH_WIN_UPDATE 1
  13. #define TOUCH_WIN_CLOSE 2
  14. #define CALIBRATION_WIDTH 15
  15. #define CALIBRATION_HEIGHT 15
  16. struct calibration_session
  17. {
  18. rt_uint8_t step;
  19. struct calibration_data data;
  20. rt_uint16_t width;
  21. rt_uint16_t height;
  22. rt_device_t device;
  23. rt_thread_t tid;
  24. struct rtgui_win *wid;
  25. };
  26. static struct calibration_session *calibration_ptr = RT_NULL;
  27. static void calibration_data_post(rt_uint16_t x, rt_uint16_t y)
  28. {
  29. if (calibration_ptr != RT_NULL)
  30. {
  31. switch (calibration_ptr->step)
  32. {
  33. case CALIBRATION_STEP_LEFTTOP:
  34. calibration_ptr->data.min_x = x;
  35. calibration_ptr->data.min_y = y;
  36. break;
  37. case CALIBRATION_STEP_RIGHTTOP:
  38. calibration_ptr->data.max_x = x;
  39. calibration_ptr->data.min_y = (calibration_ptr->data.min_y + y)/2;
  40. break;
  41. case CALIBRATION_STEP_LEFTBOTTOM:
  42. calibration_ptr->data.min_x = (calibration_ptr->data.min_x + x)/2;
  43. calibration_ptr->data.max_y = y;
  44. break;
  45. case CALIBRATION_STEP_RIGHTBOTTOM:
  46. calibration_ptr->data.max_x = (calibration_ptr->data.max_x + x)/2;
  47. calibration_ptr->data.max_y = (calibration_ptr->data.max_y + y)/2;
  48. break;
  49. case CALIBRATION_STEP_CENTER:
  50. /* calibration done */
  51. {
  52. rt_uint16_t w, h;
  53. struct rtgui_event_command ecmd;
  54. RTGUI_EVENT_COMMAND_INIT(&ecmd);
  55. ecmd.command_id = TOUCH_WIN_CLOSE;
  56. ecmd.wid = calibration_ptr->wid;
  57. /* calculate calibrated data */
  58. if (calibration_ptr->data.max_x > calibration_ptr->data.min_x)
  59. w = calibration_ptr->data.max_x - calibration_ptr->data.min_x;
  60. else
  61. w = calibration_ptr->data.min_x - calibration_ptr->data.max_x;
  62. w = (w/(calibration_ptr->width - 2 * CALIBRATION_WIDTH)) * CALIBRATION_WIDTH;
  63. if (calibration_ptr->data.max_y > calibration_ptr->data.min_y)
  64. h = calibration_ptr->data.max_y - calibration_ptr->data.min_y;
  65. else
  66. h = calibration_ptr->data.min_y - calibration_ptr->data.max_y;
  67. h = (h/(calibration_ptr->height - 2 * CALIBRATION_HEIGHT)) * CALIBRATION_HEIGHT;
  68. rt_kprintf("w: %d, h: %d\n", w, h);
  69. if (calibration_ptr->data.max_x > calibration_ptr->data.min_x)
  70. {
  71. calibration_ptr->data.min_x -= w;
  72. calibration_ptr->data.max_x += w;
  73. }
  74. else
  75. {
  76. calibration_ptr->data.min_x += w;
  77. calibration_ptr->data.max_x -= w;
  78. }
  79. if (calibration_ptr->data.max_y > calibration_ptr->data.min_y)
  80. {
  81. calibration_ptr->data.min_y -= h;
  82. calibration_ptr->data.max_y += h;
  83. }
  84. else
  85. {
  86. calibration_ptr->data.min_y += h;
  87. calibration_ptr->data.max_y -= h;
  88. }
  89. rt_kprintf("calibration data: (%d, %d), (%d, %d)\n",
  90. calibration_ptr->data.min_x,
  91. calibration_ptr->data.max_x,
  92. calibration_ptr->data.min_y,
  93. calibration_ptr->data.max_y);
  94. rtgui_send(calibration_ptr->tid, &ecmd.parent, sizeof(struct rtgui_event_command));
  95. }
  96. return;
  97. }
  98. calibration_ptr->step ++;
  99. /* post command event */
  100. {
  101. struct rtgui_event_command ecmd;
  102. RTGUI_EVENT_COMMAND_INIT(&ecmd);
  103. ecmd.command_id = TOUCH_WIN_UPDATE;
  104. ecmd.wid = calibration_ptr->wid;
  105. rtgui_send(calibration_ptr->tid, &ecmd.parent, sizeof(struct rtgui_event_command));
  106. }
  107. }
  108. }
  109. rt_bool_t calibration_event_handler(struct rtgui_object *object, struct rtgui_event *event)
  110. {
  111. struct rtgui_widget *widget;
  112. widget = RTGUI_WIDGET(object);
  113. switch (event->type)
  114. {
  115. case RTGUI_EVENT_PAINT:
  116. {
  117. struct rtgui_dc *dc;
  118. struct rtgui_rect rect;
  119. dc = rtgui_dc_begin_drawing(widget);
  120. if (dc == RT_NULL)
  121. break;
  122. /* get rect information */
  123. rtgui_widget_get_rect(widget, &rect);
  124. /* clear whole window */
  125. RTGUI_WIDGET_BACKGROUND(widget) = white;
  126. rtgui_dc_fill_rect(dc, &rect);
  127. /* reset color */
  128. RTGUI_WIDGET_BACKGROUND(widget) = green;
  129. RTGUI_WIDGET_FOREGROUND(widget) = black;
  130. switch (calibration_ptr->step)
  131. {
  132. case CALIBRATION_STEP_LEFTTOP:
  133. rtgui_dc_draw_hline(dc, 0, 2 * CALIBRATION_WIDTH, CALIBRATION_HEIGHT);
  134. rtgui_dc_draw_vline(dc, CALIBRATION_WIDTH, 0, 2 * CALIBRATION_HEIGHT);
  135. RTGUI_WIDGET_FOREGROUND(widget) = red;
  136. rtgui_dc_fill_circle(dc, CALIBRATION_WIDTH, CALIBRATION_HEIGHT, 4);
  137. break;
  138. case CALIBRATION_STEP_RIGHTTOP:
  139. rtgui_dc_draw_hline(dc, calibration_ptr->width - 2 * CALIBRATION_WIDTH,
  140. calibration_ptr->width, CALIBRATION_HEIGHT);
  141. rtgui_dc_draw_vline(dc, calibration_ptr->width - CALIBRATION_WIDTH, 0, 2 * CALIBRATION_HEIGHT);
  142. RTGUI_WIDGET_FOREGROUND(widget) = red;
  143. rtgui_dc_fill_circle(dc, calibration_ptr->width - CALIBRATION_WIDTH, CALIBRATION_HEIGHT, 4);
  144. break;
  145. case CALIBRATION_STEP_LEFTBOTTOM:
  146. rtgui_dc_draw_hline(dc, 0, 2 * CALIBRATION_WIDTH, calibration_ptr->height - CALIBRATION_HEIGHT);
  147. rtgui_dc_draw_vline(dc, CALIBRATION_WIDTH, calibration_ptr->height - 2 * CALIBRATION_HEIGHT, calibration_ptr->height);
  148. RTGUI_WIDGET_FOREGROUND(widget) = red;
  149. rtgui_dc_fill_circle(dc, CALIBRATION_WIDTH, calibration_ptr->height - CALIBRATION_HEIGHT, 4);
  150. break;
  151. case CALIBRATION_STEP_RIGHTBOTTOM:
  152. rtgui_dc_draw_hline(dc, calibration_ptr->width - 2 * CALIBRATION_WIDTH,
  153. calibration_ptr->width, calibration_ptr->height - CALIBRATION_HEIGHT);
  154. rtgui_dc_draw_vline(dc, calibration_ptr->width - CALIBRATION_WIDTH, calibration_ptr->height - 2 * CALIBRATION_HEIGHT, calibration_ptr->height);
  155. RTGUI_WIDGET_FOREGROUND(widget) = red;
  156. rtgui_dc_fill_circle(dc, calibration_ptr->width - CALIBRATION_WIDTH, calibration_ptr->height - CALIBRATION_HEIGHT, 4);
  157. break;
  158. case CALIBRATION_STEP_CENTER:
  159. rtgui_dc_draw_hline(dc, calibration_ptr->width/2 - CALIBRATION_WIDTH, calibration_ptr->width/2 + CALIBRATION_WIDTH, calibration_ptr->height/2);
  160. rtgui_dc_draw_vline(dc, calibration_ptr->width/2, calibration_ptr->height/2 - CALIBRATION_HEIGHT, calibration_ptr->height/2 + CALIBRATION_HEIGHT);
  161. RTGUI_WIDGET_FOREGROUND(widget) = red;
  162. rtgui_dc_fill_circle(dc, calibration_ptr->width/2, calibration_ptr->height/2, 4);
  163. break;
  164. }
  165. rtgui_dc_end_drawing(dc);
  166. }
  167. break;
  168. case RTGUI_EVENT_COMMAND:
  169. {
  170. struct rtgui_event_command *ecmd = (struct rtgui_event_command *)event;
  171. switch (ecmd->command_id)
  172. {
  173. case TOUCH_WIN_UPDATE:
  174. rtgui_widget_update(widget);
  175. break;
  176. case TOUCH_WIN_CLOSE:
  177. rtgui_win_close(RTGUI_WIN(widget));
  178. break;
  179. }
  180. }
  181. return RT_TRUE;
  182. default:
  183. rtgui_win_event_handler(RTGUI_OBJECT(widget), event);
  184. break;
  185. }
  186. return RT_FALSE;
  187. }
  188. void calibration_entry(void *parameter)
  189. {
  190. struct rtgui_app *app;
  191. struct rtgui_win *win;
  192. struct rtgui_rect rect;
  193. app = rtgui_app_create(rt_thread_self(), "cali");
  194. if (app == RT_NULL)
  195. return;
  196. rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &rect);
  197. /* set screen rect */
  198. calibration_ptr->width = rect.x2;
  199. calibration_ptr->height = rect.y2;
  200. /* create calibration window */
  201. win = rtgui_win_create(RT_NULL,
  202. "calibration", &rect, RTGUI_WIN_STYLE_NO_TITLE | RTGUI_WIN_STYLE_NO_BORDER);
  203. if (win == RT_NULL)
  204. {
  205. rtgui_app_destroy(app);
  206. return;
  207. }
  208. calibration_ptr->wid = win;
  209. rtgui_object_set_event_handler(RTGUI_OBJECT(win), calibration_event_handler);
  210. rtgui_win_show(win, RT_TRUE);
  211. rtgui_win_destroy(win);
  212. rtgui_app_destroy(app);
  213. /* set calibration data */
  214. rt_device_control(calibration_ptr->device, RT_TOUCH_CALIBRATION_DATA, &calibration_ptr->data);
  215. /* recover to normal */
  216. rt_device_control(calibration_ptr->device, RT_TOUCH_NORMAL, RT_NULL);
  217. /* release memory */
  218. rt_free(calibration_ptr);
  219. calibration_ptr = RT_NULL;
  220. }
  221. void calibration_init(void)
  222. {
  223. rt_device_t device;
  224. device = rt_device_find("touch");
  225. if (device == RT_NULL)
  226. return;
  227. calibration_ptr = (struct calibration_session *)rt_malloc(sizeof(struct calibration_session));
  228. rt_memset(calibration_ptr, 0, sizeof(struct calibration_data));
  229. calibration_ptr->device = device;
  230. rt_device_control(calibration_ptr->device, RT_TOUCH_CALIBRATION, (void *)calibration_data_post);
  231. calibration_ptr->tid = rt_thread_create("cali", calibration_entry, RT_NULL, 2048, 20, 5);
  232. if (calibration_ptr->tid != RT_NULL)
  233. rt_thread_startup(calibration_ptr->tid);
  234. }
  235. #ifdef RT_USING_FINSH
  236. #include <finsh.h>
  237. void calibration(void)
  238. {
  239. calibration_init();
  240. }
  241. FINSH_FUNCTION_EXPORT(calibration, perform touch calibration);
  242. #endif