ft5446.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-04-11 Wayne First version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <string.h>
  13. #define DBG_TAG "ft5446"
  14. #define DBG_LVL DBG_INFO
  15. #include <rtdbg.h>
  16. #include "ft5446.h"
  17. static struct rt_i2c_client ft5446_client;
  18. static void ft5446_touch_up(void *buf, rt_int8_t id);
  19. static rt_err_t ft5446_write_reg(struct rt_i2c_client *dev, rt_uint8_t reg, rt_uint8_t value)
  20. {
  21. struct rt_i2c_msg msgs;
  22. rt_uint8_t buf[2];
  23. buf[0] = reg;
  24. buf[1] = value;
  25. msgs.addr = dev->client_addr;
  26. msgs.flags = RT_I2C_WR;
  27. msgs.buf = buf;
  28. msgs.len = sizeof(buf);
  29. if (rt_i2c_transfer(dev->bus, &msgs, 1) == 1)
  30. {
  31. return RT_EOK;
  32. }
  33. else
  34. {
  35. return -RT_ERROR;
  36. }
  37. }
  38. static rt_err_t ft5446_read_reg(struct rt_i2c_client *dev, rt_uint8_t reg, rt_uint8_t *data, rt_uint8_t len)
  39. {
  40. struct rt_i2c_msg msgs[2];
  41. msgs[0].addr = dev->client_addr;
  42. msgs[0].flags = RT_I2C_WR;
  43. msgs[0].buf = &reg;
  44. msgs[0].len = FT_REGITER_LEN;
  45. msgs[1].addr = dev->client_addr;
  46. msgs[1].flags = RT_I2C_RD;
  47. msgs[1].buf = data;
  48. msgs[1].len = len;
  49. if (rt_i2c_transfer(dev->bus, msgs, 2) == 2)
  50. {
  51. return RT_EOK;
  52. }
  53. else
  54. {
  55. return -RT_ERROR;
  56. }
  57. }
  58. static rt_int16_t pre_x[FT_MAX_TOUCH];
  59. static rt_int16_t pre_y[FT_MAX_TOUCH];
  60. static rt_int16_t pre_w[FT_MAX_TOUCH];
  61. static rt_uint8_t s_tp_dowm[FT_MAX_TOUCH];
  62. static void ft5446_touch_up(void *buf, rt_int8_t id)
  63. {
  64. struct rt_touch_data *read_data = (struct rt_touch_data *)buf;
  65. if (s_tp_dowm[id] == 1)
  66. {
  67. s_tp_dowm[id] = 0;
  68. read_data[id].event = RT_TOUCH_EVENT_UP;
  69. }
  70. else
  71. {
  72. read_data[id].event = RT_TOUCH_EVENT_NONE;
  73. }
  74. read_data[id].timestamp = rt_touch_get_ts();
  75. read_data[id].width = pre_w[id];
  76. read_data[id].x_coordinate = pre_x[id];
  77. read_data[id].y_coordinate = pre_y[id];
  78. read_data[id].track_id = id;
  79. pre_x[id] = -1; /* last point is none */
  80. pre_y[id] = -1;
  81. pre_w[id] = -1;
  82. //LOG_I("%s (%d)\n", __func__, id);
  83. }
  84. static void ft5446_touch_down(void *buf, rt_int8_t id, rt_int16_t x, rt_int16_t y, rt_int16_t w)
  85. {
  86. struct rt_touch_data *read_data = (struct rt_touch_data *)buf;
  87. if (s_tp_dowm[id] == 1)
  88. {
  89. read_data[id].event = RT_TOUCH_EVENT_MOVE;
  90. }
  91. else
  92. {
  93. read_data[id].event = RT_TOUCH_EVENT_DOWN;
  94. s_tp_dowm[id] = 1;
  95. }
  96. read_data[id].timestamp = rt_touch_get_ts();
  97. read_data[id].width = w;
  98. read_data[id].x_coordinate = x;
  99. read_data[id].y_coordinate = y;
  100. read_data[id].track_id = id;
  101. pre_x[id] = x; /* save last point */
  102. pre_y[id] = y;
  103. pre_w[id] = w;
  104. //LOG_I("%s (%d %d %d %d)\n", __func__, id, x, y, w );
  105. }
  106. static int8_t pre_id[FT_MAX_TOUCH];
  107. static S_FT_REGMAP sFtRegMap;
  108. static rt_uint8_t pre_touch = 0;
  109. static rt_size_t ft5446_read_point(struct rt_touch_device *touch, void *buf, rt_size_t read_num)
  110. {
  111. int i;
  112. rt_err_t error = 0;
  113. rt_int32_t touch_event, touchid;
  114. RT_ASSERT(touch);
  115. RT_ASSERT(buf);
  116. RT_ASSERT(read_num != 0);
  117. RT_ASSERT(read_num <= FT_MAX_TOUCH);
  118. error = ft5446_read_reg(&ft5446_client, 0, (rt_uint8_t *)&sFtRegMap, sizeof(sFtRegMap));
  119. if (error)
  120. {
  121. LOG_E("get touch data failed, err:%d\n", error);
  122. goto exit_read_point;
  123. }
  124. if (sFtRegMap.u8TDStatus > FT_MAX_TOUCH)
  125. {
  126. LOG_E("FW report max point:%d > panel info. max:%d\n", sFtRegMap.u8TDStatus, FT_MAX_TOUCH);
  127. goto exit_read_point;
  128. }
  129. if (pre_touch > sFtRegMap.u8TDStatus) /* point up */
  130. {
  131. for (i = 0; i < FT_MAX_TOUCH; i++)
  132. {
  133. rt_uint8_t j;
  134. for (j = 0; j < sFtRegMap.u8TDStatus; j++) /* this time touch num */
  135. {
  136. touchid = sFtRegMap.m_sTP[j].u8TouchID;
  137. if (touchid >= 0x0f)
  138. continue;
  139. if (pre_id[i] == touchid) /* this id is not free */
  140. break;
  141. }
  142. if ((j == sFtRegMap.u8TDStatus) && (pre_id[i] != -1)) /* free this node */
  143. {
  144. // LOG_I("free %d tid=%d\n", i, pre_id[i]);
  145. ft5446_touch_up(buf, pre_id[i]);
  146. pre_id[i] = -1;
  147. }
  148. }
  149. }
  150. for (i = 0; i < sFtRegMap.u8TDStatus; i++)
  151. {
  152. touch_event = sFtRegMap.m_sTP[i].u8EvtFlag;
  153. touchid = sFtRegMap.m_sTP[i].u8TouchID;
  154. //LOG_I("(%d/%d) %d %d\n", i, sFtRegMap.u8TDStatus, touchid, touch_event );
  155. if (touchid >= 0x0f)
  156. continue;
  157. pre_id[i] = touchid;
  158. if ((touch_event == FT_EVENTFLAG_PRESS_DOWN) || (touch_event == FT_EVENTFLAG_CONTACT))
  159. {
  160. rt_uint16_t x, y, w;
  161. x = ((uint16_t)sFtRegMap.m_sTP[i].u8X_11_8 << 8) | sFtRegMap.m_sTP[i].u8X_7_0;
  162. y = ((uint16_t)sFtRegMap.m_sTP[i].u8Y_11_8 << 8) | sFtRegMap.m_sTP[i].u8Y_7_0;
  163. w = sFtRegMap.m_sTP[i].m_u8Weight;
  164. //LOG_I("[%d] (%d %d %d %d)\n", touch_event, touchid, x, y, w );
  165. if (x >= touch->info.range_x || y >= touch->info.range_y)
  166. {
  167. LOG_E("invalid position, X[%d,%u,%d], Y[%d,%u,%d]\n",
  168. 0, x, touch->info.range_x,
  169. 0, y, touch->info.range_y);
  170. continue;
  171. }
  172. ft5446_touch_down(buf, touchid, x, y, w);
  173. }
  174. else
  175. {
  176. // Up
  177. ft5446_touch_up(buf, touchid);
  178. }
  179. } // for (i = 0; i < sFtRegMap.u8TDStatus; i++)
  180. pre_touch = sFtRegMap.u8TDStatus;
  181. return read_num;
  182. exit_read_point:
  183. pre_touch = 0;
  184. return 0;
  185. }
  186. static rt_err_t ft5446_control(struct rt_touch_device *touch, int cmd, void *arg)
  187. {
  188. switch (cmd)
  189. {
  190. case RT_TOUCH_CTRL_GET_INFO:
  191. {
  192. struct rt_touch_info *info = (struct rt_touch_info *)arg;
  193. RT_ASSERT(arg);
  194. rt_memcpy(info, &touch->info, sizeof(struct rt_touch_info));
  195. break;
  196. }
  197. case RT_TOUCH_CTRL_GET_ID:
  198. break;
  199. case RT_TOUCH_CTRL_SET_X_RANGE:
  200. break;
  201. case RT_TOUCH_CTRL_SET_Y_RANGE:
  202. break;
  203. case RT_TOUCH_CTRL_SET_X_TO_Y:
  204. break;
  205. case RT_TOUCH_CTRL_SET_MODE:
  206. break;
  207. default:
  208. break;
  209. }
  210. return RT_EOK;
  211. }
  212. static struct rt_touch_ops ft5446_touch_ops =
  213. {
  214. .touch_readpoint = ft5446_read_point,
  215. .touch_control = ft5446_control,
  216. };
  217. static void ft5446_init(struct rt_i2c_client *dev)
  218. {
  219. ft5446_write_reg(dev, 0x0, 0);
  220. }
  221. int rt_hw_ft5446_init(const char *name, struct rt_touch_config *cfg)
  222. {
  223. struct rt_touch_device *touch_device = RT_NULL;
  224. rt_uint32_t bus_speed = 400000;
  225. touch_device = (struct rt_touch_device *)rt_malloc(sizeof(struct rt_touch_device));
  226. if (touch_device == RT_NULL)
  227. {
  228. LOG_E("touch device malloc fail");
  229. return -RT_ERROR;
  230. }
  231. rt_memset((void *)touch_device, 0, sizeof(struct rt_touch_device));
  232. /* hw init*/
  233. rt_pin_mode(*(rt_uint8_t *)cfg->user_data, PIN_MODE_OUTPUT);
  234. rt_pin_write(*(rt_uint8_t *)cfg->user_data, PIN_LOW);
  235. rt_thread_delay(5);
  236. rt_pin_write(*(rt_uint8_t *)cfg->user_data, PIN_HIGH);
  237. rt_thread_delay(200);
  238. rt_pin_mode(cfg->irq_pin.pin, cfg->irq_pin.mode);
  239. ft5446_client.bus = (struct rt_i2c_bus_device *)rt_device_find(cfg->dev_name);
  240. if (ft5446_client.bus == RT_NULL)
  241. {
  242. LOG_E("Can't find %s device", cfg->dev_name);
  243. return -RT_ERROR;
  244. }
  245. if (rt_device_open((rt_device_t)ft5446_client.bus, RT_DEVICE_FLAG_RDWR) != RT_EOK)
  246. {
  247. LOG_E("open %s device failed", cfg->dev_name);
  248. return -RT_ERROR;
  249. }
  250. if (rt_device_control((rt_device_t)ft5446_client.bus, RT_I2C_DEV_CTRL_CLK, &bus_speed) != RT_EOK)
  251. {
  252. LOG_E("control %s device failed", cfg->dev_name);
  253. return -RT_ERROR;
  254. }
  255. ft5446_client.client_addr = FT5446_ADDRESS;
  256. ft5446_init(&ft5446_client);
  257. rt_memset(&pre_x[0], 0xff, FT_MAX_TOUCH * sizeof(int16_t));
  258. rt_memset(&pre_y[0], 0xff, FT_MAX_TOUCH * sizeof(int16_t));
  259. rt_memset(&pre_w[0], 0xff, FT_MAX_TOUCH * sizeof(int16_t));
  260. rt_memset(&s_tp_dowm[0], 0, FT_MAX_TOUCH * sizeof(int16_t));
  261. rt_memset(&pre_id[0], 0xff, FT_MAX_TOUCH * sizeof(int8_t));
  262. /* register touch device */
  263. touch_device->info.type = RT_TOUCH_TYPE_CAPACITANCE;
  264. touch_device->info.vendor = RT_TOUCH_VENDOR_FT;
  265. touch_device->info.range_x = BSP_LCD_WIDTH;
  266. touch_device->info.range_y = BSP_LCD_HEIGHT;
  267. touch_device->info.point_num = FT_MAX_TOUCH;
  268. rt_memcpy(&touch_device->config, cfg, sizeof(struct rt_touch_config));
  269. touch_device->ops = &ft5446_touch_ops;
  270. rt_hw_touch_register(touch_device, name, RT_DEVICE_FLAG_INT_RX, RT_NULL);
  271. LOG_I("touch device ft5446 init success");
  272. return RT_EOK;
  273. }