219 lines
4.6 KiB
C
219 lines
4.6 KiB
C
/*
|
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Change Logs:
|
|
* Date Author Notes
|
|
* 2017-08-08 Yang the first version
|
|
*/
|
|
|
|
#include <rtthread.h>
|
|
#include <rthw.h>
|
|
#include <rtdevice.h>
|
|
#include "drv_touch.h"
|
|
#include <string.h>
|
|
|
|
#ifdef BSP_USING_TOUCH
|
|
|
|
#define DBG_ENABLE
|
|
#define DBG_SECTION_NAME "TOUCH.ft"
|
|
#define DBG_LEVEL TOUCH_DBG_LEVEL
|
|
#define DBG_COLOR
|
|
#include <rtdbg.h>
|
|
|
|
|
|
#ifdef TOUCH_IC_FT3X67
|
|
#define CHIP_ID_REG 0xA8U
|
|
#define CHIP_ID_VALUE 0x11U
|
|
#define TOUCH_SLAVE_ADDR 0x38U
|
|
#else
|
|
#error "Please define at least one TOUCH DEVICE"
|
|
/* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */
|
|
#endif
|
|
|
|
static struct rt_i2c_bus_device *ft_i2c_bus;
|
|
static struct touch_drivers ft_driver;
|
|
|
|
static int ft_read(struct rt_i2c_bus_device *i2c_bus, rt_uint8_t addr, rt_uint8_t *buffer, rt_size_t length)
|
|
{
|
|
int ret = -1;
|
|
int retries = 0;
|
|
|
|
struct rt_i2c_msg msgs[] =
|
|
{
|
|
{
|
|
.addr = ft_driver.address,
|
|
.flags = RT_I2C_WR,
|
|
.len = 1,
|
|
.buf = &addr,
|
|
},
|
|
{
|
|
.addr = ft_driver.address,
|
|
.flags = RT_I2C_RD,
|
|
.len = length,
|
|
.buf = buffer,
|
|
},
|
|
};
|
|
|
|
while (retries < IIC_RETRY_NUM)
|
|
{
|
|
ret = rt_i2c_transfer(i2c_bus, msgs, 2);
|
|
if (ret == 2)break;
|
|
retries++;
|
|
}
|
|
|
|
if (retries >= IIC_RETRY_NUM)
|
|
{
|
|
LOG_E("%s i2c read error: %d", __func__, ret);
|
|
return -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void ft_write(touch_drv_t driver, struct rt_i2c_bus_device *i2c_bus, rt_uint8_t addr, rt_uint8_t *buffer, rt_size_t length)
|
|
{
|
|
|
|
rt_uint8_t *send_buffer = rt_malloc(length + 1);
|
|
|
|
RT_ASSERT(send_buffer);
|
|
|
|
send_buffer[0] = addr;
|
|
memcpy(send_buffer + 1, buffer, length);
|
|
|
|
struct rt_i2c_msg msgs[] =
|
|
{
|
|
{
|
|
.addr = ft_driver.address,
|
|
.flags = RT_I2C_WR,
|
|
.len = length + 1,
|
|
.buf = send_buffer,
|
|
}
|
|
};
|
|
|
|
length = rt_i2c_transfer(i2c_bus, msgs, 1);
|
|
rt_free(send_buffer);
|
|
send_buffer = RT_NULL;
|
|
}
|
|
|
|
static void ft_isr_enable(rt_bool_t enable)
|
|
{
|
|
rt_pin_irq_enable(BSP_TOUCH_INT_PIN, enable);
|
|
}
|
|
|
|
static void ft_touch_isr(void *parameter)
|
|
{
|
|
ft_isr_enable(RT_FALSE);
|
|
rt_sem_release(ft_driver.isr_sem);
|
|
}
|
|
|
|
static rt_err_t ft_read_point(touch_msg_t msg)
|
|
{
|
|
int ret = -1;
|
|
uint8_t point_num = 0;
|
|
static uint8_t s_tp_down = 0;
|
|
uint8_t point[6];
|
|
ret = ft_read(ft_i2c_bus, 0x02, &point_num, 1);
|
|
if (ret < 0)
|
|
{
|
|
return RT_ERROR;
|
|
}
|
|
|
|
if (point_num == 0)
|
|
{
|
|
if (s_tp_down)
|
|
{
|
|
s_tp_down = 0;
|
|
msg->event = TOUCH_EVENT_UP;
|
|
return RT_EOK;
|
|
}
|
|
msg->event = TOUCH_EVENT_NONE;
|
|
return RT_ERROR;
|
|
}
|
|
|
|
ret = ft_read(ft_i2c_bus, 0x03, point, 6);
|
|
if (ret < 0)
|
|
{
|
|
return RT_ERROR;
|
|
}
|
|
|
|
msg->y = (point[0]&0x0F) << 8 | point[1];
|
|
msg->x = (point[2]&0x0F) << 8 | point[3];
|
|
if (s_tp_down)
|
|
{
|
|
msg->event = TOUCH_EVENT_MOVE;
|
|
return RT_EOK;
|
|
}
|
|
msg->event = TOUCH_EVENT_DOWN;
|
|
s_tp_down = 1;
|
|
|
|
return RT_EOK;
|
|
}
|
|
|
|
static void ft_init(struct rt_i2c_bus_device *i2c_bus)
|
|
{
|
|
if (ft_i2c_bus == RT_NULL)
|
|
{
|
|
ft_i2c_bus = i2c_bus;
|
|
}
|
|
ft_driver.isr_sem = rt_sem_create("ft", 0, RT_IPC_FLAG_FIFO);
|
|
RT_ASSERT(ft_driver.isr_sem);
|
|
|
|
rt_pin_mode(BSP_TOUCH_INT_PIN, PIN_MODE_INPUT_PULLUP);
|
|
rt_pin_attach_irq(BSP_TOUCH_INT_PIN, PIN_IRQ_MODE_FALLING, ft_touch_isr, RT_NULL);
|
|
|
|
rt_thread_mdelay(200);
|
|
}
|
|
|
|
static void ft_deinit(void)
|
|
{
|
|
if (ft_driver.isr_sem)
|
|
{
|
|
rt_sem_delete(ft_driver.isr_sem);
|
|
ft_driver.isr_sem = RT_NULL;
|
|
}
|
|
}
|
|
|
|
struct touch_ops ft_ops =
|
|
{
|
|
ft_isr_enable,
|
|
ft_read_point,
|
|
ft_init,
|
|
ft_deinit,
|
|
};
|
|
|
|
static rt_bool_t ft_probe(struct rt_i2c_bus_device *i2c_bus)
|
|
{
|
|
int err = 0;
|
|
uint8_t cid = 0xFF;
|
|
|
|
ft_i2c_bus = i2c_bus;
|
|
err = ft_read(ft_i2c_bus, CHIP_ID_REG, (uint8_t *)&cid, 1);
|
|
if (err < 0)
|
|
{
|
|
LOG_E("%s failed: %d", __func__, err);
|
|
return RT_FALSE;
|
|
}
|
|
LOG_I("touch CID:%02X", cid);
|
|
if(cid == CHIP_ID_VALUE)
|
|
{
|
|
return RT_TRUE;
|
|
}
|
|
return RT_FALSE;
|
|
}
|
|
|
|
int ft_driver_register(void)
|
|
{
|
|
ft_driver.address = TOUCH_SLAVE_ADDR;
|
|
ft_driver.probe = ft_probe;
|
|
ft_driver.ops = &ft_ops;
|
|
ft_driver.user_data = RT_NULL;
|
|
rt_touch_drivers_register(&ft_driver);
|
|
return 0;
|
|
}
|
|
|
|
INIT_DEVICE_EXPORT(ft_driver_register);
|
|
|
|
#endif
|