drv_touch.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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. * 2018-10-03 xuzhuoyi first implementation.
  9. */
  10. #include "drv_touch.h"
  11. #include "drivers/i2c.h"
  12. #ifdef PKG_USING_LITTLEVGL2RTT
  13. #include "littlevgl2rtt.h"
  14. #endif
  15. #define TSC_I2C_ADDR 0x41 /* 7-bit I2C address */
  16. static struct rt_i2c_bus_device *stmpe811_i2c_bus;
  17. /**
  18. \fn int32_t touch_readRegister (uint8_t reg, uint8_t *val)
  19. \brief Read register value from Touchscreen controller
  20. \param[in] reg Register address
  21. \param[out] val Pointer where data will be read from register
  22. \returns
  23. - \b 0: function succeeded
  24. - \b -1: function failed
  25. */
  26. static int32_t touch_read (uint8_t reg, uint8_t *val)
  27. {
  28. struct rt_i2c_msg msgs[2];
  29. msgs[0].addr = TSC_I2C_ADDR;
  30. msgs[0].flags = RT_I2C_WR;
  31. msgs[0].buf = ®
  32. msgs[0].len = 1;
  33. msgs[1].addr = TSC_I2C_ADDR;
  34. msgs[1].flags = RT_I2C_RD;
  35. msgs[1].buf = val;
  36. msgs[1].len = 1;
  37. if (rt_i2c_transfer(stmpe811_i2c_bus, msgs, 2) == 2)
  38. {
  39. return RT_EOK;
  40. }
  41. else
  42. {
  43. return -RT_ERROR;
  44. }
  45. }
  46. /**
  47. \fn int32_t touch_writeData (uint8_t reg, const uint8_t *val)
  48. \brief Write value to Touchscreen controller register
  49. \param[in] reg Register address
  50. \param[in] val Pointer with data to write to register
  51. \returns
  52. - \b 0: function succeeded
  53. - \b -1: function failed
  54. */
  55. static int32_t touch_write(uint8_t reg, uint8_t val)
  56. {
  57. struct rt_i2c_msg msgs;
  58. rt_uint8_t buf[2];
  59. buf[0] = reg;
  60. buf[1] = val;
  61. msgs.addr = TSC_I2C_ADDR;
  62. msgs.flags = RT_I2C_WR;
  63. msgs.buf = buf;
  64. msgs.len = 2;
  65. if (rt_i2c_transfer(stmpe811_i2c_bus, &msgs, 1) == 1)
  66. {
  67. return RT_EOK;
  68. }
  69. else
  70. {
  71. return -RT_ERROR;
  72. }
  73. }
  74. /**
  75. \fn int32_t Touch_Initialize (void)
  76. \brief Initialize touchscreen
  77. \returns
  78. - \b 0: function succeeded
  79. - \b -1: function failed
  80. */
  81. static rt_err_t stmpe811_touch_init(rt_device_t dev)
  82. {
  83. stmpe811_i2c_bus = rt_i2c_bus_device_find("i2c3");
  84. touch_write(STMPE811_SYS_CTRL1, 0x02); /* Reset Touch-screen controller */
  85. rt_thread_mdelay(10); /* Wait 10ms */
  86. touch_write(STMPE811_SYS_CTRL2, 0x0C); /* Enable TSC and ADC */
  87. touch_write(STMPE811_ADC_CTRL1, 0x68); /* Set sample time , 12-bit mode */
  88. rt_thread_mdelay(1); /* Wait 1ms */
  89. touch_write(STMPE811_ADC_CTRL2, 0x01); /* ADC frequency 3.25 MHz */
  90. touch_write(STMPE811_TSC_CFG, 0xC2); /* Detect delay 10us,
  91. Settle time 500us */
  92. touch_write(STMPE811_FIFO_TH, 0x01); /* Threshold for FIFO */
  93. touch_write(STMPE811_FIFO_STA, 0x01); /* FIFO reset */
  94. touch_write(STMPE811_FIFO_STA, 0x00); /* FIFO not reset */
  95. touch_write(STMPE811_TSC_FRACTION_Z, 0x07); /* Fraction z */
  96. touch_write(STMPE811_TSC_I_DRIVE, 0x01); /* Drive 50 mA typical */
  97. touch_write(STMPE811_GPIO_AF, 0x00); /* Pins are used for touchscreen */
  98. touch_write(STMPE811_TSC_CTRL, 0x01); /* Enable TSC */
  99. return 0;
  100. }
  101. /**
  102. \fn int32_t Touch_Uninitialize (void)
  103. \brief De-initialize touchscreen
  104. \returns
  105. - \b 0: function succeeded
  106. - \b -1: function failed
  107. */
  108. int32_t touch_uninitialize (void) {
  109. touch_write(STMPE811_SYS_CTRL1, 0x02); /* Reset Touch-screen controller */
  110. return 0;
  111. }
  112. /**
  113. \fn int32_t Touch_GetState (TOUCH_STATE *pState)
  114. \brief Get touchscreen state
  115. \param[out] pState pointer to TOUCH_STATE structure
  116. \returns
  117. - \b 0: function succeeded
  118. - \b -1: function failed
  119. */
  120. int32_t touch_get_state(struct touch_state *state)
  121. {
  122. uint8_t val;
  123. uint8_t num;
  124. uint8_t xyz[4];
  125. int32_t res;
  126. struct rt_i2c_msg msgs[2];
  127. /* Read touch status */
  128. res = touch_read(STMPE811_TSC_CTRL, &val);
  129. if (res < 0) return -1;
  130. state->pressed = (val & (1 << 7)) ? 1 : 0;
  131. if (state->pressed)
  132. {
  133. val = STMPE811_TSC_DATA;
  134. /* If FIFO overflow, discard all samples except the last one */
  135. res = touch_read(STMPE811_FIFO_SIZE, &num);
  136. if (res < 0 || num == 0) return -1;
  137. while (num--)
  138. {
  139. msgs[0].addr = TSC_I2C_ADDR;
  140. msgs[0].flags = RT_I2C_WR;
  141. msgs[0].buf = &val;
  142. msgs[0].len = 1;
  143. //rt_i2c_transfer(stmpe811_i2c_bus, &msgs, 1);
  144. //ptrI2C->MasterTransmit (TSC_I2C_ADDR, &val, 1, true);
  145. //while (ptrI2C->GetStatus().busy);
  146. msgs[1].addr = TSC_I2C_ADDR;
  147. msgs[1].flags = RT_I2C_RD;
  148. msgs[1].buf = xyz;
  149. msgs[1].len = 4;
  150. rt_i2c_transfer(stmpe811_i2c_bus, msgs, 2);
  151. //ptrI2C->MasterReceive (TSC_I2C_ADDR, xyz, 4, false);
  152. //while (ptrI2C->GetStatus().busy);
  153. }
  154. state->x = (int16_t)((xyz[0] << 4) | ((xyz[1] & 0xF0) >> 4));
  155. state->y = (int16_t) (xyz[2] | ((xyz[1] & 0x0F) << 8));
  156. }
  157. else
  158. {
  159. /* Clear all data in FIFO */
  160. touch_write(STMPE811_FIFO_STA, 0x1);
  161. touch_write(STMPE811_FIFO_STA, 0x0);
  162. }
  163. return 0;
  164. }
  165. void touch_show_state()
  166. {
  167. int16_t x;
  168. int16_t y;
  169. struct touch_state ts;
  170. touch_get_state(&ts);
  171. x = (3706 - ts.x) / 14;
  172. y = (-461 + ts.y) / 10.5;
  173. rt_kprintf("[drv_touch] touch_show_state, x: %d, y: %d, pressed: %d, padding: %d\n", ts.x , ts.y, ts.pressed, ts.padding);
  174. rt_kprintf("[drv_touch] touch_show_state, phy x: %d, phy y: %d\n", x , y);
  175. }
  176. MSH_CMD_EXPORT(touch_show_state, show screen coordinate in touching);
  177. static int rt_hw_touch_init(void)
  178. {
  179. static struct rt_device touch;
  180. /* init device structure */
  181. touch.type = RT_Device_Class_Unknown;
  182. touch.init = stmpe811_touch_init;
  183. touch.user_data = RT_NULL;
  184. /* register touch device to RT-Thread */
  185. rt_device_register(&touch, "touch", RT_DEVICE_FLAG_RDWR);
  186. return RT_EOK;
  187. }
  188. INIT_BOARD_EXPORT(rt_hw_touch_init);