ft6336.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <stdlib.h>
  4. #include "FreeRTOS.h"
  5. #include "chip.h"
  6. #include "board.h"
  7. #include "timers.h"
  8. #ifdef TP_USE_FT6336U
  9. #include <xm_base.h>
  10. #include <xm_event.h>
  11. #define FT6336U_STAT_ADDR 0x02
  12. #define FT6336U_TOUCH1_ADDR 0x03
  13. #define FT6336U_TOUCH2_ADDR 0x09
  14. #define FT6336U_TOUCH3_ADDR 0x0F
  15. #define FT6336U_TOUCH4_ADDR 0x15
  16. #define FT6336U_TOUCH5_ADDR 0x1B
  17. #define FT6336U_CHIP_ID 0xA3
  18. #define FT6336U_CONFIG_X_MAX 960
  19. #define FT6336U_CONFIG_Y_MAX 320
  20. #define FT6336U_SLAVE_ADDR 0x38
  21. #define FT6336U_GPIO_INT TP_GPIO_INT
  22. #define FT6336U_GPIO_RST TP_GPIO_RST
  23. #define FT6336U_INVERTED_X TP_INV_X
  24. #define FT6336U_INVERTED_Y TP_INV_Y
  25. #if TP_MT_TOUCH
  26. #define FT6336U_MAX_CONTACTS 5
  27. #else
  28. #define FT6336U_MAX_CONTACTS 1
  29. #endif
  30. //#define FT6336U_USE_RELEASE_TIMER
  31. //#define FT6336U_REPEAT_FILTER
  32. #define GPIO_IS_VALID(n) ((n >= 0) && (n < 128) ? 1 : 0)
  33. #define FT6336U_ERR(fmt, args...) printf("###ERR:[%s]"fmt, __func__, ##args)
  34. #define FT6336U_DBG(fmt, args...) //printf("DBG:[%s]"fmt, __func__, ##args)
  35. enum {
  36. FT6336U_INDEV_STATE_DOWN,
  37. FT6336U_INDEV_STATE_UP,
  38. FT6336U_INDEV_STATE_CONTACT
  39. };
  40. struct ft6336u_ts_data {
  41. struct i2c_adapter *adap;
  42. unsigned int max_touch_num;
  43. unsigned int x_max;
  44. unsigned int y_max;
  45. int last_input_x;
  46. int last_input_y;
  47. int last_input_state;
  48. int gpio_int;
  49. int gpio_rst;
  50. uint8_t id;
  51. unsigned long irq_flags;
  52. TaskHandle_t irq_task;
  53. #ifdef FT6336U_USE_RELEASE_TIMER
  54. TimerHandle_t release_timer;
  55. #endif
  56. };
  57. typedef struct _ft6336u_point{
  58. int16_t x;
  59. int16_t y;
  60. uint8_t state;
  61. } ft6336u_point_t;
  62. static int ft6336u_i2c_read(struct i2c_adapter *adap, uint8_t reg, uint8_t *buf, int len)
  63. {
  64. struct i2c_msg msgs[2];
  65. int ret;
  66. msgs[0].flags = !I2C_M_RD;
  67. msgs[0].addr = adap->addr;
  68. msgs[0].len = 1;
  69. msgs[0].buf = &reg;
  70. msgs[1].flags = I2C_M_RD;
  71. msgs[1].addr = adap->addr;
  72. msgs[1].len = len;
  73. msgs[1].buf = buf;
  74. ret = i2c_transfer(adap, msgs, 2);
  75. return ((ret != 2) ? -EIO : 0);
  76. }
  77. #if 0
  78. static int ft6336u_i2c_write(struct i2c_adapter *adap, const uint8_t *buf, int len)
  79. {
  80. struct i2c_msg msg;
  81. int ret;
  82. msg.flags = !I2C_M_RD;
  83. msg.addr = adap->addr;
  84. msg.buf = buf;
  85. msg.len = len + 1;
  86. ret = i2c_transfer(adap, &msg, 1);
  87. return ((ret != 1) ? -EIO : 0);
  88. }
  89. #endif
  90. static int ft6336u_ts_read_input_report(struct ft6336u_ts_data *ts)
  91. {
  92. uint8_t counter = 0;
  93. uint8_t lvalue;
  94. uint8_t ts_num;
  95. do {
  96. //make sure data in buffer is valid
  97. ft6336u_i2c_read(ts->adap, FT6336U_STAT_ADDR, &lvalue, 1);
  98. if(counter++ == 0x30)
  99. return 0;
  100. } while(lvalue & 0x08);
  101. ts_num = (uint8_t)(lvalue & 0x0F);
  102. if(ts_num > FT6336U_MAX_CONTACTS)
  103. ts_num = FT6336U_MAX_CONTACTS;
  104. // FT6336U_DBG("points num:%d\n", ts_num);
  105. return ts_num;
  106. }
  107. static int ft6336u_ts_report_touch(struct ft6336u_ts_data *ts, int id)
  108. {
  109. ft6336u_point_t point;
  110. uint8_t values[4];
  111. const uint8_t x_base[] = {
  112. FT6336U_TOUCH1_ADDR,
  113. FT6336U_TOUCH2_ADDR,
  114. FT6336U_TOUCH3_ADDR,
  115. FT6336U_TOUCH4_ADDR,
  116. FT6336U_TOUCH5_ADDR
  117. };
  118. if(ft6336u_i2c_read(ts->adap, x_base[id], values, 4) != 0) {
  119. FT6336U_ERR("i2c read coordinate failed\n");
  120. return -1;
  121. }
  122. point.state = (values[0]>>6) & 0x3;
  123. point.x = (((uint16_t)(values[0]&0x0f)) << 8) | values[1];
  124. point.y = (((uint16_t)(values[2]&0x0f)) << 8) | values[3];
  125. /*invalid point val*/
  126. if((point.x > ts->x_max) || (point.y > ts->y_max) || (point.state > FT6336U_INDEV_STATE_CONTACT)) {
  127. FT6336U_ERR("Coordinate out of range: x:%d, y:%d\n", point.x, point.y);
  128. return -1;
  129. }
  130. #if FT6336U_INVERTED_X
  131. point.x = ts->x_max - point.x;
  132. #endif
  133. #if FT6336U_INVERTED_Y
  134. point.y = ts->y_max - point.y;
  135. #endif
  136. #ifdef FT6336U_REPEAT_FILTER
  137. if(point.state == FT6336U_INDEV_STATE_CONTACT) {
  138. if((ts->last_input_x == point.x) && (ts->last_input_y == point.y)) {
  139. return 0;
  140. } else {
  141. //move event.
  142. }
  143. }
  144. #endif
  145. //send press event
  146. XM_TpEventProc (XM_EVENT_TOUCHDOWN, point.x, point.y, 0);
  147. ts->last_input_x = point.x;
  148. ts->last_input_y = point.y;
  149. ts->last_input_state = point.state;
  150. // FT6336U_DBG("id[%d]:x:%d, y:%d, state:0x%x\n", id, point.x, point.y, point.state);
  151. return 0;
  152. }
  153. static void ft6336u_process_events(struct ft6336u_ts_data *ts)
  154. {
  155. uint8_t ts_num, i;
  156. ts_num = ft6336u_ts_read_input_report(ts);
  157. for(i=0; i<ts_num; i++) {
  158. ft6336u_ts_report_touch(ts, i);
  159. }
  160. if(ts_num == 0) { /* report the last point release event */
  161. XM_TpEventProc (XM_EVENT_TOUCHUP, ts->last_input_x, ts->last_input_y, 0);
  162. }
  163. }
  164. #ifdef FT6336U_USE_RELEASE_TIMER
  165. static void ft6336_timeout_callback(TimerHandle_t timer)
  166. {
  167. struct ft6336u_ts_data *ts = (struct ft6336u_ts_data *)pvTimerGetTimerID(timer);
  168. if(!ts) {
  169. FT6336U_ERR("Invalid ts.\n");
  170. return;
  171. }
  172. if(ts->last_input_state != FT6336U_INDEV_STATE_UP) { //drop release event.
  173. XM_TpEventProc (XM_EVENT_TOUCHUP, ts->last_input_x, ts->last_input_y, 0);
  174. FT6336U_ERR("Force report release event\n");
  175. }
  176. }
  177. #endif
  178. static void ft6336u_ts_irq_task(void *param)
  179. {
  180. uint32_t ulNotifiedValue;
  181. struct ft6336u_ts_data *ts;
  182. for(;;) {
  183. xTaskNotifyWait( 0x00, /* Don't clear any notification bits on entry. */
  184. 0xffffffff, /* Reset the notification value to 0 on exit. */
  185. &ulNotifiedValue, /* Notified value pass out in ulNotifiedValue. */
  186. portMAX_DELAY);
  187. ts = (struct ft6336u_ts_data *)ulNotifiedValue;
  188. if(!ts) {
  189. FT6336U_ERR("Invalid ts.\n");
  190. continue;
  191. }
  192. #ifdef FT6336U_USE_RELEASE_TIMER
  193. if(ts->release_timer)
  194. xTimerStop(ts->release_timer, 0);
  195. #endif
  196. ft6336u_process_events(ts);
  197. #ifdef FT6336U_USE_RELEASE_TIMER
  198. if(ts->release_timer)
  199. {
  200. xTimerReset(ts->release_timer, 0);
  201. xTimerStart(ts->release_timer, 0);
  202. }
  203. #endif
  204. }
  205. }
  206. static void ft6336u_ts_irq_handler(void *param)
  207. {
  208. struct ft6336u_ts_data *ts = (struct ft6336u_ts_data *)param;
  209. if(ts)
  210. xTaskNotifyFromISR(ts->irq_task, (uint32_t)ts, eSetValueWithOverwrite, 0);
  211. }
  212. static int ft6336u_request_irq(struct ft6336u_ts_data *ts)
  213. {
  214. int ret = -1;
  215. if(GPIO_IS_VALID(ts->gpio_int)) {
  216. gpio_direction_input(ts->gpio_int);
  217. if(gpio_irq_request(ts->gpio_int, ts->irq_flags, ft6336u_ts_irq_handler, ts)) {
  218. FT6336U_ERR("gpio irq request failed\n");
  219. return -1;
  220. }
  221. ret = 0;
  222. }
  223. return ret;
  224. }
  225. static int ft6336u_configure_dev(struct ft6336u_ts_data *ts)
  226. {
  227. int ret;
  228. ret = xTaskCreate(ft6336u_ts_irq_task, "ft6336u irq task", 1024, ts, 10, &ts->irq_task);
  229. if(ret != pdPASS) {
  230. FT6336U_ERR("create ft6336u irq task fail.\n");
  231. return -1;
  232. }
  233. ret = ft6336u_request_irq(ts);
  234. if(ret) {
  235. FT6336U_ERR("request IRQ failed\n");
  236. if(ts->irq_task)
  237. vTaskDelete(ts->irq_task);
  238. return ret;
  239. }
  240. return 0;
  241. }
  242. static int ft6336u_read_chip_id(struct ft6336u_ts_data *ts)
  243. {
  244. int retry = 3;
  245. int ret;
  246. do {
  247. ret = ft6336u_i2c_read(ts->adap, FT6336U_CHIP_ID, &ts->id, 1);
  248. if(ret == 0) {
  249. FT6336U_DBG("FT6336U ID %d\n", ts->id);
  250. return 0;
  251. }
  252. vTaskDelay(pdMS_TO_TICKS(10));
  253. } while(retry--);
  254. return -1;
  255. }
  256. static int ft6336u_get_chip_para(struct ft6336u_ts_data *ts)
  257. {
  258. int ret;
  259. ret = ft6336u_read_chip_id(ts);
  260. if(ret) {
  261. FT6336U_ERR("read chip id failed\n");
  262. return ret;
  263. }
  264. if(ts->id != 0x64) {
  265. FT6336U_ERR("Invalid chip ID:0x%2x\n", ts->id);
  266. return -1;
  267. }
  268. ts->irq_flags = IRQ_TYPE_EDGE_FALLING;
  269. ts->max_touch_num = FT6336U_MAX_CONTACTS;
  270. ts->x_max = FT6336U_CONFIG_X_MAX;
  271. ts->y_max = FT6336U_CONFIG_Y_MAX;
  272. return 0;
  273. }
  274. static int ft6336u_reset(struct ft6336u_ts_data *ts)
  275. {
  276. if(GPIO_IS_VALID(ts->gpio_rst)) {
  277. gpio_direction_output(ts->gpio_rst, 0);
  278. vTaskDelay(pdMS_TO_TICKS(10)); /* Trst: > 5ms */
  279. gpio_direction_output(ts->gpio_rst, 1);
  280. vTaskDelay(pdMS_TO_TICKS(200)); /* tpon: 200ms */
  281. return 0;
  282. }
  283. return -1;
  284. }
  285. static int ft6336u_ts_probe(struct i2c_adapter *adap)
  286. {
  287. struct ft6336u_ts_data *ts;
  288. int ret;
  289. ts = pvPortMalloc(sizeof(*ts));
  290. if(!ts) {
  291. FT6336U_ERR("malloc failed.\n");
  292. return -ENOMEM;
  293. }
  294. memset(ts, 0, sizeof(*ts));
  295. ts->adap = adap;
  296. ts->adap->addr = FT6336U_SLAVE_ADDR;
  297. ts->gpio_int = FT6336U_GPIO_INT;
  298. ts->gpio_rst = FT6336U_GPIO_RST;
  299. ret = ft6336u_reset(ts);
  300. if(ret) {
  301. FT6336U_ERR("Controller reset failed.\n");
  302. // goto exit;
  303. }
  304. ret = ft6336u_get_chip_para(ts);
  305. if(ret) {
  306. FT6336U_ERR("version id unmatches.\n");
  307. goto exit;
  308. }
  309. #ifdef FT6336U_USE_RELEASE_TIMER
  310. ts->release_timer = xTimerCreate("FT6336 Release Timer",
  311. pdMS_TO_TICKS(200),
  312. pdFALSE,
  313. ts,
  314. ft6336_timeout_callback
  315. );
  316. #endif
  317. ret = ft6336u_configure_dev(ts);
  318. if(ret) {
  319. FT6336U_ERR("ft6336u_configure_dev failed.\n");
  320. goto exit;
  321. }
  322. return 0;
  323. exit:
  324. vPortFree(ts);
  325. return -1;
  326. }
  327. int ft6336u_init(void)
  328. {
  329. struct i2c_adapter *adap = NULL;
  330. if(!(adap = i2c_open("i2c0"))) {
  331. FT6336U_ERR("open i2c0 fail.\n");
  332. return -1;
  333. }
  334. if(ft6336u_ts_probe(adap)) {
  335. FT6336U_ERR("ft6336u probe fail\n");
  336. i2c_close(adap);
  337. return -1;
  338. }
  339. return 0;
  340. }
  341. #endif