drv_touch_ft5x06.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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. * 2018-10-29 XY
  10. */
  11. #include <rthw.h>
  12. #include <rtthread.h>
  13. #include <rtdevice.h>
  14. #include "drv_touch.h"
  15. #include "fsl_iomuxc.h"
  16. #include "fsl_gpio.h"
  17. #define TP_INT_PIN 54 /* GPIO_AD_B0_11 */
  18. #define TP_RST_PIN 45 /* GPIO_AD_B0_02 */
  19. #define FT5x06_TS_ADDR (0x38)
  20. #if 0
  21. #define TPDEBUG rt_kprintf
  22. #else
  23. #define TPDEBUG(...)
  24. #endif
  25. static struct touch_driver ft5x06_driver;
  26. typedef enum _touch_event
  27. {
  28. kTouch_Down = 0, /*!< The state changed to touched. */
  29. kTouch_Up = 1, /*!< The state changed to not touched. */
  30. kTouch_Contact = 2, /*!< There is a continuous touch being detected. */
  31. kTouch_Reserved = 3 /*!< No touch information available. */
  32. } touch_event_t;
  33. typedef struct _touch_point
  34. {
  35. touch_event_t TOUCH_EVENT; /*!< Indicates the state or event of the touch point. */
  36. uint8_t TOUCH_ID; /*!< Id of the touch point. This numeric value stays constant between down and up event. */
  37. uint16_t TOUCH_X; /*!< X coordinate of the touch point */
  38. uint16_t TOUCH_Y; /*!< Y coordinate of the touch point */
  39. } touch_point_t;
  40. typedef struct _ft5406_touch_point
  41. {
  42. uint8_t XH;
  43. uint8_t XL;
  44. uint8_t YH;
  45. uint8_t YL;
  46. uint8_t RESERVED[2];
  47. } ft5406_touch_point_t;
  48. typedef struct _ft5406_touch_data
  49. {
  50. uint8_t DEVIDE_MODE;
  51. uint8_t GEST_ID;
  52. uint8_t TD_STATUS;
  53. ft5406_touch_point_t TOUCH;
  54. } ft5406_touch_data_t;
  55. #define TOUCH_POINT_GET_EVENT(T) ((touch_event_t)((T).XH >> 6))
  56. #define TOUCH_POINT_GET_ID(T) ((T).YH >> 4)
  57. #define TOUCH_POINT_GET_X(T) ((((T).XH & 0x0f) << 8) | (T).XL)
  58. #define TOUCH_POINT_GET_Y(T) ((((T).YH & 0x0f) << 8) | (T).YL)
  59. static int ft5406_read_touch(touch_point_t *dp)
  60. {
  61. rt_uint8_t cmd = 0;
  62. ft5406_touch_data_t touch_data;
  63. if (rt_touch_read(FT5x06_TS_ADDR, &cmd, 1, &touch_data, sizeof(ft5406_touch_data_t)) != 0)
  64. return -1;
  65. dp->TOUCH_X = TOUCH_POINT_GET_Y(touch_data.TOUCH);
  66. dp->TOUCH_Y = TOUCH_POINT_GET_X(touch_data.TOUCH);
  67. dp->TOUCH_EVENT = TOUCH_POINT_GET_EVENT(touch_data.TOUCH);
  68. dp->TOUCH_ID = TOUCH_POINT_GET_ID(touch_data.TOUCH);
  69. if (dp->TOUCH_EVENT == 3) return -1;
  70. if (touch_data.TD_STATUS != 0)
  71. return 0;
  72. else
  73. return -1;
  74. }
  75. static void ft5x06_isr_enable(rt_bool_t enable)
  76. {
  77. if(enable == RT_TRUE)
  78. {
  79. rt_pin_irq_enable(TP_INT_PIN, PIN_IRQ_ENABLE);
  80. }
  81. else
  82. {
  83. rt_pin_irq_enable(TP_INT_PIN, PIN_IRQ_DISABLE);
  84. }
  85. }
  86. static void ft5x06_touch_isr(void *parameter)
  87. {
  88. TPDEBUG("[TP] ft5x06_touch_isr\n");
  89. ft5x06_isr_enable(RT_FALSE);
  90. rt_sem_release(ft5x06_driver.isr_sem);
  91. }
  92. static rt_err_t ft5x06_read_point(touch_message_t msg)
  93. {
  94. touch_point_t dp;
  95. if (ft5406_read_touch(&dp) != 0)
  96. {
  97. msg->event = TOUCH_EVENT_UP;
  98. }
  99. else
  100. {
  101. if (dp.TOUCH_EVENT == kTouch_Up)
  102. {
  103. msg->event = TOUCH_EVENT_UP;
  104. }
  105. else if (dp.TOUCH_EVENT == kTouch_Down)
  106. {
  107. msg->event = TOUCH_EVENT_DOWN;
  108. }
  109. else if (dp.TOUCH_EVENT == kTouch_Contact)
  110. {
  111. msg->event = TOUCH_EVENT_MOVE;
  112. }
  113. else
  114. {
  115. msg->event = TOUCH_EVENT_UP;
  116. }
  117. }
  118. msg->x = dp.TOUCH_X;
  119. msg->y = dp.TOUCH_Y;
  120. TPDEBUG("[TP] [%d, %d] %s\n", msg->x, msg->y,
  121. msg->event == TOUCH_EVENT_DOWN ? "DOWN" : (msg->event == TOUCH_EVENT_MOVE ? "MOVE" : (msg->event == TOUCH_EVENT_UP ? "UP" : "NONE")));
  122. if (msg->event != TOUCH_EVENT_UP)
  123. {
  124. rt_sem_release(ft5x06_driver.isr_sem);
  125. }
  126. else
  127. {
  128. ft5x06_isr_enable(RT_TRUE);
  129. }
  130. return RT_EOK;
  131. }
  132. static void ft5x06_init(struct rt_i2c_bus_device *i2c_bus)
  133. {
  134. ft5x06_driver.isr_sem = rt_sem_create("ft5x06", 0, RT_IPC_FLAG_FIFO);
  135. RT_ASSERT(ft5x06_driver.isr_sem);
  136. rt_pin_attach_irq(TP_INT_PIN, PIN_IRQ_MODE_LOW_LEVEL, ft5x06_touch_isr, &ft5x06_driver);
  137. rt_pin_irq_enable(TP_INT_PIN, PIN_IRQ_ENABLE);
  138. rt_thread_delay(RT_TICK_PER_SECOND / 5);
  139. }
  140. static void ft5x06_deinit(void)
  141. {
  142. if (ft5x06_driver.isr_sem)
  143. {
  144. rt_sem_delete(ft5x06_driver.isr_sem);
  145. ft5x06_driver.isr_sem = RT_NULL;
  146. }
  147. }
  148. struct touch_ops ft5x06_ops =
  149. {
  150. ft5x06_init,
  151. ft5x06_deinit,
  152. ft5x06_read_point,
  153. };
  154. static void ft5406_hw_reset(void)
  155. {
  156. gpio_pin_config_t pin_config =
  157. {
  158. kGPIO_DigitalOutput, 0,
  159. };
  160. CLOCK_EnableClock(kCLOCK_Gpio1);
  161. IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, 0U);
  162. IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, 0x10B0u);
  163. /* Enable touch panel controller */
  164. GPIO_PinInit(GPIO1, 2, &pin_config);
  165. GPIO_WritePinOutput(GPIO1, 2, 1);
  166. rt_thread_delay(RT_TICK_PER_SECOND / 20);
  167. GPIO_WritePinOutput(GPIO1, 2, 0);
  168. rt_thread_delay(RT_TICK_PER_SECOND / 20);
  169. GPIO_WritePinOutput(GPIO1, 2, 1);
  170. }
  171. static rt_bool_t ft5x06_probe(struct rt_i2c_bus_device *i2c_bus)
  172. {
  173. rt_uint16_t cmd = 0x000c;
  174. rt_uint16_t tmp[2];
  175. rt_uint16_t CurVersion;
  176. ft5406_hw_reset();
  177. if (rt_touch_read(FT5x06_TS_ADDR, &cmd, 2, tmp, 2) != 0)
  178. {
  179. TPDEBUG("[TP] %s failed!\n", __func__);
  180. return RT_FALSE;
  181. }
  182. CurVersion = (tmp[0]<<8) | tmp[1];
  183. rt_kprintf("[TP] FT5X06 Touch Version : %d\n", CurVersion);
  184. return RT_TRUE;
  185. }
  186. int ft5x06_driver_register(void)
  187. {
  188. ft5x06_driver.probe = ft5x06_probe;
  189. ft5x06_driver.ops = &ft5x06_ops;
  190. ft5x06_driver.user_data = RT_NULL;
  191. rt_touch_drivers_register(&ft5x06_driver);
  192. return 0;
  193. }
  194. INIT_ENV_EXPORT(ft5x06_driver_register);