1
0

drv_xpt2046.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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. * 2020-11-08 bigmagic first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <touch.h>
  13. #include "drv_xpt2046.h"
  14. //http://www.lcdwiki.com/MHS-3.5inch_RPi_Display
  15. #define DBG_TAG "xpt2046"
  16. #define DBG_LVL DBG_INFO
  17. #include <rtdbg.h>
  18. //XPT2046
  19. #define READ_X (0xD0)
  20. #define READ_Y (0x90)
  21. #define TFT_WIDTH (320)
  22. #define TFT_HEIGHT (480)
  23. //freq
  24. #define TOUCH_SPI_MAX_FREQ (10*1000)
  25. #define TP_IRQ_PIN (17)
  26. #define TOUCH_DEVICE_NAME ("spi0.1")
  27. static struct rt_semaphore touch_ack;
  28. static rt_touch_t touch_device = RT_NULL;
  29. static rt_thread_t touch_tid = RT_NULL;
  30. #define TOUCH_THREAD_STACK_SIZE (1024)
  31. #define TOUCH_THREAD_PRIORITY (30)
  32. #define TOUCH_THREAD_TIMESLICE (10)
  33. rt_uint8_t touch_flag = 0;
  34. rt_uint16_t touch_x_val = 0;
  35. rt_uint16_t touch_y_val = 0;
  36. extern struct rt_semaphore lcd_spi_lock;
  37. static void touch_read_x_y(void *dev, rt_uint16_t *x, rt_uint16_t *y)
  38. {
  39. struct rt_spi_device *touch_dev = (struct rt_spi_device *)dev;
  40. struct rt_spi_message msg1,msg2,msg3,msg4;
  41. rt_uint16_t readx_val = 0,ready_val = 0;
  42. rt_uint8_t readx[2];
  43. rt_uint8_t ready[2];
  44. rt_sem_take(&lcd_spi_lock, RT_WAITING_FOREVER);
  45. int read_x_id = READ_X;
  46. int read_y_id = READ_Y;
  47. msg1.send_buf = &read_x_id;
  48. msg1.recv_buf = RT_NULL;
  49. msg1.length = 1;
  50. msg1.cs_take = 1;
  51. msg1.cs_release = 0;
  52. msg1.next = &msg2;
  53. msg2.send_buf = RT_NULL;
  54. msg2.recv_buf = &readx[0];
  55. msg2.length = 2;
  56. msg2.cs_take = 0;
  57. msg2.cs_release = 0;
  58. msg2.next = &msg3;
  59. msg3.send_buf = &read_y_id;
  60. msg3.recv_buf = RT_NULL;
  61. msg3.length = 1;
  62. msg3.cs_take = 0;
  63. msg3.cs_release = 0;
  64. msg3.next = &msg4;
  65. msg4.send_buf = RT_NULL;
  66. msg4.recv_buf = &ready[0];
  67. msg4.length = 2;
  68. msg4.cs_take = 0;
  69. msg4.cs_release = 1;
  70. msg4.next = RT_NULL;
  71. rt_spi_transfer_message(touch_dev, &msg1);
  72. readx_val = ((readx[0] << 8) | readx[1]) >> 4;
  73. ready_val = ((ready[0] << 8) | ready[1]) >> 4;
  74. rt_sem_release(&lcd_spi_lock);
  75. *x = readx_val;
  76. *y = ready_val;
  77. }
  78. /*
  79. XPT2046:Width:320 High:480
  80. no pressed:(0x800,0xfff)
  81. ---ETH----USB-----------------------
  82. | (0x800,0x800) (0xfff,0x800) |
  83. | |
  84. | (0x800,0xFFF) (0xfff,0xfff) |
  85. ------------------------------------
  86. */
  87. #define XMIN 0x800
  88. #define YMAX 0xfff
  89. void read_tp(void *dev, rt_uint16_t *x, rt_uint16_t *y)
  90. {
  91. struct rt_spi_device *touch_dev = (struct rt_spi_device *)dev;
  92. rt_uint8_t try = 0;
  93. uint16_t _y[5] = {0,0,0,0,0};
  94. uint16_t _x[5] = {0,0,0,0,0};
  95. uint16_t x_val = 0;
  96. uint16_t y_val = 0;
  97. uint16_t cur_x = 0;
  98. uint16_t cur_y = 0;
  99. int index = 0;
  100. while(1)
  101. {
  102. try = try + 1;
  103. touch_read_x_y(touch_dev, x, y);
  104. if((*x > XMIN) && (*y < YMAX))
  105. {
  106. _x[index] = *x;
  107. _y[index] = *y;
  108. index = index + 1;
  109. }
  110. if(index == 5)
  111. {
  112. break;
  113. }
  114. if(try > 10)
  115. {
  116. break;
  117. }
  118. }
  119. x_val = (_x[0] + _x[1] + _x[2] + _x[3]+ _x[4]) / index;
  120. y_val = (_y[0] + _y[1] + _y[2] + _y[3]+ _y[4]) / index;
  121. cur_x = (x_val - 0x800) * TFT_WIDTH / 0x800;
  122. cur_y = (y_val - 0x800) * TFT_HEIGHT / 0x800;
  123. if((cur_x < TFT_WIDTH) && (cur_y < TFT_HEIGHT))
  124. {
  125. *x = TFT_WIDTH - cur_x;
  126. *y = TFT_HEIGHT - cur_y;
  127. }
  128. else
  129. {
  130. *x = 0;
  131. *y = 0;
  132. }
  133. }
  134. static void touch_thread_entry(void *param)
  135. {
  136. rt_uint16_t x,y;
  137. struct rt_spi_device *touch_dev;
  138. touch_dev = (struct rt_spi_device *)rt_device_find(TOUCH_DEVICE_NAME);
  139. touch_dev->config.max_hz = TOUCH_SPI_MAX_FREQ;
  140. if (!touch_dev)
  141. {
  142. rt_kprintf("no %s!\n", TOUCH_DEVICE_NAME);
  143. }
  144. while (1)
  145. {
  146. rt_sem_take(&touch_ack, RT_WAITING_FOREVER);
  147. read_tp(touch_dev, &x, &y);
  148. if((x!= 0) && (y !=0))
  149. {
  150. touch_x_val = x;
  151. touch_y_val = y;
  152. touch_flag = 1;
  153. }
  154. rt_pin_mode(TP_IRQ_PIN, PIN_MODE_INPUT_PULLUP);
  155. }
  156. }
  157. static void touch_readly(void *args)
  158. {
  159. if(rt_pin_read(TP_IRQ_PIN) == PIN_LOW)
  160. {
  161. rt_pin_mode(TP_IRQ_PIN, PIN_MODE_OUTPUT);
  162. rt_pin_write(TP_IRQ_PIN,PIN_HIGH);
  163. rt_sem_release(&touch_ack);
  164. }
  165. }
  166. static rt_size_t xpt2046_read_point(struct rt_touch_device *touch, void *buf, rt_size_t read_num)
  167. {
  168. rt_uint16_t* touchxy = (rt_uint16_t *)buf;
  169. if((read_num != 0) && (touch_flag == 1))
  170. {
  171. touchxy[0] = touch_x_val;
  172. touchxy[1] = touch_y_val;
  173. touch_flag = 0;
  174. return read_num;
  175. }
  176. else
  177. {
  178. return 0;
  179. }
  180. }
  181. static rt_err_t xpt2046_control(struct rt_touch_device *device, int cmd, void *data)
  182. {
  183. return RT_EOK;
  184. }
  185. static struct rt_touch_ops touch_ops =
  186. {
  187. .touch_readpoint = xpt2046_read_point,
  188. .touch_control = xpt2046_control,
  189. };
  190. static int hw_xpt2046_touch_init(void)
  191. {
  192. //touch sem
  193. rt_sem_init(&touch_ack, "touch_ack", 0, RT_IPC_FLAG_FIFO);
  194. touch_tid = rt_thread_create("touch",
  195. touch_thread_entry, RT_NULL,
  196. TOUCH_THREAD_STACK_SIZE,
  197. TOUCH_THREAD_PRIORITY, TOUCH_THREAD_TIMESLICE);
  198. if (touch_tid != RT_NULL)
  199. rt_thread_startup(touch_tid);
  200. rt_pin_mode(TP_IRQ_PIN, PIN_MODE_INPUT_PULLUP);
  201. rt_pin_attach_irq(TP_IRQ_PIN, PIN_IRQ_MODE_LOW_LEVEL, touch_readly, RT_NULL);
  202. rt_pin_irq_enable(TP_IRQ_PIN, PIN_IRQ_ENABLE);
  203. touch_device = (rt_touch_t)rt_calloc(1, sizeof(struct rt_touch_device));
  204. if (touch_device == RT_NULL)
  205. return -RT_ERROR;
  206. /* register touch device */
  207. touch_device->info.type = RT_TOUCH_TYPE_RESISTANCE;
  208. touch_device->info.vendor = RT_TOUCH_VENDOR_UNKNOWN;
  209. //rt_memcpy(&touch_device->config, cfg, sizeof(struct rt_touch_config));
  210. touch_device->ops = &touch_ops;
  211. rt_hw_touch_register(touch_device, "xpt2046", RT_DEVICE_FLAG_INT_RX, RT_NULL);
  212. return 0;
  213. }
  214. INIT_DEVICE_EXPORT(hw_xpt2046_touch_init);