calibration.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #include <rtgui/rtgui.h>
  2. #include <rtgui/dc.h>
  3. #include <rtgui/rtgui_system.h>
  4. #include <rtgui/widgets/window.h>
  5. #include "touch.h"
  6. #define CALIBRATION_STEP_LEFTTOP 0
  7. #define CALIBRATION_STEP_RIGHTTOP 1
  8. #define CALIBRATION_STEP_RIGHTBOTTOM 2
  9. #define CALIBRATION_STEP_LEFTBOTTOM 3
  10. #define CALIBRATION_STEP_CENTER 4
  11. #define TOUCH_WIN_UPDATE 1
  12. #define TOUCH_WIN_CLOSE 2
  13. struct calibration_session
  14. {
  15. rt_uint8_t step;
  16. struct calibration_data data;
  17. rt_uint16_t width; rt_uint16_t height;
  18. rt_device_t device;
  19. rt_thread_t tid;
  20. };
  21. static struct calibration_session* calibration_ptr = RT_NULL;
  22. static void calibration_data_post(rt_uint16_t x, rt_uint16_t y)
  23. {
  24. if (calibration_ptr != RT_NULL)
  25. {
  26. switch (calibration_ptr->step)
  27. {
  28. case CALIBRATION_STEP_LEFTTOP:
  29. calibration_ptr->data.min_x = x;
  30. calibration_ptr->data.min_y = y;
  31. break;
  32. case CALIBRATION_STEP_RIGHTTOP:
  33. calibration_ptr->data.max_x = x;
  34. calibration_ptr->data.min_y = (calibration_ptr->data.min_y + y)/2;
  35. break;
  36. case CALIBRATION_STEP_LEFTBOTTOM:
  37. calibration_ptr->data.min_x = (calibration_ptr->data.min_x + x)/2;
  38. calibration_ptr->data.max_y = y;
  39. break;
  40. case CALIBRATION_STEP_RIGHTBOTTOM:
  41. calibration_ptr->data.max_x = (calibration_ptr->data.max_x + x)/2;
  42. calibration_ptr->data.max_y = (calibration_ptr->data.max_y + y)/2;
  43. break;
  44. case CALIBRATION_STEP_CENTER:
  45. /* calibration done */
  46. {
  47. struct rtgui_event_command ecmd;
  48. RTGUI_EVENT_COMMAND_INIT(&ecmd);
  49. ecmd.command_id = TOUCH_WIN_CLOSE;
  50. rtgui_thread_send(calibration_ptr->tid, &ecmd.parent, sizeof(struct rtgui_event_command));
  51. }
  52. return;
  53. }
  54. calibration_ptr->step ++;
  55. /* post command event */
  56. {
  57. struct rtgui_event_command ecmd;
  58. RTGUI_EVENT_COMMAND_INIT(&ecmd);
  59. ecmd.command_id = TOUCH_WIN_UPDATE;
  60. rtgui_thread_send(calibration_ptr->tid, &ecmd.parent, sizeof(struct rtgui_event_command));
  61. }
  62. }
  63. }
  64. rt_bool_t calibration_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
  65. {
  66. switch (event->type)
  67. {
  68. case RTGUI_EVENT_PAINT:
  69. {
  70. struct rtgui_dc* dc;
  71. struct rtgui_rect rect;
  72. dc = rtgui_dc_begin_drawing(widget);
  73. if (dc == RT_NULL) break;
  74. /* get rect information */
  75. rtgui_widget_get_rect(widget, &rect);
  76. /* clear whole window */
  77. RTGUI_WIDGET_BACKGROUND(widget) = white;
  78. rtgui_dc_fill_rect(dc, &rect);
  79. /* reset color */
  80. RTGUI_WIDGET_BACKGROUND(widget) = green;
  81. RTGUI_WIDGET_FOREGROUND(widget) = black;
  82. switch (calibration_ptr->step)
  83. {
  84. case CALIBRATION_STEP_LEFTTOP:
  85. rtgui_dc_draw_hline(dc, 1, 1 + 15, 1);
  86. rtgui_dc_draw_vline(dc, 1, 1, 1 + 15);
  87. RTGUI_WIDGET_FOREGROUND(widget) = red;
  88. rtgui_dc_fill_circle(dc, 0, 0, 4);
  89. break;
  90. case CALIBRATION_STEP_RIGHTTOP:
  91. rtgui_dc_draw_hline(dc, calibration_ptr->width - 1 - 15, calibration_ptr->width - 1, 1);
  92. rtgui_dc_draw_vline(dc, calibration_ptr->width - 1, 1, 1 + 15);
  93. RTGUI_WIDGET_FOREGROUND(widget) = red;
  94. rtgui_dc_fill_circle(dc, calibration_ptr->width - 1, 0, 4);
  95. break;
  96. case CALIBRATION_STEP_LEFTBOTTOM:
  97. rtgui_dc_draw_hline(dc, 1, 1 + 15, calibration_ptr->height - 1);
  98. rtgui_dc_draw_vline(dc, 1, calibration_ptr->height - 1 - 15, calibration_ptr->height - 1);
  99. RTGUI_WIDGET_FOREGROUND(widget) = red;
  100. rtgui_dc_fill_circle(dc, 0, calibration_ptr->height - 1, 4);
  101. break;
  102. case CALIBRATION_STEP_RIGHTBOTTOM:
  103. rtgui_dc_draw_hline(dc, calibration_ptr->width - 1 - 15, calibration_ptr->width - 1, calibration_ptr->height - 1);
  104. rtgui_dc_draw_vline(dc, calibration_ptr->width - 1, calibration_ptr->height - 1 - 15, calibration_ptr->height - 1);
  105. RTGUI_WIDGET_FOREGROUND(widget) = red;
  106. rtgui_dc_fill_circle(dc, calibration_ptr->width - 1, calibration_ptr->height - 1, 4);
  107. break;
  108. case CALIBRATION_STEP_CENTER:
  109. rtgui_dc_draw_hline(dc, calibration_ptr->width/2 - 15, calibration_ptr->width/2 + 15, calibration_ptr->height/2);
  110. rtgui_dc_draw_vline(dc, calibration_ptr->width/2, calibration_ptr->height/2 - 15, calibration_ptr->height/2 + 15);
  111. RTGUI_WIDGET_FOREGROUND(widget) = red;
  112. rtgui_dc_fill_circle(dc, calibration_ptr->width/2, calibration_ptr->height/2, 4);
  113. break;
  114. }
  115. rtgui_dc_end_drawing(dc);
  116. }
  117. break;
  118. case RTGUI_EVENT_COMMAND:
  119. {
  120. struct rtgui_event_command* ecmd = (struct rtgui_event_command*)event;
  121. switch (ecmd->command_id)
  122. {
  123. case TOUCH_WIN_UPDATE:
  124. rtgui_widget_update(widget);
  125. break;
  126. case TOUCH_WIN_CLOSE:
  127. rtgui_win_close(RTGUI_WIN(widget));
  128. break;
  129. }
  130. }
  131. return RT_TRUE;
  132. default:
  133. rtgui_win_event_handler(widget, event);
  134. }
  135. return RT_FALSE;
  136. }
  137. void calibration_entry(void* parameter)
  138. {
  139. rt_mq_t mq;
  140. rtgui_win_t* win;
  141. struct rtgui_rect rect;
  142. mq = rt_mq_create("cali", 40, 8, RT_IPC_FLAG_FIFO);
  143. if (mq == RT_NULL) return;
  144. rtgui_thread_register(rt_thread_self(), mq);
  145. rtgui_graphic_driver_get_default_rect(&rect);
  146. /* set screen rect */
  147. calibration_ptr->width = rect.x2;
  148. calibration_ptr->height = rect.y2;
  149. /* create calibration window */
  150. win = rtgui_win_create(RT_NULL,
  151. "calibration", &rect, RTGUI_WIN_STYLE_NO_TITLE | RTGUI_WIN_STYLE_NO_BORDER);
  152. rtgui_widget_set_event_handler(RTGUI_WIDGET(win), calibration_event_handler);
  153. if (win != RT_NULL)
  154. {
  155. rtgui_win_show(win, RT_FALSE);
  156. // rtgui_widget_update(RTGUI_WIDGET(win));
  157. rtgui_win_event_loop(win);
  158. }
  159. rtgui_thread_deregister(rt_thread_self());
  160. rt_mq_delete(mq);
  161. /* set calibration data */
  162. rt_device_control(calibration_ptr->device, RT_TOUCH_CALIBRATION_DATA, &calibration_ptr->data);
  163. /* recover to normal */
  164. rt_device_control(calibration_ptr->device, RT_TOUCH_NORMAL, RT_NULL);
  165. /* release memory */
  166. rt_free(calibration_ptr);
  167. calibration_ptr = RT_NULL;
  168. }
  169. void calibration_init()
  170. {
  171. rt_device_t device;
  172. device = rt_device_find("touch");
  173. if (device == RT_NULL) return; /* no this device */
  174. calibration_ptr = (struct calibration_session*)rt_malloc(sizeof(struct calibration_session));
  175. rt_memset(calibration_ptr, 0, sizeof(struct calibration_data));
  176. calibration_ptr->device = device;
  177. rt_device_control(calibration_ptr->device, RT_TOUCH_CALIBRATION, (void*)calibration_data_post);
  178. calibration_ptr->tid = rt_thread_create("cali", calibration_entry, RT_NULL,
  179. 2048, 20, 5);
  180. if (calibration_ptr->tid != RT_NULL) rt_thread_startup(calibration_ptr->tid);
  181. }
  182. #include <finsh.h>
  183. void calibration()
  184. {
  185. calibration_init();
  186. }
  187. FINSH_FUNCTION_EXPORT(calibration, perform touch calibration);