drv_touch_ft.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2017-08-08 Yang the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rthw.h>
  12. #include <rtdevice.h>
  13. #include "drv_touch.h"
  14. #include <string.h>
  15. #ifdef BSP_USING_TOUCH
  16. #define DBG_ENABLE
  17. #define DBG_SECTION_NAME "TOUCH.ft"
  18. #define DBG_LEVEL TOUCH_DBG_LEVEL
  19. #define DBG_COLOR
  20. #include <rtdbg.h>
  21. #ifdef TOUCH_IC_FT3X67
  22. #define CHIP_ID_REG 0xA8U
  23. #define CHIP_ID_VALUE 0x11U
  24. #define TOUCH_SLAVE_ADDR 0x38U
  25. #else
  26. #error "Please define at least one TOUCH DEVICE"
  27. /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
  28. #endif
  29. static struct rt_i2c_bus_device *ft_i2c_bus;
  30. static struct touch_drivers ft_driver;
  31. static int ft_read(struct rt_i2c_bus_device *i2c_bus, rt_uint8_t addr, rt_uint8_t *buffer, rt_size_t length)
  32. {
  33. int ret = -1;
  34. int retries = 0;
  35. struct rt_i2c_msg msgs[] =
  36. {
  37. {
  38. .addr = ft_driver.address,
  39. .flags = RT_I2C_WR,
  40. .len = 1,
  41. .buf = &addr,
  42. },
  43. {
  44. .addr = ft_driver.address,
  45. .flags = RT_I2C_RD,
  46. .len = length,
  47. .buf = buffer,
  48. },
  49. };
  50. while (retries < IIC_RETRY_NUM)
  51. {
  52. ret = rt_i2c_transfer(i2c_bus, msgs, 2);
  53. if (ret == 2)break;
  54. retries++;
  55. }
  56. if (retries >= IIC_RETRY_NUM)
  57. {
  58. LOG_E("%s i2c read error: %d", __func__, ret);
  59. return -1;
  60. }
  61. return ret;
  62. }
  63. static void ft_write(touch_drv_t driver, struct rt_i2c_bus_device *i2c_bus, rt_uint8_t addr, rt_uint8_t *buffer, rt_size_t length)
  64. {
  65. rt_uint8_t *send_buffer = rt_malloc(length + 1);
  66. RT_ASSERT(send_buffer);
  67. send_buffer[0] = addr;
  68. memcpy(send_buffer + 1, buffer, length);
  69. struct rt_i2c_msg msgs[] =
  70. {
  71. {
  72. .addr = ft_driver.address,
  73. .flags = RT_I2C_WR,
  74. .len = length + 1,
  75. .buf = send_buffer,
  76. }
  77. };
  78. length = rt_i2c_transfer(i2c_bus, msgs, 1);
  79. rt_free(send_buffer);
  80. send_buffer = RT_NULL;
  81. }
  82. static void ft_isr_enable(rt_bool_t enable)
  83. {
  84. rt_pin_irq_enable(BSP_TOUCH_INT_PIN, enable);
  85. }
  86. static void ft_touch_isr(void *parameter)
  87. {
  88. ft_isr_enable(RT_FALSE);
  89. rt_sem_release(ft_driver.isr_sem);
  90. }
  91. static rt_err_t ft_read_point(touch_msg_t msg)
  92. {
  93. int ret = -1;
  94. uint8_t point_num = 0;
  95. static uint8_t s_tp_down = 0;
  96. uint8_t point[6];
  97. ret = ft_read(ft_i2c_bus, 0x02, &point_num, 1);
  98. if (ret < 0)
  99. {
  100. return RT_ERROR;
  101. }
  102. if (point_num == 0)
  103. {
  104. if (s_tp_down)
  105. {
  106. s_tp_down = 0;
  107. msg->event = TOUCH_EVENT_UP;
  108. return RT_EOK;
  109. }
  110. msg->event = TOUCH_EVENT_NONE;
  111. return RT_ERROR;
  112. }
  113. ret = ft_read(ft_i2c_bus, 0x03, point, 6);
  114. if (ret < 0)
  115. {
  116. return RT_ERROR;
  117. }
  118. msg->y = (point[0]&0x0F) << 8 | point[1];
  119. msg->x = (point[2]&0x0F) << 8 | point[3];
  120. if (s_tp_down)
  121. {
  122. msg->event = TOUCH_EVENT_MOVE;
  123. return RT_EOK;
  124. }
  125. msg->event = TOUCH_EVENT_DOWN;
  126. s_tp_down = 1;
  127. return RT_EOK;
  128. }
  129. static void ft_init(struct rt_i2c_bus_device *i2c_bus)
  130. {
  131. if (ft_i2c_bus == RT_NULL)
  132. {
  133. ft_i2c_bus = i2c_bus;
  134. }
  135. ft_driver.isr_sem = rt_sem_create("ft", 0, RT_IPC_FLAG_FIFO);
  136. RT_ASSERT(ft_driver.isr_sem);
  137. rt_pin_mode(BSP_TOUCH_INT_PIN, PIN_MODE_INPUT_PULLUP);
  138. rt_pin_attach_irq(BSP_TOUCH_INT_PIN, PIN_IRQ_MODE_FALLING, ft_touch_isr, RT_NULL);
  139. rt_thread_mdelay(200);
  140. }
  141. static void ft_deinit(void)
  142. {
  143. if (ft_driver.isr_sem)
  144. {
  145. rt_sem_delete(ft_driver.isr_sem);
  146. ft_driver.isr_sem = RT_NULL;
  147. }
  148. }
  149. struct touch_ops ft_ops =
  150. {
  151. ft_isr_enable,
  152. ft_read_point,
  153. ft_init,
  154. ft_deinit,
  155. };
  156. static rt_bool_t ft_probe(struct rt_i2c_bus_device *i2c_bus)
  157. {
  158. int err = 0;
  159. uint8_t cid = 0xFF;
  160. ft_i2c_bus = i2c_bus;
  161. err = ft_read(ft_i2c_bus, CHIP_ID_REG, (uint8_t *)&cid, 1);
  162. if (err < 0)
  163. {
  164. LOG_E("%s failed: %d", __func__, err);
  165. return RT_FALSE;
  166. }
  167. LOG_I("touch CID:%02X", cid);
  168. if(cid == CHIP_ID_VALUE)
  169. {
  170. return RT_TRUE;
  171. }
  172. return RT_FALSE;
  173. }
  174. int ft_driver_register(void)
  175. {
  176. ft_driver.address = TOUCH_SLAVE_ADDR;
  177. ft_driver.probe = ft_probe;
  178. ft_driver.ops = &ft_ops;
  179. ft_driver.user_data = RT_NULL;
  180. rt_touch_drivers_register(&ft_driver);
  181. return 0;
  182. }
  183. INIT_DEVICE_EXPORT(ft_driver_register);
  184. #endif