409 lines
11 KiB
C
409 lines
11 KiB
C
/*
|
|
* File : drv_touch_gt9xx.c
|
|
* This file is part of RT-Thread RTOS
|
|
* COPYRIGHT (C) 2017, RT-Thread Development Team
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Change Logs:
|
|
* Date Author Notes
|
|
* 2018-02-08 Zhangyihong the first version
|
|
* 2018-04-03 XY gt9xx for 1024 * 600
|
|
* 2018-10-11 sundm75 ls1c for 480 * 272
|
|
*/
|
|
#include "rtthread.h"
|
|
|
|
#include "drv_touch.h"
|
|
#include "string.h"
|
|
#include "ls1c_gpio.h"
|
|
#include "ls1c.h"
|
|
#include "ls1c_pin.h"
|
|
|
|
#ifdef TINA_USING_TOUCH
|
|
|
|
#define TP_INT_PIN (89)
|
|
#define TP_RESET_PIN (87)
|
|
#define LED_PIN (52)
|
|
|
|
|
|
#define gt9xx_READ_XY_REG 0x814E /* 坐标寄存器 当前检测到的触摸情况 */
|
|
#define gt9xx_CLEARBUF_REG 0x814E /* 清除坐标寄存器 */
|
|
#define gt9xx_CONFIG_REG 0x8047 /* 配置参数寄存器 */
|
|
#define gt9xx_COMMAND_REG 0x8040 /* 实时命令 */
|
|
#define gt9xx_PRODUCT_ID_REG 0x8140 /* productid */
|
|
#define gt9xx_VENDOR_ID_REG 0x814A /* 当前模组选项信息 */
|
|
#define gt9xx_CONFIG_VERSION_REG 0x8047 /* 配置文件版本号 */
|
|
#define gt9xx_CONFIG_CHECKSUM_REG 0x80FF /* 配置文件校验码 */
|
|
#define gt9xx_FIRMWARE_VERSION_REG 0x8144 /* 固件版本号 */
|
|
|
|
#define IIC_RETRY_NUM 1
|
|
|
|
void touch_down(void);
|
|
void touch_mo(void);
|
|
void touch_up(void);
|
|
|
|
static struct rt_i2c_bus_device *gt9xx_i2c_bus;
|
|
static void gt9xx_isr_enable(rt_bool_t enable);
|
|
static rt_err_t gt9xx_read_point(touch_msg_t msg);
|
|
static void gt9xx_init(struct rt_i2c_bus_device *i2c_bus);
|
|
static void gt9xx_deinit(void);
|
|
static int gt9xx_read_xy(void);
|
|
|
|
static gpio_direction_output( int pin, int level)
|
|
{
|
|
gpio_init(pin, gpio_mode_output);
|
|
gpio_set(pin, level);
|
|
}
|
|
static gpio_direction_input(int pin)
|
|
{
|
|
gpio_init(pin, gpio_mode_input);
|
|
}
|
|
static gpio_irq_enable( int pin)
|
|
{
|
|
int touch_irq = LS1C_GPIO_TO_IRQ(TP_INT_PIN);
|
|
rt_hw_interrupt_umask(touch_irq);
|
|
}
|
|
static gpio_irq_disable(int pin)
|
|
{
|
|
int touch_irq = LS1C_GPIO_TO_IRQ(TP_INT_PIN);
|
|
rt_hw_interrupt_mask(touch_irq);
|
|
}
|
|
static gpio_set_value(int pin, int level)
|
|
{
|
|
gpio_set(pin, level);
|
|
}
|
|
struct touch_ops gt9xx_ops =
|
|
{
|
|
gt9xx_isr_enable,
|
|
gt9xx_read_point,
|
|
gt9xx_init,
|
|
gt9xx_deinit,
|
|
};
|
|
|
|
static struct touch_drivers gt9xx_driver;
|
|
extern struct lcd_config lcd_config;
|
|
|
|
static rt_uint8_t gt9xx_config[186];
|
|
|
|
static int gt9xx_read(struct rt_i2c_bus_device *i2c_bus, rt_uint16_t addr, rt_uint8_t *buffer, rt_size_t length)
|
|
{
|
|
int ret = -1;
|
|
int retries = 0;
|
|
rt_uint8_t tmp_buf[2];
|
|
|
|
struct rt_i2c_msg msgs[] =
|
|
{
|
|
{
|
|
.addr = gt9xx_driver.address,
|
|
.flags = RT_I2C_WR,
|
|
.len = 2,
|
|
.buf = tmp_buf,
|
|
},
|
|
{
|
|
.addr = gt9xx_driver.address,
|
|
.flags = RT_I2C_RD,
|
|
.len = length,
|
|
.buf = buffer,
|
|
},
|
|
};
|
|
|
|
tmp_buf[0] = (rt_uint8_t)(addr >> 8);
|
|
tmp_buf[1] = (rt_uint8_t)(addr);
|
|
|
|
while (retries < IIC_RETRY_NUM)
|
|
{
|
|
ret = rt_i2c_transfer(i2c_bus, msgs, 2);
|
|
ret = rt_i2c_transfer(i2c_bus, msgs, 2);
|
|
ret = rt_i2c_transfer(i2c_bus, msgs, 2);
|
|
ret = rt_i2c_transfer(i2c_bus, msgs, 2);
|
|
if (ret == 2)break;
|
|
retries++;
|
|
}
|
|
|
|
if (retries >= IIC_RETRY_NUM)
|
|
{
|
|
rt_kprintf("%s i2c read error: %d\n", __func__, ret);
|
|
return -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void gt9xx_write(struct rt_i2c_bus_device *i2c_bus, rt_uint16_t addr, rt_uint8_t *buffer, rt_size_t length)
|
|
{
|
|
|
|
rt_uint8_t *send_buffer = rt_malloc(length + 2);
|
|
|
|
RT_ASSERT(send_buffer);
|
|
|
|
send_buffer[0] = (rt_uint8_t)(addr >> 8);
|
|
send_buffer[1] = (rt_uint8_t)(addr);
|
|
memcpy(send_buffer + 2, buffer, length);
|
|
|
|
struct rt_i2c_msg msgs[] =
|
|
{
|
|
{
|
|
.addr = gt9xx_driver.address,
|
|
.flags = RT_I2C_WR,
|
|
.len = length + 2,
|
|
.buf = send_buffer,
|
|
}
|
|
};
|
|
|
|
length = rt_i2c_transfer(i2c_bus, msgs, 1);
|
|
rt_free(send_buffer);
|
|
send_buffer = RT_NULL;
|
|
}
|
|
|
|
static void gt9xx_isr_enable(rt_bool_t enable)
|
|
{
|
|
if (enable)
|
|
{
|
|
gpio_irq_enable( TP_INT_PIN);
|
|
}
|
|
else
|
|
{
|
|
gpio_irq_disable( TP_INT_PIN);
|
|
}
|
|
}
|
|
|
|
static rt_err_t gt9xx_read_point(touch_msg_t msg)
|
|
{
|
|
rt_uint8_t buf[8];
|
|
rt_uint8_t clean = 0;
|
|
static rt_uint8_t s_tp_down = 0;
|
|
|
|
gt9xx_read(gt9xx_i2c_bus, gt9xx_READ_XY_REG, buf, 8);
|
|
gt9xx_write(gt9xx_i2c_bus, gt9xx_CLEARBUF_REG, &clean, 1);
|
|
if ((buf[0] & 0x80) == 0)
|
|
{
|
|
if (s_tp_down)
|
|
{
|
|
s_tp_down = 0;
|
|
msg->event = TOUCH_EVENT_UP;
|
|
return RT_EOK;
|
|
}
|
|
msg->event = TOUCH_EVENT_NONE;
|
|
return RT_EOK;
|
|
}
|
|
msg->x = ((rt_uint16_t)buf[3] << 8) | buf[2];
|
|
msg->y = ((rt_uint16_t)buf[5] << 8) | buf[4];
|
|
if (s_tp_down)
|
|
{
|
|
msg->event = TOUCH_EVENT_MOVE;
|
|
return RT_EOK;
|
|
}
|
|
msg->event = TOUCH_EVENT_DOWN;
|
|
s_tp_down = 1;
|
|
|
|
return RT_EOK;
|
|
}
|
|
|
|
void gt9xx_touch_isr(int irq, void *param)
|
|
{
|
|
gpio_irq_disable(TP_INT_PIN);
|
|
rt_sem_release(gt9xx_driver.isr_sem);
|
|
}
|
|
|
|
static void gt9xx_set_address(rt_uint8_t address)
|
|
{
|
|
pin_set_purpose(TP_INT_PIN, PIN_PURPOSE_OTHER);
|
|
pin_set_purpose(TP_RESET_PIN, PIN_PURPOSE_OTHER);
|
|
gpio_direction_output( TP_INT_PIN, 0);
|
|
gpio_direction_output( TP_RESET_PIN, 0);
|
|
if (address == 0x5D)
|
|
{
|
|
rt_thread_delay(30);
|
|
gpio_set_value( TP_RESET_PIN, 1);
|
|
rt_thread_delay(300);
|
|
pin_set_purpose(TP_INT_PIN, PIN_PURPOSE_OTHER);
|
|
gpio_direction_input(TP_INT_PIN);
|
|
rt_thread_delay(10);
|
|
}
|
|
else
|
|
{
|
|
gpio_set_value( TP_INT_PIN, 1);
|
|
gpio_set_value( TP_RESET_PIN, 0);
|
|
rt_thread_delay(30);
|
|
gpio_set_value( TP_RESET_PIN, 1);
|
|
gpio_set_value( TP_INT_PIN, 1);
|
|
rt_thread_delay(30);
|
|
gpio_set_value( TP_INT_PIN, 0);
|
|
rt_thread_delay(30);
|
|
gpio_set_value( TP_INT_PIN, 1);
|
|
}
|
|
}
|
|
|
|
static void gt9xx_soft_reset(struct rt_i2c_bus_device *i2c_bus)
|
|
{
|
|
rt_uint8_t buf = 2;
|
|
gt9xx_write(i2c_bus, gt9xx_COMMAND_REG, &buf, 1);
|
|
}
|
|
|
|
static void gt9xx_init(struct rt_i2c_bus_device *i2c_bus)
|
|
{
|
|
rt_uint8_t id = 0;
|
|
int touch_irq = LS1C_GPIO_TO_IRQ(TP_INT_PIN);
|
|
|
|
gt9xx_driver.isr_sem = rt_sem_create("gt9xx", 0, RT_IPC_FLAG_FIFO);
|
|
RT_ASSERT(gt9xx_driver.isr_sem);
|
|
|
|
gt9xx_i2c_bus = i2c_bus;
|
|
gt9xx_set_address(gt9xx_driver.address);
|
|
|
|
gt9xx_read(i2c_bus, gt9xx_CONFIG_VERSION_REG, &id, 1);
|
|
rt_kprintf("\r\nGT9xx Config version:0x%02X\r\n", id);
|
|
|
|
gt9xx_read(i2c_bus, gt9xx_VENDOR_ID_REG, &id, 1);
|
|
rt_kprintf("\r\nGT9xx sensor id:0x%02X\r\n", id);
|
|
|
|
gpio_set_irq_type( TP_INT_PIN, IRQ_TYPE_EDGE_RISING);
|
|
gpio_irq_disable( TP_INT_PIN);
|
|
|
|
rt_hw_interrupt_install(touch_irq, gt9xx_touch_isr, RT_NULL, "touch");
|
|
|
|
rt_thread_delay(RT_TICK_PER_SECOND / 5);
|
|
gpio_init(LED_PIN, gpio_mode_output);
|
|
}
|
|
|
|
static int gt9xx_write_config(void)
|
|
{
|
|
int i;
|
|
rt_uint8_t config_checksum = 0;
|
|
gt9xx_set_address(gt9xx_driver.address);
|
|
//Add sth...
|
|
gt9xx_config[5] = 0x05;
|
|
gt9xx_config[6] = 0x0C;
|
|
for (i = 0; i < sizeof(gt9xx_config) - 2; i++)
|
|
{
|
|
config_checksum += gt9xx_config[i];
|
|
}
|
|
gt9xx_config[184] = (~config_checksum) + 1;
|
|
gt9xx_config[185] = 0x01;
|
|
gt9xx_write(gt9xx_i2c_bus, gt9xx_CONFIG_REG, gt9xx_config, sizeof(gt9xx_config));
|
|
return 0;
|
|
}
|
|
MSH_CMD_EXPORT(gt9xx_write_config,please read first);
|
|
|
|
static int gt9xx_read_config(void)
|
|
{
|
|
int i;
|
|
rt_uint8_t buf[8];
|
|
rt_uint8_t clean = 0;
|
|
gt9xx_read(gt9xx_i2c_bus, gt9xx_CONFIG_VERSION_REG, gt9xx_config, sizeof(gt9xx_config));
|
|
gt9xx_config[sizeof(gt9xx_config)-1] = 1;
|
|
|
|
rt_kprintf("\n");
|
|
for(i = 0; i < sizeof(gt9xx_config); i++)
|
|
{
|
|
rt_kprintf("0x%02X,",gt9xx_config[i]);
|
|
if((i+1)%8 == 0)
|
|
{
|
|
rt_kprintf("\n");
|
|
}
|
|
}
|
|
rt_kprintf("\n");
|
|
return 0;
|
|
}
|
|
MSH_CMD_EXPORT(gt9xx_read_config,read gt9xx config);
|
|
static int gt9xx_read_xy(void)
|
|
{
|
|
int i;
|
|
rt_uint8_t buf[8];
|
|
rt_uint8_t clean = 0;
|
|
rt_uint16_t x,y;
|
|
|
|
gt9xx_read(gt9xx_i2c_bus, gt9xx_READ_XY_REG, buf, 8);
|
|
gt9xx_write(gt9xx_i2c_bus, gt9xx_CLEARBUF_REG, &clean, 1);
|
|
x = ((rt_uint16_t)buf[3] << 8) | buf[2];
|
|
y = ((rt_uint16_t)buf[5] << 8) | buf[4];
|
|
rt_kprintf("\n814e= 0x%02x; 814f= 0x%02x;\n x1 : %d, y1 : %d\n", buf[0], buf[1], x, y);
|
|
|
|
rt_kprintf("\n");
|
|
return 0;
|
|
}
|
|
MSH_CMD_EXPORT(gt9xx_read_xy,read gt9xx xy);
|
|
|
|
static rt_bool_t gt9xx_probe(struct rt_i2c_bus_device *i2c_bus)
|
|
{
|
|
rt_uint8_t buffer[5] = { 0 };
|
|
|
|
gt9xx_set_address(gt9xx_driver.address);
|
|
gt9xx_soft_reset(i2c_bus);
|
|
rt_thread_delay(10);
|
|
gt9xx_read(i2c_bus, gt9xx_PRODUCT_ID_REG, buffer, 4);
|
|
buffer[4] = '\0';
|
|
if (buffer[0] == '9' && buffer[1] == '1' && buffer[2] == '1')
|
|
{
|
|
rt_kprintf("Found chip gt911\r\n");
|
|
return RT_TRUE;
|
|
}
|
|
else if (buffer[0] == '9' && buffer[1] == '1' && buffer[2] == '4' && buffer[3] == '7')
|
|
{
|
|
rt_kprintf("Found chip gt9147\r\n");
|
|
return RT_TRUE;
|
|
}
|
|
else if (buffer[0] == '9' && buffer[1] == '1' && buffer[2] == '5' && buffer[3] == '7')
|
|
{
|
|
rt_kprintf("Found chip gt9157\r\n");
|
|
return RT_TRUE;
|
|
}
|
|
else
|
|
{
|
|
rt_kprintf("Uknow chip :");
|
|
rt_kprintf("%d%d%d%d\r\n",buffer[0], buffer[1] , buffer[2], buffer[3]);
|
|
return RT_TRUE;
|
|
}
|
|
return RT_FALSE;
|
|
}
|
|
|
|
static void gt9xx_deinit(void)
|
|
{
|
|
rt_sem_delete(gt9xx_driver.isr_sem);
|
|
}
|
|
|
|
static int gt9xx_driver_register(void)
|
|
{
|
|
rt_kprintf("\r\n%s \r\n", __FUNCTION__);
|
|
gt9xx_driver.address = 0x5D;
|
|
gt9xx_driver.probe = gt9xx_probe;
|
|
gt9xx_driver.ops = >9xx_ops;
|
|
gt9xx_driver.user_data = RT_NULL;
|
|
rt_touch_drivers_register(>9xx_driver);
|
|
return 0;
|
|
}
|
|
INIT_ENV_EXPORT(gt9xx_driver_register);
|
|
|
|
void touch_down(void)
|
|
{
|
|
gpio_set(LED_PIN, gpio_level_low);
|
|
}
|
|
|
|
void touch_mo(void)
|
|
{
|
|
if (0 == (gpio_get(LED_PIN)))
|
|
gpio_set(LED_PIN, gpio_level_high);
|
|
else
|
|
gpio_set(LED_PIN, gpio_level_low);
|
|
}
|
|
|
|
void touch_up(void)
|
|
{
|
|
gpio_set(LED_PIN, gpio_level_high);
|
|
}
|
|
|
|
|
|
#endif
|