第一次提交
This commit is contained in:
365
e3_176_ref-buding/components/touch/focaltech.c
Normal file
365
e3_176_ref-buding/components/touch/focaltech.c
Normal file
@@ -0,0 +1,365 @@
|
||||
/**
|
||||
* @file focaltech.c
|
||||
* @focaltech touch ic driver file.
|
||||
*
|
||||
* @Copyright (c) 2022 Semidrive Semiconductor.
|
||||
* @All rights reserved.
|
||||
*
|
||||
**/
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
#include <debug.h>
|
||||
#include <task.h>
|
||||
#include "event_groups.h"
|
||||
#include <sdrv_gpio.h>
|
||||
#include "focaltech.h"
|
||||
|
||||
#define FTS_INCELL 0x1
|
||||
#define FTS_CHIP_TYPE_MAPPING {{0x12, 0x72, 0x51, 0x72, 0x51, 0x72, 0xA1, 0x00, 0x00}}
|
||||
|
||||
#define FTS_ONE_TCH_LEN 6
|
||||
|
||||
#define FTS_TOUCH_X_H_POS 3
|
||||
#define FTS_TOUCH_X_L_POS 4
|
||||
#define FTS_TOUCH_Y_H_POS 5
|
||||
#define FTS_TOUCH_Y_L_POS 6
|
||||
#define FTS_TOUCH_POINT_NUM 2
|
||||
#define FTS_TOUCH_EVENT_POS 3
|
||||
#define FTS_TOUCH_ID_POS 5
|
||||
|
||||
/*register address*/
|
||||
#define FTS_REG_INT_CNT 0x8F
|
||||
#define FTS_REG_FLOW_WORK_CNT 0x91
|
||||
#define FTS_REG_WORKMODE 0x00
|
||||
#define FTS_REG_WORKMODE_FACTORY_VALUE 0x40
|
||||
#define FTS_REG_WORKMODE_WORK_VALUE 0x00
|
||||
#define FTS_REG_ESDCHECK_DISABLE 0x8D
|
||||
#define FTS_REG_CHIP_ID 0xA3
|
||||
#define FTS_REG_CHIP_ID2 0x9F
|
||||
#define FTS_REG_POWER_MODE 0xA5
|
||||
#define FTS_REG_POWER_MODE_SLEEP 0x03
|
||||
#define FTS_REG_FW_VER 0xA6
|
||||
#define FTS_REG_VENDOR_ID 0xA8
|
||||
#define FTS_REG_LCD_BUSY_NUM 0xAB
|
||||
#define FTS_REG_FACE_DEC_MODE_EN 0xB0
|
||||
#define FTS_REG_FACTORY_MODE_DETACH_FLAG 0xB4
|
||||
#define FTS_REG_FACE_DEC_MODE_STATUS 0x01
|
||||
#define FTS_REG_IDE_PARA_VER_ID 0xB5
|
||||
#define FTS_REG_IDE_PARA_STATUS 0xB6
|
||||
#define FTS_REG_GLOVE_MODE_EN 0xC0
|
||||
#define FTS_REG_COVER_MODE_EN 0xC1
|
||||
#define FTS_REG_CHARGER_MODE_EN 0x8B
|
||||
#define FTS_REG_GESTURE_EN 0xD0
|
||||
#define FTS_REG_GESTURE_OUTPUT_ADDRESS 0xD3
|
||||
#define FTS_REG_MODULE_ID 0xE3
|
||||
#define FTS_REG_LIC_VER 0xE4
|
||||
#define FTS_REG_ESD_SATURATE 0xED
|
||||
|
||||
struct ft_chip_t {
|
||||
uint32_t type;
|
||||
uint8_t chip_idh;
|
||||
uint8_t chip_idl;
|
||||
uint8_t rom_idh;
|
||||
uint8_t rom_idl;
|
||||
uint8_t pb_idh;
|
||||
uint8_t pb_idl;
|
||||
uint8_t bl_idh;
|
||||
uint8_t bl_idl;
|
||||
};
|
||||
|
||||
struct fts_data {
|
||||
struct ft_chip_t ids;
|
||||
touch_dev_t *ts_dev;
|
||||
EventGroupHandle_t ts_event;
|
||||
} g_fts;
|
||||
|
||||
int fts_read(struct fts_data *fts, uint8_t *cmd, uint32_t cmdlen,
|
||||
uint8_t *data, uint8_t datalen)
|
||||
{
|
||||
int ret = 0;
|
||||
sdrv_i2cdrv_bus_stat_t bus_stat;
|
||||
sdrv_i2cdrv_trans_stat_t trans_stat;
|
||||
sdrv_i2c_t *ctrl = fts->ts_dev->i2c_ctrl;
|
||||
int addr = fts->ts_dev->i2c_addr;
|
||||
|
||||
/* get bus stat, if busy can not use */
|
||||
bus_stat = sdrv_i2c_get_bus_stat(ctrl);
|
||||
if (bus_stat == SDRV_I2CDRV_BUS_BUSY) {
|
||||
ssdk_printf(SSDK_CRIT, "i2c ctrl %u busy\r\n", ctrl->cfg->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set bus stat to busy indicate bus be occupied now */
|
||||
ret = sdrv_i2c_set_bus_stat(ctrl, SDRV_I2CDRV_BUS_BUSY);
|
||||
if (ret < 0) {
|
||||
ssdk_printf(SSDK_CRIT, "i2c ctrl %u set bus stat fail\r\n",
|
||||
ctrl->cfg->id);
|
||||
return -2;
|
||||
}
|
||||
|
||||
sdrv_i2c_write(ctrl, addr, cmd, cmdlen, 1000, false);
|
||||
|
||||
trans_stat = sdrv_i2c_get_trans_stat(ctrl);
|
||||
if (trans_stat != SDRV_I2CDRV_TRANS_OK) {
|
||||
ssdk_printf(SSDK_CRIT, "%s write fail\r\n", __func__);
|
||||
ret = -3;
|
||||
goto end;
|
||||
}
|
||||
|
||||
sdrv_i2c_read(ctrl, addr, data, datalen, 1000, true);
|
||||
|
||||
trans_stat = sdrv_i2c_get_trans_stat(ctrl);
|
||||
if (trans_stat != SDRV_I2CDRV_TRANS_OK) {
|
||||
ssdk_printf(SSDK_CRIT, "%s, read fail\r\n", __func__);
|
||||
ret = -4;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
sdrv_i2c_set_bus_stat(ctrl, SDRV_I2CDRV_BUS_IDLE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fts_write(struct fts_data *fts, uint8_t *buf, uint32_t len)
|
||||
{
|
||||
int ret = 0;
|
||||
sdrv_i2cdrv_bus_stat_t bus_stat;
|
||||
sdrv_i2cdrv_trans_stat_t trans_stat;
|
||||
sdrv_i2c_t *ctrl = fts->ts_dev->i2c_ctrl;
|
||||
int addr = fts->ts_dev->i2c_addr;
|
||||
|
||||
/* get bus stat, if busy can not use */
|
||||
bus_stat = sdrv_i2c_get_bus_stat(ctrl);
|
||||
if (bus_stat == SDRV_I2CDRV_BUS_BUSY) {
|
||||
ssdk_printf(SSDK_CRIT, "i2c ctrl %u busy\r\n", ctrl->cfg->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set bus stat to busy indicate bus be occupied now */
|
||||
ret = sdrv_i2c_set_bus_stat(ctrl, SDRV_I2CDRV_BUS_BUSY);
|
||||
if (ret < 0) {
|
||||
ssdk_printf(SSDK_CRIT, "i2c ctrl %u set bus stat fail\r\n",
|
||||
ctrl->cfg->id);
|
||||
return -2;
|
||||
}
|
||||
|
||||
sdrv_i2c_write(ctrl, addr, buf, len, 1000, true);
|
||||
|
||||
trans_stat = sdrv_i2c_get_trans_stat(ctrl);
|
||||
if (trans_stat != SDRV_I2CDRV_TRANS_OK) {
|
||||
ssdk_printf(SSDK_CRIT, "%s write fail\r\n", __func__);
|
||||
ret = -3;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
sdrv_i2c_set_bus_stat(ctrl, SDRV_I2CDRV_BUS_IDLE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fts_read_reg(struct fts_data *fts, uint8_t addr, uint8_t *value)
|
||||
{
|
||||
return fts_read(fts, &addr, 1, value, 1);
|
||||
}
|
||||
|
||||
int fts_write_reg(struct fts_data *fts, uint8_t addr, uint8_t value)
|
||||
{
|
||||
uint8_t buf[2] = {0};
|
||||
|
||||
buf[0] = addr;
|
||||
buf[1] = value;
|
||||
return fts_write(fts, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static int fts_get_chip_types(struct fts_data *fts,
|
||||
uint8_t id_h, uint8_t id_l, bool fw_valid)
|
||||
{
|
||||
int i = 0;
|
||||
struct ft_chip_t ctype[] = FTS_CHIP_TYPE_MAPPING;
|
||||
uint32_t ctype_entries = sizeof(ctype) / sizeof(struct ft_chip_t);
|
||||
|
||||
if ((0x0 == id_h) || (0x0 == id_l)) {
|
||||
ssdk_printf(SSDK_ERR, "id_h/id_l is 0\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < ctype_entries; i++) {
|
||||
if (true == fw_valid) {
|
||||
if ((id_h == ctype[i].chip_idh) && (id_l == ctype[i].chip_idl))
|
||||
break;
|
||||
} else {
|
||||
if (((id_h == ctype[i].rom_idh) && (id_l == ctype[i].rom_idl))
|
||||
|| ((id_h == ctype[i].pb_idh) && (id_l == ctype[i].pb_idl))
|
||||
|| ((id_h == ctype[i].bl_idh) && (id_l == ctype[i].bl_idl)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= ctype_entries) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
fts->ids = ctype[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fts_get_ic_info(struct fts_data *fts)
|
||||
{
|
||||
int ret = 0;
|
||||
int cnt = 0;
|
||||
uint8_t chip_id[2] = {0};
|
||||
|
||||
do {
|
||||
ret = fts_read_reg(fts, FTS_REG_CHIP_ID, &chip_id[0]);
|
||||
ret = fts_read_reg(fts, FTS_REG_CHIP_ID2, &chip_id[1]);
|
||||
if (ret < 0) {
|
||||
ssdk_printf(SSDK_ERR, "i2c read chip fail\r\n");
|
||||
} else {
|
||||
ret = fts_get_chip_types(fts, chip_id[0], chip_id[1], true);
|
||||
if (!ret)
|
||||
break;
|
||||
else
|
||||
ssdk_printf(SSDK_ERR, "TP not ready, read:0x%02x%02x",
|
||||
chip_id[0], chip_id[1]);
|
||||
}
|
||||
|
||||
ts_mdelay(100);
|
||||
} while (++cnt < 3);
|
||||
|
||||
if (cnt >= 3) {
|
||||
ssdk_printf(SSDK_ERR, "%s: read chip id fail\r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssdk_printf(SSDK_ERR, "%s: chip id = 0x%02x%02x\r\n", __func__,
|
||||
fts->ids.chip_idh, fts->ids.chip_idl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fts_reset_device(struct fts_data *fts)
|
||||
{
|
||||
sdrv_gpio_set_pin_output_level(fts->ts_dev->rst, true);
|
||||
ts_mdelay(10);
|
||||
sdrv_gpio_set_pin_output_level(fts->ts_dev->irq, false);
|
||||
ts_mdelay(2);
|
||||
sdrv_gpio_set_pin_output_level(fts->ts_dev->rst, true);
|
||||
ts_mdelay(100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fts_thread(void *arg)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
int base;
|
||||
int point_num;
|
||||
int point_num_down;
|
||||
int point_num_flag[10];
|
||||
struct fts_data *fts = arg;
|
||||
uint8_t buf[FTS_ONE_TCH_LEN * 10 + 4];
|
||||
|
||||
touch_data_t *sdrv_datap = sdrv_touch_data_pointer();
|
||||
|
||||
while (1) {
|
||||
xEventGroupWaitBits(fts->ts_event, 1, pdTRUE, pdFAIL, portMAX_DELAY);
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
buf[i] = 0xff;
|
||||
|
||||
buf[0] = 0x01;
|
||||
|
||||
ret = fts_read(fts, buf, 1, buf + 1, 63);
|
||||
if (ret < 0) {
|
||||
ssdk_printf(SSDK_ERR, "read touch data failed, ret:%d", ret);
|
||||
sdrv_gpio_pin_interrupt_enable(fts->ts_dev->irq);
|
||||
continue;
|
||||
}
|
||||
|
||||
point_num = buf[FTS_TOUCH_POINT_NUM] & 0x0F;
|
||||
|
||||
if (FTS_INCELL) {
|
||||
if ((point_num == 0x0F) && (buf[2] == 0xFF) && (buf[3] == 0xFF)
|
||||
&& (buf[4] == 0xFF) && (buf[5] == 0xFF) && (buf[6] == 0xFF)) {
|
||||
ssdk_printf(SSDK_ERR, "buf is 0xff, need recovery state\r\n");
|
||||
//fts_release_all_finger();
|
||||
//fts_tp_state_recovery(data);
|
||||
sdrv_gpio_pin_interrupt_enable(fts->ts_dev->irq);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
point_num_down = point_num;
|
||||
|
||||
for (i = 0; i < point_num; i++) {
|
||||
base = FTS_ONE_TCH_LEN * i;
|
||||
sdrv_datap->touch_point[i].id = (buf[FTS_TOUCH_ID_POS + base]) >> 4;
|
||||
sdrv_datap->touch_point[i].x = ((buf[FTS_TOUCH_X_H_POS + base] & 0x0F) << 8) +
|
||||
(buf[FTS_TOUCH_X_L_POS + base] & 0xFF);
|
||||
sdrv_datap->touch_point[i].y = ((buf[FTS_TOUCH_Y_H_POS + base] & 0x0F) << 8) +
|
||||
(buf[FTS_TOUCH_Y_L_POS + base] & 0xFF);
|
||||
point_num_flag[i] = buf[FTS_TOUCH_EVENT_POS + base] >> 6;
|
||||
if (point_num_flag[i] == 1)
|
||||
point_num_down--;
|
||||
}
|
||||
|
||||
sdrv_datap->touch_num = point_num_down;
|
||||
#if 0
|
||||
for (i = 0; i < point_num; i++) {
|
||||
ssdk_printf(SSDK_ERR, "%s, num=%d, id=%d, x=%d, y=%d, flag=%d\r\n", __func__,
|
||||
sdrv_datap->touch_num, sdrv_datap->touch_point[i].id,
|
||||
sdrv_datap->touch_point[i].x, sdrv_datap->touch_point[i].y,
|
||||
point_num_flag[i]);
|
||||
}
|
||||
#endif
|
||||
sdrv_gpio_pin_interrupt_enable(fts->ts_dev->irq);
|
||||
}
|
||||
}
|
||||
|
||||
static void fts_irq_handler(uint32_t irq, uint32_t pin, void *arg)
|
||||
{
|
||||
BaseType_t yield = pdFALSE;
|
||||
struct fts_data *fts = (struct fts_data *)arg;
|
||||
|
||||
sdrv_gpio_pin_interrupt_disable(fts->ts_dev->irq);
|
||||
//ssdk_printf(SSDK_ERR, "%s\r\n", __func__);
|
||||
|
||||
if (xEventGroupSetBitsFromISR(fts->ts_event, 1, &yield) != pdFAIL)
|
||||
portYIELD_FROM_ISR (yield);
|
||||
}
|
||||
|
||||
static int fts_config_device(struct fts_data *fts)
|
||||
{
|
||||
fts->ts_event = xEventGroupCreate();
|
||||
xTaskCreate(fts_thread, "focaltech", configTASK_IDLE_STACK_SIZE, fts,
|
||||
(tskIDLE_PRIORITY + 2), NULL);
|
||||
sdrv_gpio_set_pin_interrupt(fts->ts_dev->irq, GPIO_INTR_FALLING_EDGE);
|
||||
sdrv_gpio_register_interrupt_handler(fts->ts_dev->irq, fts_irq_handler, fts);
|
||||
sdrv_gpio_pin_interrupt_enable(fts->ts_dev->irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int focaltech_touch_init(touch_dev_t *touch_dev)
|
||||
{
|
||||
int ret = 0;
|
||||
g_fts.ts_dev = touch_dev;
|
||||
|
||||
fts_reset_device(&g_fts);
|
||||
|
||||
ret = fts_get_ic_info(&g_fts);
|
||||
if (ret) {
|
||||
ssdk_printf(SSDK_ERR, "%s: read chip id fail\r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = fts_config_device(&g_fts);
|
||||
if (ret) {
|
||||
ssdk_printf(SSDK_ERR, "%s: confif device fail\r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssdk_printf(SSDK_ERR, "%s, ===done ok===\r\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
17
e3_176_ref-buding/components/touch/focaltech.h
Normal file
17
e3_176_ref-buding/components/touch/focaltech.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @file focaltech.h
|
||||
* @focaltech touch ic head file.
|
||||
*
|
||||
* @Copyright (c) 2022 Semidrive Semiconductor.
|
||||
* @All rights reserved.
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef FOCALTECH_DRV_H_
|
||||
#define FOCALTECH_DRV_H_
|
||||
|
||||
#include "touch_dev.h"
|
||||
|
||||
extern int focaltech_touch_init(touch_dev_t *touch_dev);
|
||||
|
||||
#endif
|
||||
278
e3_176_ref-buding/components/touch/goodix.c
Normal file
278
e3_176_ref-buding/components/touch/goodix.c
Normal file
@@ -0,0 +1,278 @@
|
||||
/**
|
||||
* @file goodix.c
|
||||
* @goodix touch ic driver file.
|
||||
*
|
||||
* @Copyright (c) 2022 Semidrive Semiconductor.
|
||||
* @All rights reserved.
|
||||
*
|
||||
**/
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
#include <debug.h>
|
||||
#include <task.h>
|
||||
#include "event_groups.h"
|
||||
#include <sdrv_gpio.h>
|
||||
#include "goodix.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define GOODIX_CONTACT_SIZE 8
|
||||
#define GOODIX_MAX_CONTACTS 10
|
||||
#define GOODIX_VENDOR_ID 0x0416
|
||||
#define GTP_READ_COOR_ADDR 0x814E
|
||||
#define GOODIX_REG_ID 0x8140
|
||||
|
||||
struct goodix_ts_data {
|
||||
int id;
|
||||
int version;
|
||||
int vendor;
|
||||
touch_dev_t *ts_dev;
|
||||
EventGroupHandle_t ts_event;
|
||||
} g_goodix;
|
||||
|
||||
int goodix_i2c_read(struct goodix_ts_data *goodix, uint8_t *buf, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
sdrv_i2cdrv_bus_stat_t bus_stat;
|
||||
sdrv_i2cdrv_trans_stat_t trans_stat;
|
||||
sdrv_i2c_t *ctrl = goodix->ts_dev->i2c_ctrl;
|
||||
int addr = goodix->ts_dev->i2c_addr;
|
||||
|
||||
/* get bus stat, if busy can not use */
|
||||
bus_stat = sdrv_i2c_get_bus_stat(ctrl);
|
||||
if (bus_stat == SDRV_I2CDRV_BUS_BUSY) {
|
||||
ssdk_printf(SSDK_CRIT, "i2c ctrl %u busy\r\n", ctrl->cfg->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set bus stat to busy indicate bus be occupied now */
|
||||
ret = sdrv_i2c_set_bus_stat(ctrl, SDRV_I2CDRV_BUS_BUSY);
|
||||
if (ret < 0) {
|
||||
ssdk_printf(SSDK_CRIT, "i2c ctrl %u set bus stat fail\r\n",
|
||||
ctrl->cfg->id);
|
||||
return -2;
|
||||
}
|
||||
|
||||
sdrv_i2c_write(ctrl, addr, buf, 2, 1000, false);
|
||||
|
||||
trans_stat = sdrv_i2c_get_trans_stat(ctrl);
|
||||
if (trans_stat != SDRV_I2CDRV_TRANS_OK) {
|
||||
ssdk_printf(SSDK_CRIT, "%s write fail\r\n", __func__);
|
||||
ret = -3;
|
||||
goto end;
|
||||
}
|
||||
|
||||
sdrv_i2c_read(ctrl, addr, buf + 2, len - 2, 1000, true);
|
||||
|
||||
trans_stat = sdrv_i2c_get_trans_stat(ctrl);
|
||||
if (trans_stat != SDRV_I2CDRV_TRANS_OK) {
|
||||
ssdk_printf(SSDK_CRIT, "%s, read fail\r\n", __func__);
|
||||
ret = -4;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
sdrv_i2c_set_bus_stat(ctrl, SDRV_I2CDRV_BUS_IDLE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int goodix_i2c_write(struct goodix_ts_data *goodix, uint8_t *buf, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
sdrv_i2cdrv_bus_stat_t bus_stat;
|
||||
sdrv_i2cdrv_trans_stat_t trans_stat;
|
||||
sdrv_i2c_t *ctrl = goodix->ts_dev->i2c_ctrl;
|
||||
int addr = goodix->ts_dev->i2c_addr;
|
||||
|
||||
/* get bus stat, if busy can not use */
|
||||
bus_stat = sdrv_i2c_get_bus_stat(ctrl);
|
||||
if (bus_stat == SDRV_I2CDRV_BUS_BUSY) {
|
||||
ssdk_printf(SSDK_CRIT, "i2c ctrl %u busy\r\n", ctrl->cfg->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set bus stat to busy indicate bus be occupied now */
|
||||
ret = sdrv_i2c_set_bus_stat(ctrl, SDRV_I2CDRV_BUS_BUSY);
|
||||
if (ret < 0) {
|
||||
ssdk_printf(SSDK_CRIT, "i2c ctrl %u set bus stat fail\r\n",
|
||||
ctrl->cfg->id);
|
||||
return -2;
|
||||
}
|
||||
|
||||
sdrv_i2c_write(ctrl, addr, buf, len, 1000, true);
|
||||
|
||||
trans_stat = sdrv_i2c_get_trans_stat(ctrl);
|
||||
if (trans_stat != SDRV_I2CDRV_TRANS_OK) {
|
||||
ssdk_printf(SSDK_CRIT, "%s write fail\r\n", __func__);
|
||||
ret = -3;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
sdrv_i2c_set_bus_stat(ctrl, SDRV_I2CDRV_BUS_IDLE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int goodix_read_version(struct goodix_ts_data *goodix)
|
||||
{
|
||||
uint8_t data[8] = {GOODIX_REG_ID >> 8, GOODIX_REG_ID & 0xFF};
|
||||
char id_str[5];
|
||||
int id, version;
|
||||
|
||||
goodix_i2c_read(goodix, data, 8);
|
||||
|
||||
//ssdk_printf(SSDK_ERR, "%s: %#x, %#x, %#x, %#x, %#x, %#x\r\n", __func__,
|
||||
// data[2], data[3], data[4], data[5], data[6], data[7]);
|
||||
|
||||
memcpy(id_str, data + 2, 4);
|
||||
id = atoi(id_str);
|
||||
version = data[6] + (data[7] << 8);
|
||||
|
||||
if (!id)
|
||||
return -1;
|
||||
else {
|
||||
goodix->id = id;
|
||||
goodix->version = version;
|
||||
goodix->vendor = GOODIX_VENDOR_ID;
|
||||
}
|
||||
|
||||
ssdk_printf(SSDK_ERR, "%s: id:%d, version:%#x\r\n", __func__, id, version);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int goodix_reset_device(struct goodix_ts_data *goodix)
|
||||
{
|
||||
sdrv_gpio_set_pin_output_level(goodix->ts_dev->rst, false);
|
||||
sdrv_gpio_set_pin_output_level(goodix->ts_dev->irq, false);
|
||||
//sdrv_gpio_set_pin_output_level(goodix->ts_dev->irq,
|
||||
// (goodix->ts_dev->i2c_addr == 0x14));
|
||||
ts_mdelay(10);
|
||||
sdrv_gpio_set_pin_output_level(goodix->ts_dev->rst, true);
|
||||
//ts_mdelay(20);
|
||||
//sdrv_gpio_set_pin_output_level(goodix->ts_dev->irq, false);
|
||||
ts_mdelay(50);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int goodix_ts_read_input_report(struct goodix_ts_data *goodix, uint8_t *data)
|
||||
{
|
||||
int count = 0;
|
||||
int touch_num = 0;
|
||||
uint8_t end_cmd[3] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0};
|
||||
/* store first finger point */
|
||||
uint8_t point_data[11] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF};
|
||||
/* store second~tenth finger point, if do have */
|
||||
uint8_t point_data1[74] = {GTP_READ_COOR_ADDR >> 8, (GTP_READ_COOR_ADDR + 1 + GOODIX_CONTACT_SIZE) & 0xFF};
|
||||
|
||||
if (!goodix)
|
||||
return -1;
|
||||
|
||||
while (count < 10) {
|
||||
goodix_i2c_read(goodix, point_data, 11);
|
||||
|
||||
if (point_data[2] & (0x1 << 7)) {
|
||||
touch_num = point_data[2] & 0xf;
|
||||
memcpy(data, point_data + 2, 9);
|
||||
|
||||
if (touch_num > 1) {
|
||||
goodix_i2c_read(goodix, point_data1, 2 + GOODIX_CONTACT_SIZE * (touch_num - 1));
|
||||
memcpy(data + 9, point_data1 + 2, GOODIX_CONTACT_SIZE * (touch_num - 1));
|
||||
}
|
||||
|
||||
goodix_i2c_write(goodix, end_cmd, 3);
|
||||
return touch_num;
|
||||
}
|
||||
|
||||
count++;
|
||||
ts_mdelay(2);
|
||||
}
|
||||
|
||||
goodix_i2c_write(goodix, end_cmd, 3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void goodix_ts_thread(void *arg)
|
||||
{
|
||||
struct goodix_ts_data *goodix = arg;
|
||||
uint8_t pdata[81] = {0,};
|
||||
int touch_num;
|
||||
|
||||
touch_data_t *sdrv_datap = sdrv_touch_data_pointer();
|
||||
|
||||
while (1) {
|
||||
xEventGroupWaitBits(goodix->ts_event, 1, pdTRUE, pdFAIL, portMAX_DELAY);
|
||||
|
||||
touch_num = goodix_ts_read_input_report(goodix, pdata);
|
||||
|
||||
ssdk_printf(SSDK_ERR, "%s: 0x%x, (0x%x, 0x%x, 0x%x, 0x%x)\r\n",
|
||||
__func__, pdata[0], pdata[3], pdata[2], pdata[5], pdata[4]);
|
||||
|
||||
if ((touch_num < 0) || (pdata[0] == 0)) {
|
||||
sdrv_gpio_pin_interrupt_enable(goodix->ts_dev->irq);
|
||||
continue;
|
||||
}
|
||||
|
||||
sdrv_datap->touch_num = touch_num;
|
||||
|
||||
for (int j = 0; j < touch_num; j++) {
|
||||
sdrv_datap->touch_point[j].id = *((uint8_t *)(pdata + 1 + GOODIX_CONTACT_SIZE * j));
|
||||
sdrv_datap->touch_point[j].x = *((uint16_t *)(pdata + 2 + GOODIX_CONTACT_SIZE * j));
|
||||
sdrv_datap->touch_point[j].y = *((uint16_t *)(pdata + 4 + GOODIX_CONTACT_SIZE * j));
|
||||
}
|
||||
|
||||
sdrv_gpio_pin_interrupt_enable(goodix->ts_dev->irq);
|
||||
}
|
||||
}
|
||||
|
||||
static void goodix_irq_handler(uint32_t irq, uint32_t pin, void *arg)
|
||||
{
|
||||
BaseType_t yield = pdFALSE;
|
||||
struct goodix_ts_data *goodix = (struct goodix_ts_data *)arg;
|
||||
|
||||
sdrv_gpio_pin_interrupt_disable(goodix->ts_dev->irq);
|
||||
|
||||
if (xEventGroupSetBitsFromISR(goodix->ts_event, 1, &yield) != pdFAIL)
|
||||
portYIELD_FROM_ISR (yield);
|
||||
}
|
||||
|
||||
static int goodix_config_device(struct goodix_ts_data *goodix)
|
||||
{
|
||||
goodix->ts_event = xEventGroupCreate();
|
||||
xTaskCreate(goodix_ts_thread, "goodix", configTASK_IDLE_STACK_SIZE, goodix,
|
||||
(tskIDLE_PRIORITY + 2), NULL);
|
||||
sdrv_gpio_set_pin_interrupt(goodix->ts_dev->irq, GPIO_INTR_FALLING_EDGE);
|
||||
sdrv_gpio_register_interrupt_handler(goodix->ts_dev->irq, goodix_irq_handler, goodix);
|
||||
sdrv_gpio_pin_interrupt_enable(goodix->ts_dev->irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int goodix_touch_init(touch_dev_t *touch_dev)
|
||||
{
|
||||
int ret = 0;
|
||||
int retry = 0;
|
||||
g_goodix.ts_dev = touch_dev;
|
||||
|
||||
do {
|
||||
goodix_reset_device(&g_goodix);
|
||||
|
||||
if (!goodix_read_version(&g_goodix))
|
||||
break;
|
||||
} while (++retry < 3);
|
||||
|
||||
if (retry >= 3) {
|
||||
ssdk_printf(SSDK_ERR, "%s: read version fail\r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = goodix_config_device(&g_goodix);
|
||||
if (ret) {
|
||||
ssdk_printf(SSDK_ERR, "%s: config device fail\r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssdk_printf(SSDK_ERR, "%s, ===done ok===\r\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
17
e3_176_ref-buding/components/touch/goodix.h
Normal file
17
e3_176_ref-buding/components/touch/goodix.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @file goodix.h
|
||||
* @goodix touch ic head file.
|
||||
*
|
||||
* @Copyright (c) 2022 Semidrive Semiconductor.
|
||||
* @All rights reserved.
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef GOODIX_DRV_H_
|
||||
#define GOODIX_DRV_H_
|
||||
|
||||
#include "touch_dev.h"
|
||||
|
||||
extern int goodix_touch_init(touch_dev_t *touch_dev);
|
||||
|
||||
#endif
|
||||
50
e3_176_ref-buding/components/touch/touch_dev.c
Normal file
50
e3_176_ref-buding/components/touch/touch_dev.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @file touch_dev.c
|
||||
* @touch dev source file.
|
||||
*
|
||||
* @Copyright (c) 2022 Semidrive Semiconductor.
|
||||
* @All rights reserved.
|
||||
*
|
||||
**/
|
||||
|
||||
#include <debug.h>
|
||||
#include "touch_cfg.h"
|
||||
#include <string.h>
|
||||
|
||||
//#define GOODIX
|
||||
#define FOCALTECH
|
||||
|
||||
#ifdef GOODIX
|
||||
#include "goodix.h"
|
||||
#endif
|
||||
|
||||
#ifdef FOCALTECH
|
||||
#include "focaltech.h"
|
||||
#endif
|
||||
|
||||
touch_data_t g_touch_data = {0};
|
||||
|
||||
int sdrv_touch_init(sdrv_i2c_t *i2c_ctrl)
|
||||
{
|
||||
int ret = -1;
|
||||
g_touch_dev.i2c_ctrl = i2c_ctrl;
|
||||
|
||||
#ifdef GOODIX
|
||||
if (!strcmp(g_touch_dev.name, "goodix"))
|
||||
ret = goodix_touch_init(&g_touch_dev);
|
||||
#endif
|
||||
|
||||
#ifdef FOCALTECH
|
||||
if (!strcmp(g_touch_dev.name, "focaltech"))
|
||||
ret = focaltech_touch_init(&g_touch_dev);
|
||||
#endif
|
||||
|
||||
ssdk_printf(SSDK_ERR, "%s, %s\r\n", __func__, ret?"fail":"pass");
|
||||
return ret;
|
||||
}
|
||||
|
||||
touch_data_t *sdrv_touch_data_pointer(void)
|
||||
{
|
||||
return &g_touch_data;
|
||||
}
|
||||
|
||||
40
e3_176_ref-buding/components/touch/touch_dev.h
Normal file
40
e3_176_ref-buding/components/touch/touch_dev.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @file touch_dev.h
|
||||
* @touch dev head file.
|
||||
*
|
||||
* @Copyright (c) 2022 Semidrive Semiconductor.
|
||||
* @All rights reserved.
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef TOUCH_DEV_H_
|
||||
#define TOUCH_DEV_H_
|
||||
|
||||
#include <sdrv_i2c.h>
|
||||
#include <udelay/udelay.h>
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
sdrv_i2c_t *i2c_ctrl;
|
||||
int i2c_addr;
|
||||
int irq;
|
||||
int rst;
|
||||
} touch_dev_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t id;
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} touch_point_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t touch_num;
|
||||
touch_point_t touch_point[10];
|
||||
} touch_data_t;
|
||||
|
||||
#define ts_mdelay(x) udelay(x * 1000)
|
||||
|
||||
extern touch_data_t *sdrv_touch_data_pointer(void);
|
||||
extern int sdrv_touch_init(sdrv_i2c_t *i2c_ctrl);
|
||||
|
||||
#endif
|
||||
39
e3_176_ref-buding/components/touch/touch_drv.c
Normal file
39
e3_176_ref-buding/components/touch/touch_drv.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file touch_drv.c
|
||||
* @touch driver source file.
|
||||
*
|
||||
* @Copyright (c) 2022 Semidrive Semiconductor.
|
||||
* @All rights reserved.
|
||||
*
|
||||
**/
|
||||
|
||||
#include "touch_drv.h"
|
||||
#include "touch_dev.h"
|
||||
|
||||
static bool touch_init_stat = false;
|
||||
|
||||
bool touch_get_event(int *x, int *y, int *id)
|
||||
{
|
||||
if (!touch_init_stat)
|
||||
return false;
|
||||
|
||||
touch_data_t *data_p = sdrv_touch_data_pointer();
|
||||
|
||||
if (!data_p->touch_num)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < 1; i++) {
|
||||
*x = data_p->touch_point[i].x;
|
||||
*y = data_p->touch_point[i].y;
|
||||
*id = data_p->touch_point[i].id;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void board_touch_init(sdrv_i2c_t *i2c_ctrl)
|
||||
{
|
||||
if (!sdrv_touch_init(i2c_ctrl))
|
||||
touch_init_stat = true;
|
||||
}
|
||||
|
||||
18
e3_176_ref-buding/components/touch/touch_drv.h
Normal file
18
e3_176_ref-buding/components/touch/touch_drv.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @file touch_drv.h
|
||||
* @touch driver head file.
|
||||
*
|
||||
* @Copyright (c) 2022 Semidrive Semiconductor.
|
||||
* @All rights reserved.
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef TOUCH_DRV_H_
|
||||
#define TOUCH_DRV_H_
|
||||
|
||||
#include <sdrv_i2c.h>
|
||||
|
||||
extern bool touch_get_event(int *x, int *y, int *id);
|
||||
extern void board_touch_init( sdrv_i2c_t *i2c_ctrl);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user