469 lines
12 KiB
C
469 lines
12 KiB
C
#include "system/includes.h"
|
|
#include "asm/port_waked_up.h"
|
|
#include "typedef.h"
|
|
#include "os/os_api.h"
|
|
#include "asm/iic.h"
|
|
#include "device/iic.h"
|
|
#include "device/device.h"
|
|
#include "lcd_config.h"
|
|
#include "app_config.h"
|
|
#include "system/includes.h"
|
|
#include "gpio.h"
|
|
#include "ui_api.h"
|
|
#include "touch_event.h"
|
|
#include "sys_common.h"
|
|
|
|
#if TCFG_TOUCH_FT6236_ENABLE
|
|
#define TEST 0
|
|
|
|
#if 1
|
|
#define log_info(x, ...) printf("\n[touch]>" x " \n", ## __VA_ARGS__)
|
|
#else
|
|
#define log_info(...)
|
|
#endif
|
|
|
|
struct touch_hdl {
|
|
u16 x;
|
|
u16 y;
|
|
u8 status;
|
|
};
|
|
struct touch_hdl lvgl_touch_hdl;
|
|
|
|
static OS_SEM touch_sem;
|
|
static u8 touch_en = 1 ;
|
|
|
|
void *get_touch_x_y(void)
|
|
{
|
|
return &lvgl_touch_hdl;
|
|
}
|
|
|
|
void get_touch_x_y_status(u16 *x, u16 *y, u8 *status)
|
|
{
|
|
#if HORIZONTAL_SCREEN==1
|
|
*x = lvgl_touch_hdl.y;
|
|
*y = 320 - lvgl_touch_hdl.x;
|
|
if (*y > LCD_H) {
|
|
*y = LCD_H;
|
|
}
|
|
#else
|
|
*x = lvgl_touch_hdl.x;
|
|
*y = lvgl_touch_hdl.y;
|
|
#endif
|
|
*status = lvgl_touch_hdl.status;
|
|
}
|
|
extern int ui_touch_msg_post(struct touch_event *event);
|
|
|
|
//I2C读写命令
|
|
#define FT6236_WRCMD 0X70 //写命令
|
|
#define FT6236_RDCMD 0X71 //读命令
|
|
|
|
#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_VALUE 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_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
|
|
|
|
static void *iic = NULL;
|
|
|
|
//I2C读写命令
|
|
#define FT_CMD_WR 0X70 //写命令
|
|
#define FT_CMD_RD 0X71 //读命令
|
|
//FT6236 部分寄存器定义
|
|
#define FT_DEVIDE_MODE 0x00 //FT6236模式控制寄存器
|
|
#define FT_REG_NUM_FINGER 0x02 //触摸状态寄存器
|
|
#define FT_TP1_REG 0X03 //第一个触摸点数据地址
|
|
|
|
#define FT_ID_G_LIB_VERSION 0xA1 //版本
|
|
#define FT_ID_G_MODE 0xA4 //FT6236中断模式控制寄存器
|
|
#define FT_ID_G_THGROUP 0x80 //触摸有效值设置寄存器
|
|
#define FT_ID_G_PERIODACTIVE 0x88 //激活状态周期设置寄存器
|
|
#define Chip_Vendor_ID 0xA3 //芯片ID(0x36)
|
|
#define ID_G_FT6236ID 0xA8 //0x11
|
|
|
|
#define Y_MIRROR 0
|
|
#define X_MIRROR 0
|
|
/*#define VK_Y LCD_W*/
|
|
/*#define VK_X LCD_H*/
|
|
#define VK_Y 480
|
|
#define VK_X 320
|
|
#define VK_Y_MOVE 50
|
|
#define VK_X_MOVE 50
|
|
#define VK_X_Y_DIFF 30
|
|
|
|
//由FT6236芯片手册查询得到各部分寄存器地址
|
|
#define FI_DEVIDE_MODE 0x00 //FT6236模式控制寄存器
|
|
#define FI_REG_NUM_FINGER 0x02 //触摸状态寄存器
|
|
|
|
#define FI_TP1_REG 0x03 //第一个触摸点数据地址
|
|
#define FI_TP2_REG 0x09 //第一个触摸点数据地址
|
|
#define FI_TP3_REG 0x0F //第一个触摸点数据地址
|
|
#define FI_TP4_REG 0x15 //第一个触摸点数据地址
|
|
#define FI_TP5_REG 0x1B //第一个触摸点数据地址
|
|
|
|
|
|
static u8 touch_status = 0;
|
|
static unsigned char wrFT6236Reg(u8 regID, unsigned char regDat)
|
|
{
|
|
u8 ret = 1;
|
|
|
|
dev_ioctl(iic, IIC_IOCTL_START, 0);
|
|
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_START_BIT, FT6236_WRCMD)) {
|
|
ret = 0;
|
|
log_info("iic write err!!! line : %d \n", __LINE__);
|
|
goto exit;
|
|
}
|
|
delay(100);
|
|
if (dev_ioctl(iic, IIC_IOCTL_TX, regID & 0xff)) {
|
|
ret = 0;
|
|
log_info("iic write err!!! line : %d \n", __LINE__);
|
|
goto exit;
|
|
}
|
|
delay(100);
|
|
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_STOP_BIT, regDat)) {
|
|
ret = 0;
|
|
log_info("iic write err!!! line : %d \n", __LINE__);
|
|
goto exit;
|
|
}
|
|
delay(100);
|
|
|
|
exit:
|
|
dev_ioctl(iic, IIC_IOCTL_STOP, 0);
|
|
return ret;
|
|
}
|
|
|
|
static unsigned char rdFT6236Reg(u8 regID, u8 *regDat)
|
|
{
|
|
u8 ret = 1;
|
|
dev_ioctl(iic, IIC_IOCTL_START, 0);
|
|
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_START_BIT, FT6236_WRCMD)) {
|
|
ret = 0;
|
|
log_info("iic write err!!! line : %d \n", __LINE__);
|
|
goto exit;
|
|
}
|
|
delay(100);
|
|
if (dev_ioctl(iic, IIC_IOCTL_TX, regID & 0xff)) {
|
|
ret = 0;;
|
|
log_info("iic write err!!! line : %d \n", __LINE__);
|
|
goto exit;
|
|
}
|
|
delay(100);
|
|
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_START_BIT, FT6236_RDCMD)) {
|
|
ret = 0;
|
|
goto exit;
|
|
}
|
|
delay(100);
|
|
dev_ioctl(iic, IIC_IOCTL_RX_WITH_STOP_BIT, (u32)regDat);
|
|
exit:
|
|
dev_ioctl(iic, IIC_IOCTL_STOP, 0);
|
|
return ret;
|
|
}
|
|
|
|
void set_touch_enable(void)
|
|
{
|
|
touch_en = 1;
|
|
}
|
|
|
|
void set_touch_disable(void)
|
|
{
|
|
touch_en = 0;
|
|
}
|
|
|
|
int get_FT6236_pid(void)
|
|
{
|
|
u8 temp = 0;
|
|
rdFT6236Reg(FTS_REG_CHIP_ID, &temp);
|
|
if (temp != 100) {
|
|
return 1;
|
|
}
|
|
log_info(">>>>>>>>>>>hell touch FT6236<<<<<<<<<<<");
|
|
return 0;
|
|
}
|
|
|
|
static void get_FT6236_xy(u16 addr, u16 *x, u16 *y)
|
|
{
|
|
u8 buf[4];
|
|
for (u8 i = 0; i < 4; i++) {
|
|
rdFT6236Reg((addr + i), &buf[i]); //读取XY坐标值
|
|
}
|
|
*y = (((u16)(buf[2] & 0X0F) << 8) + buf[3]);
|
|
*x = ((u16)(buf[0] & 0X0F) << 8) + buf[1];
|
|
}
|
|
|
|
static u8 tp_last_staus = ELM_EVENT_TOUCH_UP;
|
|
static int tp_down_cnt = 0;
|
|
|
|
static void tpd_down(int x, int y)
|
|
{
|
|
struct touch_event t;
|
|
static u8 move_flag = 0;
|
|
static int first_x = 0;
|
|
static int first_y = 0;
|
|
|
|
if (x < 0) {
|
|
x = 0;
|
|
}
|
|
if (x > (VK_X - 1)) {
|
|
x = VK_X - 1;
|
|
}
|
|
if (y < 0) {
|
|
y = 0;
|
|
}
|
|
if (y > (VK_Y - 1)) {
|
|
y = VK_Y - 1;
|
|
}
|
|
#if Y_MIRROR
|
|
x = VK_X - x - 1;
|
|
#endif
|
|
|
|
#if X_MIRROR
|
|
y = VK_Y - y - 1;
|
|
#endif
|
|
|
|
if ((tp_last_staus == ELM_EVENT_TOUCH_DOWN) && (x == first_x) && (y == first_y)) {
|
|
tp_down_cnt++;
|
|
if (tp_down_cnt < 30) {
|
|
return;
|
|
}
|
|
tp_last_staus = ELM_EVENT_TOUCH_HOLD;
|
|
tp_down_cnt = 0;
|
|
|
|
t.action = tp_last_staus;
|
|
#if HORIZONTAL_SCREEN
|
|
t.x = LCD_W - y;
|
|
t.y = x;
|
|
#else
|
|
t.x = x;
|
|
t.y = y;
|
|
#endif
|
|
log_info("----tpd_hold----x=%d, y=%d", x, y);
|
|
lvgl_touch_hdl.x = x;
|
|
lvgl_touch_hdl.y = y;
|
|
lvgl_touch_hdl.status = 1;
|
|
if (touch_en) {
|
|
ui_touch_msg_post(&t);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (tp_last_staus != ELM_EVENT_TOUCH_UP) {
|
|
int x_move = abs(x - first_x);
|
|
int y_move = abs(y - first_y);
|
|
|
|
if (!move_flag && (x_move >= VK_X_MOVE || y_move >= VK_Y_MOVE) && (abs(x_move - y_move) >= VK_X_Y_DIFF)) {
|
|
if (x_move > y_move) {
|
|
if (x > first_x) {
|
|
tp_last_staus = ELM_EVENT_TOUCH_R_MOVE;
|
|
log_info("----tpd_rigth_move----x=%d, y=%d", x, y);
|
|
} else {
|
|
tp_last_staus = ELM_EVENT_TOUCH_L_MOVE;
|
|
log_info("----tpd_left_move----x=%d, y=%d", x, y);
|
|
}
|
|
|
|
} else {
|
|
if (y > first_y) {
|
|
tp_last_staus = ELM_EVENT_TOUCH_D_MOVE;
|
|
log_info("----tpd_down_move----x=%d, y=%d", x, y);
|
|
} else {
|
|
tp_last_staus = ELM_EVENT_TOUCH_U_MOVE;
|
|
log_info("----tpd_up_move----x=%d, y=%d", x, y);
|
|
}
|
|
}
|
|
move_flag = 1;
|
|
} else {
|
|
if ((x == first_x) && (y == first_y)) {
|
|
return;
|
|
}
|
|
tp_last_staus = ELM_EVENT_TOUCH_MOVE;
|
|
log_info("----tpd_move----x=%d, y=%d", x, y);
|
|
}
|
|
#if HORIZONTAL_SCREEN
|
|
t.x = LCD_W - y;
|
|
t.y = x;
|
|
#else
|
|
t.x = x;
|
|
t.y = y;
|
|
#endif
|
|
#if defined USE_GUIX_UI_DEMO
|
|
gx_jl_touch_event_process(t.x, t.y, 2);
|
|
#endif
|
|
#if defined USE_UGFX_UI_DEMO
|
|
ugfx_touch_event_process(t.x, t.y, 2);
|
|
#endif
|
|
} else {
|
|
tp_last_staus = ELM_EVENT_TOUCH_DOWN;
|
|
move_flag = 0;
|
|
log_info("----tpd_down----x=%d, y=%d", x, y);
|
|
}
|
|
first_x = x;
|
|
first_y = y;
|
|
t.action = tp_last_staus;
|
|
#if HORIZONTAL_SCREEN
|
|
t.x = LCD_W - y;
|
|
t.y = x;
|
|
#else
|
|
t.x = x;
|
|
t.y = y;
|
|
#endif
|
|
lvgl_touch_hdl.x = x;
|
|
lvgl_touch_hdl.y = y;
|
|
lvgl_touch_hdl.status = 1;
|
|
if (touch_en) {
|
|
ui_touch_msg_post(&t);
|
|
}
|
|
#if defined USE_GUIX_UI_DEMO
|
|
gx_jl_touch_event_process(t.x, t.y, 1);
|
|
#endif
|
|
#if defined USE_UGFX_UI_DEMO
|
|
ugfx_touch_event_process(t.x, t.y, 1);
|
|
#endif
|
|
}
|
|
|
|
static void tpd_up(int x, int y)
|
|
{
|
|
struct touch_event t;
|
|
|
|
if (x < 0) {
|
|
x = 0;
|
|
}
|
|
if (x > (VK_X - 1)) {
|
|
x = VK_X - 1;
|
|
}
|
|
if (y < 0) {
|
|
y = 0;
|
|
}
|
|
if (y > (VK_Y - 1)) {
|
|
y = VK_Y - 1;
|
|
}
|
|
|
|
#if Y_MIRROR
|
|
x = VK_X - x - 1;
|
|
#endif
|
|
|
|
#if X_MIRROR
|
|
y = VK_Y - y - 1;
|
|
#endif
|
|
|
|
/* log_info("U[%4d %4d %4d]\n", x, y, 0); */
|
|
tp_last_staus = ELM_EVENT_TOUCH_UP;
|
|
tp_down_cnt = 0;
|
|
t.action = tp_last_staus;
|
|
#if HORIZONTAL_SCREEN
|
|
t.x = LCD_W - y;
|
|
t.y = x;
|
|
#else
|
|
t.x = x;
|
|
t.y = y;
|
|
#endif
|
|
log_info("----tpd_up----x=%d, y=%d", x, y);
|
|
lvgl_touch_hdl.x = x;
|
|
lvgl_touch_hdl.y = y;
|
|
lvgl_touch_hdl.status = 0;
|
|
if (touch_en) {
|
|
ui_touch_msg_post(&t);
|
|
}
|
|
#if defined USE_GUIX_UI_DEMO
|
|
gx_jl_touch_event_process(t.x, t.y, 0);
|
|
#endif
|
|
#if defined USE_UGFX_UI_DEMO
|
|
ugfx_touch_event_process(t.x, t.y, 0);
|
|
#endif
|
|
}
|
|
|
|
static void FT6236_interrupt(void)
|
|
{
|
|
os_sem_post(&touch_sem);
|
|
}
|
|
|
|
|
|
void FT6236_init(void)
|
|
{
|
|
static u8 status = 0;
|
|
static int x, y;
|
|
static u16 touch_x = 0;
|
|
static u16 touch_y = 0;
|
|
u8 read_data = 0;
|
|
|
|
os_sem_create(&touch_sem, 0);
|
|
|
|
extern const struct ui_devices_cfg ui_cfg_data;
|
|
static const struct ui_lcd_platform_data *pdata;
|
|
pdata = (struct ui_lcd_platform_data *)ui_cfg_data.private_data;
|
|
|
|
gpio_direction_output(pdata->touch_reset_pin, 0);
|
|
os_time_dly(6);
|
|
gpio_direction_output(pdata->touch_reset_pin, 1);
|
|
|
|
iic = dev_open("iic0", NULL);
|
|
os_time_dly(10);
|
|
//注册中断注意触摸用的事件0 屏幕TE用的事件1
|
|
port_wakeup_reg(EVENT_IO_0, pdata->touch_int_pin, EDGE_NEGATIVE, FT6236_interrupt);
|
|
|
|
wrFT6236Reg(FT_DEVIDE_MODE, 0);
|
|
|
|
wrFT6236Reg(FT_ID_G_THGROUP, 22);
|
|
rdFT6236Reg(FT_ID_G_THGROUP, &read_data);
|
|
printf("[touch FT_ID_G_THGROUP]>>>>>>>>>>>read_data=%d", read_data);
|
|
|
|
wrFT6236Reg(FT_ID_G_PERIODACTIVE, 13);
|
|
rdFT6236Reg(FT_ID_G_PERIODACTIVE, &read_data);
|
|
printf("[touch FT_ID_G_PERIODACTIVE]>>>>>>>>>>>read_data=%d", read_data);
|
|
|
|
wrFT6236Reg(FT_ID_G_MODE, 1);
|
|
rdFT6236Reg(FT_ID_G_MODE, &read_data);
|
|
printf("[touch FT_ID_G_MODE]>>>>>>>>>>>read_data=%d", read_data);
|
|
if (get_FT6236_pid()) {
|
|
log_info("[err]>>>>>FT6236 err!!!");
|
|
}
|
|
|
|
while (1) {
|
|
os_sem_pend(&touch_sem, 0);
|
|
|
|
rdFT6236Reg(FT_REG_NUM_FINGER, &status); //读取触摸点的状态 // BIT7表示有数据 ,bit0-3 表示触摸点个数
|
|
if (status) { //有触摸值
|
|
get_FT6236_xy(FT_TP1_REG, &touch_x, &touch_y);
|
|
tpd_down(touch_x, touch_y);//做触摸运算
|
|
touch_status = 1;//标记触摸按下
|
|
} else {
|
|
if (touch_status) { //这样做的目的是使得发消息做处理只有一次
|
|
tpd_up(touch_x, touch_y);//做触摸运算
|
|
os_time_dly(40);//保证两次触摸的最小时间间隔 UI有问题占时这样解决
|
|
os_sem_set(&touch_sem, 0);
|
|
}
|
|
touch_status = 0;//标记触摸抬起
|
|
}
|
|
status = 0;
|
|
}
|
|
}
|
|
|
|
static void my_touch_test_task(void *priv)
|
|
{
|
|
FT6236_init();
|
|
}
|
|
|
|
int FT6236_task_init(void)
|
|
{
|
|
return thread_fork("my_touch_test_task", 29, 1024, 0, NULL, my_touch_test_task, NULL);
|
|
}
|
|
|
|
#endif
|