drv_touch.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /*
  2. * COPYRIGHT (C) 2012-2022, Shanghai Real-Thread Technology Co., Ltd
  3. * All rights reserved.
  4. * Change Logs:
  5. * Date Author Notes
  6. * 2018-02-08 RT-Thread the first version
  7. */
  8. #include <rtthread.h>
  9. #include <rtdevice.h>
  10. #include "drv_touch.h"
  11. #include "drv_pin.h"
  12. // #include "lcd_cfg.h"
  13. #ifndef TOUCH_I2C_NAME
  14. #define TOUCH_I2C_NAME "i2c2"
  15. #endif
  16. #define DBG_TAG "TOUCH"
  17. #define DBG_LVL DBG_LOG
  18. #include <rtdbg.h>
  19. #define COORD_Y_REVERSE (1 << 0)
  20. #define COORD_X_REVERSE (1 << 1)
  21. #define COORD_XY_EXCHANGE (1 << 2)
  22. #ifdef BSP_USING_MANGOPI // mango board
  23. #define TP_INT_PIN GET_PIN(GPIO_PORT_D, GPIO_PIN_22) /* GPIO_PORT_D GPIO_PIN_22 */
  24. #elif defined(BSP_USING_M7)
  25. #define TP_INT_PIN GET_PIN(GPIO_PORT_G, GPIO_PIN_14) /* GPIO_PORT_G GPIO_PIN_14 */
  26. #endif
  27. static rt_slist_t _driver_list;
  28. static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
  29. static struct touch_driver *current_driver = RT_NULL;
  30. static struct rt_touch_device touch_device;
  31. static rt_timer_t touch_timer = RT_NULL;
  32. static int tp_convert_flag;
  33. // static const struct lcd_cfg_panel_info *_panel_info;
  34. void touch_coord_convert(int *x, int *y, int range_x, int range_y, int flag)
  35. {
  36. int xbuf, ybuf;
  37. if (flag & COORD_XY_EXCHANGE)
  38. {
  39. xbuf = range_x;
  40. range_x = range_y;
  41. range_y = xbuf;
  42. xbuf = *y;
  43. ybuf = *x;
  44. if (flag & COORD_X_REVERSE)
  45. {
  46. ybuf = range_y - ybuf;
  47. }
  48. if (flag & COORD_Y_REVERSE)
  49. {
  50. xbuf = range_x - xbuf;
  51. }
  52. }
  53. else
  54. {
  55. xbuf = *x;
  56. ybuf = *y;
  57. if (flag & COORD_X_REVERSE)
  58. {
  59. xbuf = range_x - xbuf;
  60. }
  61. if (flag & COORD_Y_REVERSE)
  62. {
  63. ybuf = range_y - ybuf;
  64. }
  65. }
  66. *x = xbuf;
  67. *y = ybuf;
  68. }
  69. rt_err_t rt_touch_drivers_register(touch_driver_t drv)
  70. {
  71. RT_ASSERT(drv != RT_NULL);
  72. RT_ASSERT(drv->ops != RT_NULL);
  73. RT_ASSERT(drv->probe != RT_NULL);
  74. rt_slist_append(&_driver_list, &drv->list);
  75. return RT_EOK;
  76. }
  77. int rt_touch_list_init(void)
  78. {
  79. rt_slist_init(&_driver_list);
  80. return RT_EOK;
  81. }
  82. INIT_BOARD_EXPORT(rt_touch_list_init);
  83. static void touch_timeout_handle(void *parameter)
  84. {
  85. rt_touch_t touch = (rt_touch_t)parameter;
  86. rt_device_t device = &touch->parent;
  87. device->control(device, RT_TOUCH_CTRL_ENABLE_INT, RT_NULL); // enable tp irq
  88. // rt_kprintf("[%s:%d]touch_timeout_handle\n", __FUNCTION__, __LINE__);
  89. }
  90. static rt_err_t tp_irq_handle(rt_touch_t touch)
  91. {
  92. rt_device_t device;
  93. device = &touch->parent;
  94. device->control(device, RT_TOUCH_CTRL_DISABLE_INT, RT_NULL); // disable tp irq
  95. return RT_EOK;
  96. }
  97. int rt_touch_read(rt_uint16_t addr, void *cmd_buf, size_t cmd_len, void *data_buf, size_t data_len)
  98. {
  99. struct rt_i2c_msg msgs[2];
  100. msgs[0].addr = addr;
  101. msgs[0].flags = RT_I2C_WR;
  102. msgs[0].buf = cmd_buf;
  103. msgs[0].len = cmd_len;
  104. msgs[1].addr = addr;
  105. msgs[1].flags = RT_I2C_RD;
  106. msgs[1].buf = data_buf;
  107. msgs[1].len = data_len;
  108. if (rt_i2c_transfer(i2c_bus, msgs, 2) == 2)
  109. return 0;
  110. else
  111. return -1;
  112. }
  113. int rt_touch_write(rt_uint16_t addr, void *data_buf, size_t data_len)
  114. {
  115. struct rt_i2c_msg msgs[1];
  116. msgs[0].addr = addr;
  117. msgs[0].flags = RT_I2C_WR;
  118. msgs[0].buf = data_buf;
  119. msgs[0].len = data_len;
  120. if (rt_i2c_transfer(i2c_bus, msgs, 1) == 1)
  121. return 0;
  122. else
  123. return -1;
  124. }
  125. static rt_ssize_t touch_readpoint(struct rt_touch_device *touch, void *buf, rt_size_t touch_num)
  126. {
  127. rt_device_t device;
  128. struct rt_touch_data *data = (struct rt_touch_data *)buf;
  129. int x, y;
  130. device = &touch->parent;
  131. current_driver->ops->read_point(data, touch_num);
  132. /* touch up事件是上次转换后的,所以不需要执行转换 */
  133. if ((RT_TOUCH_EVENT_NONE != data->event) && (RT_TOUCH_EVENT_UP != data->event))
  134. {
  135. x = data->x_coordinate;
  136. y = data->y_coordinate;
  137. // touch_coord_convert(&x, &y, _panel_info->width, _panel_info->height, tp_convert_flag);
  138. data->x_coordinate = x;
  139. data->y_coordinate = y;
  140. }
  141. if ((touch_timer != RT_NULL) && (current_driver->read_interval != 0))
  142. {
  143. rt_timer_start(touch_timer);
  144. }
  145. else if ((TOUCH_INT_MODE == current_driver->check_mode) && (0 != current_driver->read_interval))
  146. {
  147. device->control(device, RT_TOUCH_CTRL_ENABLE_INT, RT_NULL); // enable tp irq
  148. }
  149. else
  150. {
  151. }
  152. return 1;
  153. }
  154. static rt_err_t touch_control(struct rt_touch_device *touch, int cmd, void *arg)
  155. {
  156. return RT_EOK;
  157. }
  158. static struct rt_touch_ops touch_ops =
  159. {
  160. .touch_readpoint = touch_readpoint,
  161. .touch_control = touch_control,
  162. };
  163. static void touch_poll_entry(void *parameter)
  164. {
  165. rt_tick_t read_interval = current_driver->read_interval;
  166. if (0 == read_interval)
  167. {
  168. read_interval = rt_tick_from_millisecond(20);
  169. }
  170. while (1)
  171. {
  172. rt_thread_delay(read_interval);
  173. if (RT_NULL != touch_device.parent.rx_indicate)
  174. {
  175. /* Notify the application layer to get data */
  176. touch_device.parent.rx_indicate(&touch_device.parent, 1);
  177. }
  178. }
  179. }
  180. int rt_touch_init(void)
  181. {
  182. rt_slist_t *driver_list = RT_NULL;
  183. rt_uint16_t irq_pin = TP_INT_PIN;
  184. int range_x, range_y;
  185. i2c_bus = rt_i2c_bus_device_find(TOUCH_I2C_NAME);
  186. RT_ASSERT(i2c_bus);
  187. if (rt_device_open(&i2c_bus->parent, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
  188. {
  189. rt_kprintf("[TP] open i2c dvice failed.\n");
  190. return -RT_EIO;
  191. }
  192. rt_slist_for_each(driver_list, &_driver_list)
  193. {
  194. current_driver = (struct touch_driver *)driver_list;
  195. if (current_driver->probe(i2c_bus) == RT_TRUE)
  196. {
  197. break;
  198. }
  199. current_driver = RT_NULL;
  200. }
  201. if (current_driver == RT_NULL)
  202. {
  203. rt_kprintf("[TP] No touch pad or driver.\n");
  204. rt_device_close((rt_device_t)i2c_bus);
  205. return -RT_EIO;
  206. }
  207. if ((TOUCH_INT_MODE == current_driver->check_mode) && (0 != current_driver->read_interval))
  208. {
  209. touch_timer = rt_timer_create("touch", touch_timeout_handle,
  210. &touch_device, current_driver->read_interval,
  211. RT_TIMER_FLAG_ONE_SHOT);
  212. if (touch_timer == RT_NULL)
  213. {
  214. rt_kprintf("[TP] touch timer create failed.\n");
  215. rt_device_close((rt_device_t)i2c_bus);
  216. return -RT_EIO;
  217. }
  218. }
  219. else if (TOUCH_POLL_MODE == current_driver->check_mode)
  220. {
  221. rt_thread_t thread;
  222. irq_pin = PIN_IRQ_PIN_NONE; // No interrupt pins are used
  223. thread = rt_thread_create("touch", touch_poll_entry, RT_NULL, 2048, 16, 20);
  224. if (thread == RT_NULL)
  225. {
  226. rt_kprintf("[TP] touch poll thread create failed.\n");
  227. rt_device_close((rt_device_t)i2c_bus);
  228. return -RT_ERROR;
  229. }
  230. rt_thread_startup(thread);
  231. }
  232. /* loading the touchscreen configuration */
  233. // _panel_info = load_lcd_config_from_xml();
  234. // range_x = _panel_info->width;
  235. // range_y = _panel_info->height;
  236. // tp_convert_flag = 0;
  237. // /* touch screen xy swap */
  238. // if (_panel_info->ctp_flag & COORD_XY_EXCHANGE)
  239. // {
  240. // tp_convert_flag |= COORD_XY_EXCHANGE;
  241. // touch_coord_convert(&range_x, &range_y, _panel_info->width, _panel_info->height, COORD_XY_EXCHANGE);
  242. // }
  243. // if (_panel_info->ctp_flag & COORD_Y_REVERSE)
  244. // {
  245. // tp_convert_flag |= COORD_Y_REVERSE;
  246. // }
  247. // if (_panel_info->ctp_flag & COORD_X_REVERSE)
  248. // {
  249. // tp_convert_flag |= COORD_X_REVERSE;
  250. // }
  251. current_driver->ops->init(i2c_bus);
  252. /* touch infomation */
  253. touch_device.info.type = RT_TOUCH_TYPE_CAPACITANCE;
  254. touch_device.info.vendor = RT_TOUCH_VENDOR_UNKNOWN;
  255. touch_device.info.point_num = 1;
  256. touch_device.info.range_x = 480;
  257. touch_device.info.range_y = 272;
  258. touch_device.config.user_data = RT_NULL;
  259. touch_device.ops = &touch_ops;
  260. touch_device.irq_handle = tp_irq_handle;
  261. touch_device.config.irq_pin.pin = irq_pin;
  262. touch_device.config.irq_pin.mode = PIN_MODE_INPUT_PULLUP;
  263. return rt_hw_touch_register(&touch_device, "touch", RT_DEVICE_FLAG_INT_RX, RT_NULL);
  264. }
  265. INIT_ENV_EXPORT(rt_touch_init);