drv_touch.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  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. * 2021-01-13 RiceChen the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <string.h>
  13. #include <time.h>
  14. #define DBG_TAG "gt911"
  15. #define DBG_LVL DBG_INFO
  16. #include <rtdbg.h>
  17. #include "drv_touch.h"
  18. #define GET_PIN(PORTx, PIN) (32 * (PORTx - 1) + (PIN & 31))
  19. #define IRQ_PIN GET_PIN(1, 5)
  20. #define RST_PIN GET_PIN(5, 2)
  21. static struct rt_i2c_client gt911_client;
  22. /* hardware section */
  23. static rt_uint8_t GT911_CFG_TBL[] =
  24. {
  25. 0x6b, 0x00, 0x04, 0x58, 0x02, 0x05, 0x0d, 0x00, 0x01, 0x0f,
  26. 0x28, 0x0f, 0x50, 0x32, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00,
  27. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2a, 0x0c,
  28. 0x45, 0x47, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x40, 0x03, 0x2c,
  29. 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x64, 0x32, 0x00, 0x00,
  30. 0x00, 0x28, 0x64, 0x94, 0xd5, 0x02, 0x07, 0x00, 0x00, 0x04,
  31. 0x95, 0x2c, 0x00, 0x8b, 0x34, 0x00, 0x82, 0x3f, 0x00, 0x7d,
  32. 0x4c, 0x00, 0x7a, 0x5b, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00,
  33. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  34. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  35. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  36. 0x00, 0x00, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0e, 0x0c, 0x0a,
  37. 0x08, 0x06, 0x04, 0x02, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
  38. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  39. 0x00, 0x00, 0x16, 0x18, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
  40. 0x22, 0x24, 0x13, 0x12, 0x10, 0x0f, 0x0a, 0x08, 0x06, 0x04,
  41. 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
  42. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  43. 0x00, 0x00, 0x00, 0x00, 0x79, 0x01,
  44. };
  45. static rt_err_t gt911_write_reg(struct rt_i2c_client *dev, rt_uint8_t *data, rt_uint8_t len)
  46. {
  47. struct rt_i2c_msg msgs;
  48. msgs.addr = dev->client_addr;
  49. msgs.flags = RT_I2C_WR;
  50. msgs.buf = data;
  51. msgs.len = len;
  52. if (rt_i2c_transfer(dev->bus, &msgs, 1) == 1)
  53. {
  54. return RT_EOK;
  55. }
  56. else
  57. {
  58. return -RT_ERROR;
  59. }
  60. }
  61. static rt_err_t gt911_read_regs(struct rt_i2c_client *dev, rt_uint8_t *reg, rt_uint8_t *data, rt_uint8_t len)
  62. {
  63. struct rt_i2c_msg msgs[2];
  64. msgs[0].addr = dev->client_addr;
  65. msgs[0].flags = RT_I2C_WR;
  66. msgs[0].buf = reg;
  67. msgs[0].len = GT911_REGITER_LEN;
  68. msgs[1].addr = dev->client_addr;
  69. msgs[1].flags = RT_I2C_RD;
  70. msgs[1].buf = data;
  71. msgs[1].len = len;
  72. if (rt_i2c_transfer(dev->bus, msgs, 2) == 2)
  73. {
  74. return RT_EOK;
  75. }
  76. else
  77. {
  78. return -RT_ERROR;
  79. }
  80. }
  81. static rt_err_t gt911_get_product_id(struct rt_i2c_client *dev, rt_uint8_t *data, rt_uint8_t len)
  82. {
  83. rt_uint8_t reg[2];
  84. reg[0] = (rt_uint8_t)(GT911_PRODUCT_ID >> 8);
  85. reg[1] = (rt_uint8_t)(GT911_PRODUCT_ID & 0xff);
  86. if (gt911_read_regs(dev, reg, data, len) != RT_EOK)
  87. {
  88. LOG_E("read id failed");
  89. return -RT_ERROR;
  90. }
  91. return RT_EOK;
  92. }
  93. static rt_err_t gt911_get_info(struct rt_i2c_client *dev, struct rt_touch_info *info)
  94. {
  95. rt_uint8_t reg[2];
  96. rt_uint8_t out_info[7];
  97. rt_uint8_t out_len = 7;
  98. reg[0] = (rt_uint8_t)(GT911_CONFIG_REG >> 8);
  99. reg[1] = (rt_uint8_t)(GT911_CONFIG_REG & 0xFF);
  100. if(gt911_read_regs(dev, reg, out_info, out_len) != RT_EOK)
  101. {
  102. LOG_E("read info failed");
  103. return -RT_ERROR;
  104. }
  105. info->range_x = (out_info[2] << 8) | out_info[1];
  106. info->range_y = (out_info[4] << 8) | out_info[3];
  107. info->point_num = out_info[5] & 0x0f;
  108. return RT_EOK;
  109. }
  110. static rt_err_t gt911_soft_reset(struct rt_i2c_client *dev)
  111. {
  112. rt_uint8_t buf[3];
  113. buf[0] = (rt_uint8_t)(GT911_COMMAND_REG >> 8);
  114. buf[1] = (rt_uint8_t)(GT911_COMMAND_REG & 0xFF);
  115. buf[2] = 0x02;
  116. if(gt911_write_reg(dev, buf, 3) != RT_EOK)
  117. {
  118. LOG_E("soft reset failed");
  119. return -RT_ERROR;
  120. }
  121. return RT_EOK;
  122. }
  123. static int16_t pre_x[GT911_MAX_TOUCH] = {-1, -1, -1, -1, -1};
  124. static int16_t pre_y[GT911_MAX_TOUCH] = {-1, -1, -1, -1, -1};
  125. static int16_t pre_w[GT911_MAX_TOUCH] = {-1, -1, -1, -1, -1};
  126. static rt_uint8_t s_tp_dowm[GT911_MAX_TOUCH];
  127. static struct rt_touch_data *read_data;
  128. static void gt911_touch_up(void *buf, int8_t id)
  129. {
  130. read_data = (struct rt_touch_data *)buf;
  131. if(s_tp_dowm[id] == 1)
  132. {
  133. s_tp_dowm[id] = 0;
  134. read_data[id].event = RT_TOUCH_EVENT_UP;
  135. }
  136. else
  137. {
  138. read_data[id].event = RT_TOUCH_EVENT_NONE;
  139. }
  140. read_data[id].timestamp = rt_touch_get_ts();
  141. read_data[id].width = pre_w[id];
  142. read_data[id].x_coordinate = pre_x[id];
  143. read_data[id].y_coordinate = pre_y[id];
  144. read_data[id].track_id = id;
  145. pre_x[id] = -1; /* last point is none */
  146. pre_y[id] = -1;
  147. pre_w[id] = -1;
  148. }
  149. static void gt911_touch_down(void *buf, int8_t id, int16_t x, int16_t y, int16_t w)
  150. {
  151. read_data = (struct rt_touch_data *)buf;
  152. if (s_tp_dowm[id] == 1)
  153. {
  154. read_data[id].event = RT_TOUCH_EVENT_MOVE;
  155. }
  156. else
  157. {
  158. read_data[id].event = RT_TOUCH_EVENT_DOWN;
  159. s_tp_dowm[id] = 1;
  160. }
  161. read_data[id].timestamp = rt_touch_get_ts();
  162. read_data[id].width = w;
  163. read_data[id].x_coordinate = x;
  164. read_data[id].y_coordinate = y;
  165. read_data[id].track_id = id;
  166. pre_x[id] = x; /* save last point */
  167. pre_y[id] = y;
  168. pre_w[id] = w;
  169. }
  170. static rt_size_t gt911_read_point(struct rt_touch_device *touch, void *buf, rt_size_t read_num)
  171. {
  172. rt_uint8_t point_status = 0;
  173. rt_uint8_t touch_num = 0;
  174. rt_uint8_t write_buf[3];
  175. rt_uint8_t cmd[2];
  176. rt_uint8_t read_buf[8 * GT911_MAX_TOUCH] = {0};
  177. rt_uint8_t read_index;
  178. int8_t read_id = 0;
  179. int16_t input_x = 0;
  180. int16_t input_y = 0;
  181. int16_t input_w = 0;
  182. static rt_uint8_t pre_touch = 0;
  183. static int8_t pre_id[GT911_MAX_TOUCH] = {0};
  184. /* point status register */
  185. cmd[0] = (rt_uint8_t)((GT911_READ_STATUS >> 8) & 0xFF);
  186. cmd[1] = (rt_uint8_t)(GT911_READ_STATUS & 0xFF);
  187. if (gt911_read_regs(&gt911_client, cmd, &point_status, 1) != RT_EOK)
  188. {
  189. LOG_D("read point failed\n");
  190. read_num = 0;
  191. goto exit_;
  192. }
  193. if (point_status == 0) /* no data */
  194. {
  195. read_num = 0;
  196. goto exit_;
  197. }
  198. if ((point_status & 0x80) == 0) /* data is not ready */
  199. {
  200. read_num = 0;
  201. goto exit_;
  202. }
  203. touch_num = point_status & 0x0f; /* get point num */
  204. if (touch_num > GT911_MAX_TOUCH) /* point num is not correct */
  205. {
  206. read_num = 0;
  207. goto exit_;
  208. }
  209. cmd[0] = (rt_uint8_t)((GT911_POINT1_REG >> 8) & 0xFF);
  210. cmd[1] = (rt_uint8_t)(GT911_POINT1_REG & 0xFF);
  211. /* read point num is touch_num */
  212. if(gt911_read_regs(&gt911_client, cmd, read_buf, read_num * GT911_POINT_INFO_NUM) !=RT_EOK)
  213. {
  214. LOG_D("read point failed\n");
  215. read_num = 0;
  216. goto exit_;
  217. }
  218. if(pre_touch > touch_num) /* point up */
  219. {
  220. for (read_index = 0; read_index < pre_touch; read_index++)
  221. {
  222. rt_uint8_t j;
  223. for (j = 0; j < touch_num; j++) /* this time touch num */
  224. {
  225. read_id = read_buf[j * 8] & 0x0F;
  226. if (pre_id[read_index] == read_id) /* this id is not free */
  227. {
  228. break;
  229. }
  230. if (j >= touch_num - 1)
  231. {
  232. rt_uint8_t up_id;
  233. up_id = pre_id[read_index];
  234. gt911_touch_up(buf, up_id);
  235. }
  236. }
  237. }
  238. }
  239. if(touch_num) /* point down */
  240. {
  241. rt_uint8_t off_set;
  242. for(read_index = 0; read_index < touch_num; read_index++)
  243. {
  244. off_set = read_index * 8;
  245. read_id = read_buf[off_set] & 0x0f;
  246. pre_id[read_index] = read_id;
  247. input_x = read_buf[off_set + 1] | (read_buf[off_set + 2] << 8); /* x */
  248. input_y = read_buf[off_set + 3] | (read_buf[off_set + 4] << 8); /* y */
  249. input_w = read_buf[off_set + 5] | (read_buf[off_set + 6] << 8); /* size */
  250. gt911_touch_down(buf, read_id, input_x, input_y, input_w);
  251. }
  252. }
  253. else if (pre_touch)
  254. {
  255. for(read_index = 0; read_index < pre_touch; read_index++)
  256. {
  257. gt911_touch_up(buf, pre_id[read_index]);
  258. }
  259. }
  260. pre_touch = touch_num;
  261. exit_:
  262. write_buf[0] = (rt_uint8_t)((GT911_READ_STATUS >> 8) & 0xFF);
  263. write_buf[1] = (rt_uint8_t)(GT911_READ_STATUS & 0xFF);
  264. write_buf[2] = 0x00;
  265. gt911_write_reg(&gt911_client, write_buf, 3);
  266. return read_num;
  267. }
  268. static rt_err_t gt911_control(struct rt_touch_device *touch, int cmd, void *arg)
  269. {
  270. if (cmd == RT_TOUCH_CTRL_GET_ID)
  271. {
  272. return gt911_get_product_id(&gt911_client, arg, 6);
  273. }
  274. if (cmd == RT_TOUCH_CTRL_GET_INFO)
  275. {
  276. return gt911_get_info(&gt911_client, arg);
  277. }
  278. rt_uint8_t buf[4];
  279. rt_uint8_t i = 0;
  280. rt_uint8_t *config = RT_NULL;
  281. config = (rt_uint8_t *)rt_calloc(1, sizeof(GT911_CFG_TBL) + GT911_REGITER_LEN);
  282. if(config == RT_NULL)
  283. {
  284. LOG_D("malloc config memory failed\n");
  285. return -RT_ERROR;
  286. }
  287. config[0] = (rt_uint8_t)((GT911_CONFIG_REG >> 8) & 0xFF);
  288. config[1] = (rt_uint8_t)(GT911_CONFIG_REG & 0xFF);
  289. memcpy(&config[2], GT911_CFG_TBL, sizeof(GT911_CFG_TBL));
  290. switch(cmd)
  291. {
  292. case RT_TOUCH_CTRL_SET_X_RANGE:
  293. {
  294. rt_uint16_t x_range;
  295. x_range = *(rt_uint16_t *)arg;
  296. config[4] = (rt_uint8_t)(x_range >> 8);
  297. config[3] = (rt_uint8_t)(x_range & 0xff);
  298. GT911_CFG_TBL[2] = config[4];
  299. GT911_CFG_TBL[1] = config[3];
  300. break;
  301. }
  302. case RT_TOUCH_CTRL_SET_Y_RANGE:
  303. {
  304. rt_uint16_t y_range;
  305. y_range = *(rt_uint16_t *)arg;
  306. config[6] = (rt_uint8_t)(y_range >> 8);
  307. config[5] = (rt_uint8_t)(y_range & 0xff);
  308. GT911_CFG_TBL[4] = config[6];
  309. GT911_CFG_TBL[3] = config[5];
  310. break;
  311. }
  312. case RT_TOUCH_CTRL_SET_X_TO_Y:
  313. {
  314. config[8] ^= (1 << 3);
  315. break;
  316. }
  317. case RT_TOUCH_CTRL_SET_MODE:
  318. {
  319. rt_uint16_t trig_type;
  320. trig_type = *(rt_uint16_t *)arg;
  321. switch (trig_type)
  322. {
  323. case RT_DEVICE_FLAG_INT_RX:
  324. config[8] &= 0xFC;
  325. break;
  326. case RT_DEVICE_FLAG_RDONLY:
  327. config[8] &= 0xFC;
  328. config[8] |= 0x02;
  329. break;
  330. default:
  331. break;
  332. }
  333. break;
  334. }
  335. default:
  336. {
  337. break;
  338. }
  339. }
  340. if(gt911_write_reg(&gt911_client, config, sizeof(GT911_CFG_TBL) + GT911_ADDR_LEN) != RT_EOK)
  341. {
  342. LOG_D("send config failed");
  343. return -1;
  344. }
  345. buf[0] = (rt_uint8_t)((GT911_CHECK_SUM >> 8) & 0xFF);
  346. buf[1] = (rt_uint8_t)(GT911_CHECK_SUM & 0xFF);
  347. buf[2] = 0;
  348. for(i = GT911_ADDR_LEN; i < sizeof(GT911_CFG_TBL) + GT911_ADDR_LEN; i++)
  349. {
  350. buf[GT911_ADDR_LEN] += config[i];
  351. }
  352. buf[2] = (~buf[2]) + 1;
  353. buf[3] = 1;
  354. gt911_write_reg(&gt911_client, buf, 4);
  355. rt_free(config);
  356. return RT_EOK;
  357. }
  358. static struct rt_touch_ops gt911_touch_ops =
  359. {
  360. .touch_readpoint = gt911_read_point,
  361. .touch_control = gt911_control,
  362. };
  363. int rt_hw_gt911_init(const char *name, struct rt_touch_config *cfg)
  364. {
  365. struct rt_touch_device *touch_device = RT_NULL;
  366. touch_device = (struct rt_touch_device *)rt_malloc(sizeof(struct rt_touch_device));
  367. if(touch_device == RT_NULL)
  368. {
  369. LOG_E("touch device malloc fail");
  370. return -RT_ERROR;
  371. }
  372. rt_memset((void *)touch_device, 0, sizeof(struct rt_touch_device));
  373. /* hw init*/
  374. rt_pin_mode(*(rt_uint8_t *)cfg->user_data, PIN_MODE_OUTPUT);
  375. rt_pin_mode(cfg->irq_pin.pin, PIN_MODE_OUTPUT);
  376. rt_pin_write(*(rt_uint8_t *)cfg->user_data, PIN_LOW);
  377. rt_thread_delay(10);
  378. rt_pin_write(*(rt_uint8_t *)cfg->user_data, PIN_HIGH);
  379. rt_thread_delay(10);
  380. rt_pin_write(cfg->irq_pin.pin, PIN_MODE_INPUT);
  381. rt_thread_delay(100);
  382. gt911_client.bus = (struct rt_i2c_bus_device *)rt_device_find(cfg->dev_name);
  383. if(gt911_client.bus == RT_NULL)
  384. {
  385. LOG_E("Can't find %s device", cfg->dev_name);
  386. return -RT_ERROR;
  387. }
  388. if(rt_device_open((rt_device_t)gt911_client.bus, RT_DEVICE_FLAG_RDWR) != RT_EOK)
  389. {
  390. LOG_E("open %s device failed", cfg->dev_name);
  391. return -RT_ERROR;
  392. }
  393. gt911_client.client_addr = GT911_ADDRESS_HIGH;
  394. gt911_soft_reset(&gt911_client);
  395. /* register touch device */
  396. touch_device->info.type = RT_TOUCH_TYPE_CAPACITANCE;
  397. touch_device->info.vendor = RT_TOUCH_VENDOR_GT;
  398. rt_memcpy(&touch_device->config, cfg, sizeof(struct rt_touch_config));
  399. touch_device->ops = &gt911_touch_ops;
  400. rt_hw_touch_register(touch_device, name, RT_DEVICE_FLAG_INT_RX, RT_NULL);
  401. LOG_I("touch device gt911 init success");
  402. return RT_EOK;
  403. }
  404. int gt911_init(void)
  405. {
  406. struct rt_touch_config cfg;
  407. rt_uint8_t rst_pin;
  408. rst_pin = RST_PIN;
  409. cfg.dev_name = "i2c3";
  410. cfg.irq_pin.pin = IRQ_PIN;
  411. cfg.irq_pin.mode = PIN_MODE_INPUT_PULLDOWN;
  412. cfg.user_data = &rst_pin;
  413. rt_hw_gt911_init("gt911", &cfg);
  414. return RT_EOK;
  415. }
  416. INIT_DEVICE_EXPORT(gt911_init);