| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- #include <stdio.h>
- #include <math.h>
- #include <stdlib.h>
- #include "FreeRTOS.h"
- #include "chip.h"
- #include "board.h"
- #include "timers.h"
- #ifdef TP_USE_FT6336U
- #include <xm_base.h>
- #include <xm_event.h>
- #define FT6336U_STAT_ADDR 0x02
- #define FT6336U_TOUCH1_ADDR 0x03
- #define FT6336U_TOUCH2_ADDR 0x09
- #define FT6336U_TOUCH3_ADDR 0x0F
- #define FT6336U_TOUCH4_ADDR 0x15
- #define FT6336U_TOUCH5_ADDR 0x1B
- #define FT6336U_CHIP_ID 0xA3
- #define FT6336U_CONFIG_X_MAX 960
- #define FT6336U_CONFIG_Y_MAX 320
- #define FT6336U_SLAVE_ADDR 0x38
- #define FT6336U_GPIO_INT TP_GPIO_INT
- #define FT6336U_GPIO_RST TP_GPIO_RST
- #define FT6336U_INVERTED_X TP_INV_X
- #define FT6336U_INVERTED_Y TP_INV_Y
- #if TP_MT_TOUCH
- #define FT6336U_MAX_CONTACTS 5
- #else
- #define FT6336U_MAX_CONTACTS 1
- #endif
- //#define FT6336U_USE_RELEASE_TIMER
- //#define FT6336U_REPEAT_FILTER
- #define GPIO_IS_VALID(n) ((n >= 0) && (n < 128) ? 1 : 0)
- #define FT6336U_ERR(fmt, args...) printf("###ERR:[%s]"fmt, __func__, ##args)
- #define FT6336U_DBG(fmt, args...) //printf("DBG:[%s]"fmt, __func__, ##args)
- enum {
- FT6336U_INDEV_STATE_DOWN,
- FT6336U_INDEV_STATE_UP,
- FT6336U_INDEV_STATE_CONTACT
- };
- struct ft6336u_ts_data {
- struct i2c_adapter *adap;
- unsigned int max_touch_num;
- unsigned int x_max;
- unsigned int y_max;
- int last_input_x;
- int last_input_y;
- int last_input_state;
- int gpio_int;
- int gpio_rst;
- uint8_t id;
- unsigned long irq_flags;
- TaskHandle_t irq_task;
- #ifdef FT6336U_USE_RELEASE_TIMER
- TimerHandle_t release_timer;
- #endif
- };
- typedef struct _ft6336u_point{
- int16_t x;
- int16_t y;
- uint8_t state;
- } ft6336u_point_t;
- static int ft6336u_i2c_read(struct i2c_adapter *adap, uint8_t reg, uint8_t *buf, int len)
- {
- struct i2c_msg msgs[2];
- int ret;
- msgs[0].flags = !I2C_M_RD;
- msgs[0].addr = adap->addr;
- msgs[0].len = 1;
- msgs[0].buf = ®
- msgs[1].flags = I2C_M_RD;
- msgs[1].addr = adap->addr;
- msgs[1].len = len;
- msgs[1].buf = buf;
- ret = i2c_transfer(adap, msgs, 2);
- return ((ret != 2) ? -EIO : 0);
- }
- #if 0
- static int ft6336u_i2c_write(struct i2c_adapter *adap, const uint8_t *buf, int len)
- {
- struct i2c_msg msg;
- int ret;
- msg.flags = !I2C_M_RD;
- msg.addr = adap->addr;
- msg.buf = buf;
- msg.len = len + 1;
- ret = i2c_transfer(adap, &msg, 1);
- return ((ret != 1) ? -EIO : 0);
- }
- #endif
- static int ft6336u_ts_read_input_report(struct ft6336u_ts_data *ts)
- {
- uint8_t counter = 0;
- uint8_t lvalue;
- uint8_t ts_num;
- do {
- //make sure data in buffer is valid
- ft6336u_i2c_read(ts->adap, FT6336U_STAT_ADDR, &lvalue, 1);
- if(counter++ == 0x30)
- return 0;
- } while(lvalue & 0x08);
- ts_num = (uint8_t)(lvalue & 0x0F);
- if(ts_num > FT6336U_MAX_CONTACTS)
- ts_num = FT6336U_MAX_CONTACTS;
- // FT6336U_DBG("points num:%d\n", ts_num);
- return ts_num;
- }
- static int ft6336u_ts_report_touch(struct ft6336u_ts_data *ts, int id)
- {
- ft6336u_point_t point;
- uint8_t values[4];
- const uint8_t x_base[] = {
- FT6336U_TOUCH1_ADDR,
- FT6336U_TOUCH2_ADDR,
- FT6336U_TOUCH3_ADDR,
- FT6336U_TOUCH4_ADDR,
- FT6336U_TOUCH5_ADDR
- };
- if(ft6336u_i2c_read(ts->adap, x_base[id], values, 4) != 0) {
- FT6336U_ERR("i2c read coordinate failed\n");
- return -1;
- }
- point.state = (values[0]>>6) & 0x3;
- point.x = (((uint16_t)(values[0]&0x0f)) << 8) | values[1];
- point.y = (((uint16_t)(values[2]&0x0f)) << 8) | values[3];
- /*invalid point val*/
- if((point.x > ts->x_max) || (point.y > ts->y_max) || (point.state > FT6336U_INDEV_STATE_CONTACT)) {
- FT6336U_ERR("Coordinate out of range: x:%d, y:%d\n", point.x, point.y);
- return -1;
- }
- #if FT6336U_INVERTED_X
- point.x = ts->x_max - point.x;
- #endif
- #if FT6336U_INVERTED_Y
- point.y = ts->y_max - point.y;
- #endif
- #ifdef FT6336U_REPEAT_FILTER
- if(point.state == FT6336U_INDEV_STATE_CONTACT) {
- if((ts->last_input_x == point.x) && (ts->last_input_y == point.y)) {
- return 0;
- } else {
- //move event.
- }
- }
- #endif
- //send press event
- XM_TpEventProc (XM_EVENT_TOUCHDOWN, point.x, point.y, 0);
- ts->last_input_x = point.x;
- ts->last_input_y = point.y;
- ts->last_input_state = point.state;
- // FT6336U_DBG("id[%d]:x:%d, y:%d, state:0x%x\n", id, point.x, point.y, point.state);
- return 0;
- }
- static void ft6336u_process_events(struct ft6336u_ts_data *ts)
- {
- uint8_t ts_num, i;
- ts_num = ft6336u_ts_read_input_report(ts);
- for(i=0; i<ts_num; i++) {
- ft6336u_ts_report_touch(ts, i);
- }
- if(ts_num == 0) { /* report the last point release event */
- XM_TpEventProc (XM_EVENT_TOUCHUP, ts->last_input_x, ts->last_input_y, 0);
- }
- }
- #ifdef FT6336U_USE_RELEASE_TIMER
- static void ft6336_timeout_callback(TimerHandle_t timer)
- {
- struct ft6336u_ts_data *ts = (struct ft6336u_ts_data *)pvTimerGetTimerID(timer);
- if(!ts) {
- FT6336U_ERR("Invalid ts.\n");
- return;
- }
- if(ts->last_input_state != FT6336U_INDEV_STATE_UP) { //drop release event.
- XM_TpEventProc (XM_EVENT_TOUCHUP, ts->last_input_x, ts->last_input_y, 0);
- FT6336U_ERR("Force report release event\n");
- }
- }
- #endif
- static void ft6336u_ts_irq_task(void *param)
- {
- uint32_t ulNotifiedValue;
- struct ft6336u_ts_data *ts;
- for(;;) {
- xTaskNotifyWait( 0x00, /* Don't clear any notification bits on entry. */
- 0xffffffff, /* Reset the notification value to 0 on exit. */
- &ulNotifiedValue, /* Notified value pass out in ulNotifiedValue. */
- portMAX_DELAY);
- ts = (struct ft6336u_ts_data *)ulNotifiedValue;
- if(!ts) {
- FT6336U_ERR("Invalid ts.\n");
- continue;
- }
- #ifdef FT6336U_USE_RELEASE_TIMER
- if(ts->release_timer)
- xTimerStop(ts->release_timer, 0);
- #endif
- ft6336u_process_events(ts);
- #ifdef FT6336U_USE_RELEASE_TIMER
- if(ts->release_timer)
- {
- xTimerReset(ts->release_timer, 0);
- xTimerStart(ts->release_timer, 0);
- }
- #endif
- }
- }
- static void ft6336u_ts_irq_handler(void *param)
- {
- struct ft6336u_ts_data *ts = (struct ft6336u_ts_data *)param;
- if(ts)
- xTaskNotifyFromISR(ts->irq_task, (uint32_t)ts, eSetValueWithOverwrite, 0);
- }
- static int ft6336u_request_irq(struct ft6336u_ts_data *ts)
- {
- int ret = -1;
- if(GPIO_IS_VALID(ts->gpio_int)) {
- gpio_direction_input(ts->gpio_int);
- if(gpio_irq_request(ts->gpio_int, ts->irq_flags, ft6336u_ts_irq_handler, ts)) {
- FT6336U_ERR("gpio irq request failed\n");
- return -1;
- }
- ret = 0;
- }
- return ret;
- }
- static int ft6336u_configure_dev(struct ft6336u_ts_data *ts)
- {
- int ret;
- ret = xTaskCreate(ft6336u_ts_irq_task, "ft6336u irq task", 1024, ts, 10, &ts->irq_task);
- if(ret != pdPASS) {
- FT6336U_ERR("create ft6336u irq task fail.\n");
- return -1;
- }
- ret = ft6336u_request_irq(ts);
- if(ret) {
- FT6336U_ERR("request IRQ failed\n");
- if(ts->irq_task)
- vTaskDelete(ts->irq_task);
- return ret;
- }
- return 0;
- }
- static int ft6336u_read_chip_id(struct ft6336u_ts_data *ts)
- {
- int retry = 3;
- int ret;
- do {
- ret = ft6336u_i2c_read(ts->adap, FT6336U_CHIP_ID, &ts->id, 1);
- if(ret == 0) {
- FT6336U_DBG("FT6336U ID %d\n", ts->id);
- return 0;
- }
- vTaskDelay(pdMS_TO_TICKS(10));
- } while(retry--);
- return -1;
- }
- static int ft6336u_get_chip_para(struct ft6336u_ts_data *ts)
- {
- int ret;
- ret = ft6336u_read_chip_id(ts);
- if(ret) {
- FT6336U_ERR("read chip id failed\n");
- return ret;
- }
- if(ts->id != 0x64) {
- FT6336U_ERR("Invalid chip ID:0x%2x\n", ts->id);
- return -1;
- }
- ts->irq_flags = IRQ_TYPE_EDGE_FALLING;
- ts->max_touch_num = FT6336U_MAX_CONTACTS;
- ts->x_max = FT6336U_CONFIG_X_MAX;
- ts->y_max = FT6336U_CONFIG_Y_MAX;
- return 0;
- }
- static int ft6336u_reset(struct ft6336u_ts_data *ts)
- {
- if(GPIO_IS_VALID(ts->gpio_rst)) {
- gpio_direction_output(ts->gpio_rst, 0);
- vTaskDelay(pdMS_TO_TICKS(10)); /* Trst: > 5ms */
- gpio_direction_output(ts->gpio_rst, 1);
- vTaskDelay(pdMS_TO_TICKS(200)); /* tpon: 200ms */
- return 0;
- }
- return -1;
- }
- static int ft6336u_ts_probe(struct i2c_adapter *adap)
- {
- struct ft6336u_ts_data *ts;
- int ret;
- ts = pvPortMalloc(sizeof(*ts));
- if(!ts) {
- FT6336U_ERR("malloc failed.\n");
- return -ENOMEM;
- }
- memset(ts, 0, sizeof(*ts));
- ts->adap = adap;
- ts->adap->addr = FT6336U_SLAVE_ADDR;
- ts->gpio_int = FT6336U_GPIO_INT;
- ts->gpio_rst = FT6336U_GPIO_RST;
- ret = ft6336u_reset(ts);
- if(ret) {
- FT6336U_ERR("Controller reset failed.\n");
- // goto exit;
- }
- ret = ft6336u_get_chip_para(ts);
- if(ret) {
- FT6336U_ERR("version id unmatches.\n");
- goto exit;
- }
- #ifdef FT6336U_USE_RELEASE_TIMER
- ts->release_timer = xTimerCreate("FT6336 Release Timer",
- pdMS_TO_TICKS(200),
- pdFALSE,
- ts,
- ft6336_timeout_callback
- );
- #endif
- ret = ft6336u_configure_dev(ts);
- if(ret) {
- FT6336U_ERR("ft6336u_configure_dev failed.\n");
- goto exit;
- }
- return 0;
- exit:
- vPortFree(ts);
- return -1;
- }
- int ft6336u_init(void)
- {
- struct i2c_adapter *adap = NULL;
- if(!(adap = i2c_open("i2c0"))) {
- FT6336U_ERR("open i2c0 fail.\n");
- return -1;
- }
- if(ft6336u_ts_probe(adap)) {
- FT6336U_ERR("ft6336u probe fail\n");
- i2c_close(adap);
- return -1;
- }
- return 0;
- }
- #endif
|