XPT2046.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /**
  2. * @file XPT2046.c
  3. *
  4. */
  5. /*********************
  6. * INCLUDES
  7. *********************/
  8. #include "XPT2046.h"
  9. #if USE_XPT2046
  10. #include <stddef.h>
  11. #include LV_DRV_INDEV_INCLUDE
  12. #include LV_DRV_DELAY_INCLUDE
  13. /*********************
  14. * DEFINES
  15. *********************/
  16. #define CMD_X_READ 0b10010000
  17. #define CMD_Y_READ 0b11010000
  18. /**********************
  19. * TYPEDEFS
  20. **********************/
  21. /**********************
  22. * STATIC PROTOTYPES
  23. **********************/
  24. static void xpt2046_corr(int16_t * x, int16_t * y);
  25. static void xpt2046_avg(int16_t * x, int16_t * y);
  26. /**********************
  27. * STATIC VARIABLES
  28. **********************/
  29. int16_t avg_buf_x[XPT2046_AVG];
  30. int16_t avg_buf_y[XPT2046_AVG];
  31. uint8_t avg_last;
  32. /**********************
  33. * MACROS
  34. **********************/
  35. /**********************
  36. * GLOBAL FUNCTIONS
  37. **********************/
  38. /**
  39. * Initialize the XPT2046
  40. */
  41. void xpt2046_init(void)
  42. {
  43. }
  44. /**
  45. * Get the current position and state of the touchpad
  46. * @param data store the read data here
  47. * @return false: because no ore data to be read
  48. */
  49. bool xpt2046_read(lv_indev_data_t * data)
  50. {
  51. static int16_t last_x = 0;
  52. static int16_t last_y = 0;
  53. bool valid = true;
  54. uint8_t buf;
  55. int16_t x = 0;
  56. int16_t y = 0;
  57. uint8_t irq = LV_DRV_INDEV_IRQ_READ;
  58. if(irq == 0) {
  59. LV_DRV_INDEV_SPI_CS(0);
  60. LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_X_READ); /*Start x read*/
  61. buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0); /*Read x MSB*/
  62. x = buf << 8;
  63. buf = LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_Y_READ); /*Until x LSB converted y command can be sent*/
  64. x += buf;
  65. buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0); /*Read y MSB*/
  66. y = buf << 8;
  67. buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0); /*Read y LSB*/
  68. y += buf;
  69. /*Normalize Data*/
  70. x = x >> 3;
  71. y = y >> 3;
  72. xpt2046_corr(&x, &y);
  73. xpt2046_avg(&x, &y);
  74. last_x = x;
  75. last_y = y;
  76. LV_DRV_INDEV_SPI_CS(1);
  77. } else {
  78. x = last_x;
  79. y = last_y;
  80. avg_last = 0;
  81. valid = false;
  82. }
  83. data->point.x = x;
  84. data->point.y = y;
  85. data->state = valid == false ? LV_INDEV_STATE_REL : LV_INDEV_STATE_PR;
  86. return valid;
  87. }
  88. /**********************
  89. * STATIC FUNCTIONS
  90. **********************/
  91. static void xpt2046_corr(int16_t * x, int16_t * y)
  92. {
  93. #if XPT2046_XY_SWAP != 0
  94. int16_t swap_tmp;
  95. swap_tmp = *x;
  96. *x = *y;
  97. *y = swap_tmp;
  98. #endif
  99. if((*x) > XPT2046_X_MIN) (*x) -= XPT2046_X_MIN;
  100. else (*x) = 0;
  101. if((*y) > XPT2046_Y_MIN) (*y) -= XPT2046_Y_MIN;
  102. else (*y) = 0;
  103. (*x) = (uint32_t) ((uint32_t)(*x) * XPT2046_HOR_RES) /
  104. (XPT2046_X_MAX - XPT2046_X_MIN);
  105. (*y) = (uint32_t) ((uint32_t)(*y) * XPT2046_VER_RES) /
  106. (XPT2046_Y_MAX - XPT2046_Y_MIN);
  107. #if XPT2046_X_INV != 0
  108. (*x) = XPT2046_HOR_RES - (*x);
  109. #endif
  110. #if XPT2046_Y_INV != 0
  111. (*y) = XPT2046_VER_RES - (*y);
  112. #endif
  113. }
  114. static void xpt2046_avg(int16_t * x, int16_t * y)
  115. {
  116. /*Shift out the oldest data*/
  117. uint8_t i;
  118. for(i = XPT2046_AVG - 1; i > 0 ; i--) {
  119. avg_buf_x[i] = avg_buf_x[i - 1];
  120. avg_buf_y[i] = avg_buf_y[i - 1];
  121. }
  122. /*Insert the new point*/
  123. avg_buf_x[0] = *x;
  124. avg_buf_y[0] = *y;
  125. if(avg_last < XPT2046_AVG) avg_last++;
  126. /*Sum the x and y coordinates*/
  127. int32_t x_sum = 0;
  128. int32_t y_sum = 0;
  129. for(i = 0; i < avg_last ; i++) {
  130. x_sum += avg_buf_x[i];
  131. y_sum += avg_buf_y[i];
  132. }
  133. /*Normalize the sums*/
  134. (*x) = (int32_t)x_sum / avg_last;
  135. (*y) = (int32_t)y_sum / avg_last;
  136. }
  137. #endif