drv_ft5x06.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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. * 2017-08-08 Yang the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #ifdef RT_USING_FINSH
  13. #include <finsh.h>
  14. #endif
  15. #ifdef RT_USING_RTGUI
  16. #include <rtgui/event.h>
  17. #include <rtgui/rtgui_server.h>
  18. #endif
  19. #include "board.h"
  20. #define BSP_TOUCH_SAMPLE_HZ 30
  21. #define I2CBUS_NAME "i2c0"
  22. #define FT5x06_TS_ADDR 0x38
  23. #define TP_MAX_TOUCH_POINT 5
  24. #define DEBUG
  25. #ifdef DEBUG
  26. #define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__)
  27. #else
  28. #define DEBUG_PRINTF(...)
  29. #endif
  30. #define CTRL_NOAUTO_MONITOR 0x00
  31. #define CTRL_AUTO_MONITOR 0x01
  32. #define PMODE_ACTIVE 0x00
  33. #define PMODE_MONITOR 0x01
  34. #define PMODE_STANDBY 0x02
  35. #define PMODE_HIBERNATE 0x03
  36. #define G_MODE_POLLING 0x00
  37. #define G_MODE_TRIGGER 0x01
  38. #define TOUCH_POINT_GET_EVENT(T) ((touch_event_t)((T).XH >> 6))
  39. #define TOUCH_POINT_GET_ID(T) ((T).YH >> 4)
  40. #define TOUCH_POINT_GET_X(T) ((((T).XH & 0x0f) << 8) | (T).XL)
  41. #define TOUCH_POINT_GET_Y(T) ((((T).YH & 0x0f) << 8) | (T).YL)
  42. typedef enum _touch_event
  43. {
  44. kTouch_Down = 0, /*!< The state changed to touched. */
  45. kTouch_Up = 1, /*!< The state changed to not touched. */
  46. kTouch_Contact = 2, /*!< There is a continuous touch being detected. */
  47. kTouch_Reserved = 3 /*!< No touch information available. */
  48. } touch_event_t;
  49. typedef struct _touch_point
  50. {
  51. touch_event_t TOUCH_EVENT; /*!< Indicates the state or event of the touch point. */
  52. uint8_t TOUCH_ID; /*!< Id of the touch point. This numeric value stays constant between down and up event. */
  53. uint16_t TOUCH_X; /*!< X coordinate of the touch point */
  54. uint16_t TOUCH_Y; /*!< Y coordinate of the touch point */
  55. } touch_point_t;
  56. typedef struct _ft5x06_touch_point
  57. {
  58. uint8_t XH;
  59. uint8_t XL;
  60. uint8_t YH;
  61. uint8_t YL;
  62. } ft5x06_touch_point_t;
  63. typedef struct _ft5x06_touch_data
  64. {
  65. uint8_t DEVIDE_MODE;
  66. uint8_t GEST_ID;
  67. uint8_t TD_STATUS;
  68. ft5x06_touch_point_t TOUCH;
  69. } ft5x06_touch_data_t;
  70. static struct rt_i2c_bus_device *_i2c_bus;
  71. static int _ft5x06_read(unsigned char cmd,
  72. void *buf,
  73. size_t len)
  74. {
  75. struct rt_i2c_msg msgs[2];
  76. msgs[0].addr = FT5x06_TS_ADDR;
  77. msgs[0].flags = RT_I2C_WR;
  78. msgs[0].buf = &cmd;
  79. msgs[0].len = sizeof(cmd);
  80. msgs[1].addr = FT5x06_TS_ADDR;
  81. msgs[1].flags = RT_I2C_RD;
  82. msgs[1].buf = buf;
  83. msgs[1].len = len;
  84. if (rt_i2c_transfer(_i2c_bus, msgs, 2) == 2)
  85. return len;
  86. else
  87. return -1;
  88. }
  89. #ifdef RT_USING_FINSH
  90. static int search_ft5x06(void)
  91. {
  92. struct rt_i2c_msg msgs[2];
  93. uint8_t cmd = 0xA3;
  94. uint8_t buf = 0;
  95. msgs[0].flags = RT_I2C_WR;
  96. msgs[0].buf = &cmd;
  97. msgs[0].len = sizeof(cmd);
  98. msgs[1].flags = RT_I2C_RD;
  99. msgs[1].buf = &buf;
  100. msgs[1].len = 1;
  101. for (int i = 0; i <= 0x7f; i++)
  102. {
  103. int len;
  104. msgs[0].addr = i;
  105. msgs[1].addr = i;
  106. len = rt_i2c_transfer(_i2c_bus, msgs, 2);
  107. if (len == 2)
  108. {
  109. rt_kprintf("add:%02X transfer success, id: %02X\n", i, buf);
  110. }
  111. }
  112. return 0;
  113. }
  114. FINSH_FUNCTION_EXPORT_ALIAS(search_ft5x06, sft, search ft5x06 chip);
  115. static int ft5x06_dump(void)
  116. {
  117. uint8_t i;
  118. uint8_t reg_value;
  119. DEBUG_PRINTF("[FTS] Touch Chip\r\n");
  120. for (i = 0; i < UINT8_MAX; i++)
  121. {
  122. _ft5x06_read(i, &reg_value, 1);
  123. if (i % 8 == 7)
  124. DEBUG_PRINTF("0x%02X = 0x%02X\r\n", i, reg_value);
  125. else
  126. DEBUG_PRINTF("0x%02X = 0x%02X ", i, reg_value);
  127. }
  128. DEBUG_PRINTF("\n");
  129. return 0;
  130. }
  131. FINSH_FUNCTION_EXPORT_ALIAS(ft5x06_dump, ftdump, ft5x06 dump registers);
  132. #endif
  133. static int ft5x06_read_touch(touch_point_t *dp)
  134. {
  135. #if 0
  136. uint8_t data[33];
  137. int i;
  138. _ft5x06_read(0, data, sizeof(data));
  139. for (i = 0; i < sizeof(data)/sizeof(data[0]); i++)
  140. {
  141. DEBUG_PRINTF("%02X ", data[i]);
  142. }
  143. DEBUG_PRINTF("\n");
  144. return -1;
  145. #else
  146. ft5x06_touch_data_t touch_data;
  147. _ft5x06_read(0, &touch_data, sizeof(ft5x06_touch_data_t));
  148. dp->TOUCH_X = TOUCH_POINT_GET_Y(touch_data.TOUCH);
  149. dp->TOUCH_Y = TOUCH_POINT_GET_X(touch_data.TOUCH);
  150. DEBUG_PRINTF(" ==> status : %d (%d, %d)\n", touch_data.TD_STATUS, dp->TOUCH_X, dp->TOUCH_Y);
  151. if (touch_data.TD_STATUS != 0)
  152. return 0;
  153. else
  154. return -1;
  155. #endif
  156. }
  157. static void _touch_session()
  158. {
  159. touch_point_t tpd;
  160. #ifdef RT_USING_RTGUI
  161. struct rtgui_event_mouse emouse;
  162. #endif
  163. ft5x06_read_touch(&tpd);
  164. #ifdef RT_USING_RTGUI
  165. emouse.parent.sender = RT_NULL;
  166. emouse.wid = RT_NULL;
  167. emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
  168. emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN;
  169. emouse.x = tpd.TOUCH_X;
  170. emouse.y = tpd.TOUCH_Y;
  171. emouse.ts = rt_tick_get();
  172. emouse.id = emouse.ts;
  173. if (emouse.id == 0) emouse.id = 1;
  174. rtgui_server_post_event(&emouse.parent, sizeof(emouse));
  175. #endif
  176. do
  177. {
  178. rt_thread_delay(RT_TICK_PER_SECOND / BSP_TOUCH_SAMPLE_HZ);
  179. if (ft5x06_read_touch(&tpd) != 0)
  180. break;
  181. #ifdef RT_USING_RTGUI
  182. emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION;
  183. emouse.x = tpd.TOUCH_X;
  184. emouse.y = tpd.TOUCH_Y;
  185. emouse.ts = rt_tick_get();
  186. rtgui_server_post_event(&emouse.parent, sizeof(emouse));
  187. #endif
  188. }
  189. while (1);
  190. #ifdef RT_USING_RTGUI
  191. /* Always send touch up event. */
  192. emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
  193. emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP;
  194. emouse.x = tpd.TOUCH_X;
  195. emouse.y = tpd.TOUCH_Y;
  196. emouse.ts = rt_tick_get();
  197. rtgui_server_post_event(&emouse.parent, sizeof(emouse));
  198. #endif
  199. }
  200. static void touch_entry(void *p)
  201. {
  202. GPIO_InitTypeDef GPIO_InitStruct;
  203. __HAL_RCC_GPIOH_CLK_ENABLE();
  204. /*Configure GPIO pin : PH7 */
  205. GPIO_InitStruct.Pin = GPIO_PIN_7;
  206. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  207. GPIO_InitStruct.Pull = GPIO_NOPULL;
  208. GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  209. HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
  210. while(1)
  211. {
  212. rt_thread_delay(RT_TICK_PER_SECOND / 60);
  213. if (HAL_GPIO_ReadPin(GPIOH, GPIO_PIN_7) == GPIO_PIN_RESET)
  214. {
  215. _touch_session();
  216. }
  217. else
  218. continue;
  219. }
  220. }
  221. int ft5x06_hw_init(void)
  222. {
  223. rt_thread_t tid;
  224. rt_device_t dev;
  225. dev = rt_device_find(I2CBUS_NAME);
  226. if (!dev)
  227. {
  228. DEBUG_PRINTF("search device failed: %s\n", I2CBUS_NAME);
  229. return -1;
  230. }
  231. if (rt_device_open(dev, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
  232. {
  233. DEBUG_PRINTF("open device failed: %s\n", I2CBUS_NAME);
  234. return -1;
  235. }
  236. DEBUG_PRINTF("ft5x06 set i2c bus to %s\n", I2CBUS_NAME);
  237. _i2c_bus = (struct rt_i2c_bus_device *)dev;
  238. tid = rt_thread_create("touch", touch_entry, RT_NULL, 2048, 10, 20);
  239. if (!tid)
  240. {
  241. rt_device_close(dev);
  242. return -1;
  243. }
  244. rt_thread_startup(tid);
  245. return 0;
  246. }
  247. INIT_APP_EXPORT(ft5x06_hw_init);