Merge pull request #1937 from yangfasheng/master
add touch driver; update lcd driver;
This commit is contained in:
commit
62c3e74e3d
|
@ -38,8 +38,6 @@ if GetDepend('RT_USING_I2C'):
|
|||
# add lcd driver code
|
||||
if GetDepend('RT_USING_LCD'):
|
||||
src += ['drv_lcd.c']
|
||||
if GetDepend('BOARD_RT1050_EVK') and GetDepend('PKG_USING_GUIENGINE'):
|
||||
src += ['drv_ft5406.c']
|
||||
|
||||
# add sdio driver code
|
||||
if GetDepend('RT_USING_SDIO'):
|
||||
|
@ -68,6 +66,9 @@ if GetDepend('BOARD_RT1050_ATK') and GetDepend('RT_USING_LWIP'):
|
|||
if GetDepend('RT_USING_AUDIO'):
|
||||
src += ['drv_codec.c', 'fsl_wm8960.c']
|
||||
|
||||
if GetDepend('PKG_USING_GUIENGINE'):
|
||||
src += Glob('touch/*.c')
|
||||
|
||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES=CPPDEFINES)
|
||||
|
||||
Return('group')
|
||||
|
|
|
@ -1,340 +0,0 @@
|
|||
/*
|
||||
* 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 <rtdevice.h>
|
||||
#include <finsh.h>
|
||||
|
||||
#include <rtgui/event.h>
|
||||
#include <rtgui/rtgui_server.h>
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#include "fsl_gpio.h"
|
||||
#include "fsl_lpi2c.h"
|
||||
|
||||
#define BSP_TOUCH_SAMPLE_HZ 30
|
||||
|
||||
#define I2CBUS_NAME "i2c1"
|
||||
|
||||
#if 0
|
||||
#define FTDEBUG rt_kprintf
|
||||
#else
|
||||
#define FTDEBUG(...)
|
||||
#endif
|
||||
|
||||
#define TOUCH_SLP_TIME (RT_TICK_PER_SECOND * 5)
|
||||
|
||||
#define FT5206_TS_ADDR 0x38
|
||||
#define TP_MAX_TOUCH_POINT 2
|
||||
|
||||
enum ft5x0x_ts_regs
|
||||
{
|
||||
FT5X0X_REG_THGROUP = 0x80,
|
||||
FT5X0X_REG_THPEAK = 0x81,
|
||||
FT5X0X_REG_THCAL = 0x82,
|
||||
FT5X0X_REG_THWATER = 0x83,
|
||||
FT5X0X_REG_THTEMP = 0x84,
|
||||
FT5X0X_REG_THDIFF = 0x85,
|
||||
FT5X0X_REG_CTRL = 0x86,
|
||||
FT5X0X_REG_TIMEENTERMONITOR = 0x87,
|
||||
FT5X0X_REG_PERIODACTIVE = 0x88,
|
||||
FT5X0X_REG_PERIODMONITOR = 0x89,
|
||||
FT5X0X_REG_HEIGHT_B = 0x8a,
|
||||
FT5X0X_REG_MAX_FRAME = 0x8b,
|
||||
FT5X0X_REG_DIST_MOVE = 0x8c,
|
||||
FT5X0X_REG_DIST_POINT = 0x8d,
|
||||
FT5X0X_REG_FEG_FRAME = 0x8e,
|
||||
FT5X0X_REG_SINGLE_CLICK_OFFSET = 0x8f,
|
||||
FT5X0X_REG_DOUBLE_CLICK_TIME_MIN = 0x90,
|
||||
FT5X0X_REG_SINGLE_CLICK_TIME = 0x91,
|
||||
FT5X0X_REG_LEFT_RIGHT_OFFSET = 0x92,
|
||||
FT5X0X_REG_UP_DOWN_OFFSET = 0x93,
|
||||
FT5X0X_REG_DISTANCE_LEFT_RIGHT = 0x94,
|
||||
FT5X0X_REG_DISTANCE_UP_DOWN = 0x95,
|
||||
FT5X0X_REG_ZOOM_DIS_SQR = 0x96,
|
||||
FT5X0X_REG_RADIAN_VALUE = 0x97,
|
||||
FT5X0X_REG_MAX_X_HIGH = 0x98,
|
||||
FT5X0X_REG_MAX_X_LOW = 0x99,
|
||||
FT5X0X_REG_MAX_Y_HIGH = 0x9a,
|
||||
FT5X0X_REG_MAX_Y_LOW = 0x9b,
|
||||
FT5X0X_REG_K_X_HIGH = 0x9c,
|
||||
FT5X0X_REG_K_X_LOW = 0x9d,
|
||||
FT5X0X_REG_K_Y_HIGH = 0x9e,
|
||||
FT5X0X_REG_K_Y_LOW = 0x9f,
|
||||
FT5X0X_REG_AUTO_CLB_MODE = 0xa0,
|
||||
FT5X0X_REG_LIB_VERSION_H = 0xa1,
|
||||
FT5X0X_REG_LIB_VERSION_L = 0xa2,
|
||||
FT5X0X_REG_CIPHER = 0xa3,
|
||||
FT5X0X_REG_G_MODE = 0xa4,
|
||||
FT5X0X_REG_PMODE = 0xa5, /* Power Consume Mode */
|
||||
FT5X0X_REG_FIRMID = 0xa6,
|
||||
FT5X0X_REG_STATE = 0xa7,
|
||||
FT5X0X_REG_VENDID = 0xa8,
|
||||
FT5X0X_REG_ERR = 0xa9,
|
||||
FT5X0X_REG_CLB = 0xaa,
|
||||
};
|
||||
|
||||
#define CTRL_NOAUTO_MONITOR 0x00
|
||||
#define CTRL_AUTO_MONITOR 0x01
|
||||
|
||||
#define PMODE_ACTIVE 0x00
|
||||
#define PMODE_MONITOR 0x01
|
||||
#define PMODE_STANDBY 0x02
|
||||
#define PMODE_HIBERNATE 0x03
|
||||
|
||||
#define G_MODE_POLLING 0x00
|
||||
#define G_MODE_TRIGGER 0x01
|
||||
|
||||
typedef enum _touch_event
|
||||
{
|
||||
kTouch_Down = 0, /*!< The state changed to touched. */
|
||||
kTouch_Up = 1, /*!< The state changed to not touched. */
|
||||
kTouch_Contact = 2, /*!< There is a continuous touch being detected. */
|
||||
kTouch_Reserved = 3 /*!< No touch information available. */
|
||||
} touch_event_t;
|
||||
|
||||
typedef struct _touch_point
|
||||
{
|
||||
touch_event_t TOUCH_EVENT; /*!< Indicates the state or event of the touch point. */
|
||||
uint8_t TOUCH_ID; /*!< Id of the touch point. This numeric value stays constant between down and up event. */
|
||||
uint16_t TOUCH_X; /*!< X coordinate of the touch point */
|
||||
uint16_t TOUCH_Y; /*!< Y coordinate of the touch point */
|
||||
} touch_point_t;
|
||||
|
||||
typedef struct _ft5406_touch_point
|
||||
{
|
||||
uint8_t XH;
|
||||
uint8_t XL;
|
||||
uint8_t YH;
|
||||
uint8_t YL;
|
||||
uint8_t RESERVED[2];
|
||||
} ft5406_touch_point_t;
|
||||
|
||||
typedef struct _ft5406_touch_data
|
||||
{
|
||||
uint8_t DEVIDE_MODE;
|
||||
uint8_t GEST_ID;
|
||||
uint8_t TD_STATUS;
|
||||
ft5406_touch_point_t TOUCH;
|
||||
} ft5406_touch_data_t;
|
||||
|
||||
#define TOUCH_POINT_GET_EVENT(T) ((touch_event_t)((T).XH >> 6))
|
||||
#define TOUCH_POINT_GET_ID(T) ((T).YH >> 4)
|
||||
#define TOUCH_POINT_GET_X(T) ((((T).XH & 0x0f) << 8) | (T).XL)
|
||||
#define TOUCH_POINT_GET_Y(T) ((((T).YH & 0x0f) << 8) | (T).YL)
|
||||
|
||||
static struct rt_i2c_bus_device *_i2c_bus;
|
||||
static struct rt_semaphore _tp_sem;
|
||||
|
||||
static int _ft5406_read(unsigned char cmd,
|
||||
void *buf,
|
||||
size_t len)
|
||||
{
|
||||
struct rt_i2c_msg msgs[2];
|
||||
|
||||
msgs[0].addr = FT5206_TS_ADDR;
|
||||
msgs[0].flags = RT_I2C_WR;
|
||||
msgs[0].buf = &cmd;
|
||||
msgs[0].len = sizeof(cmd);
|
||||
|
||||
msgs[1].addr = FT5206_TS_ADDR;
|
||||
msgs[1].flags = RT_I2C_RD;
|
||||
msgs[1].buf = buf;
|
||||
msgs[1].len = len;
|
||||
|
||||
if (rt_i2c_transfer(_i2c_bus, msgs, 2) == 2)
|
||||
return len;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int ft5406_read_touch(touch_point_t *dp)
|
||||
{
|
||||
ft5406_touch_data_t touch_data;
|
||||
|
||||
_ft5406_read(0, &touch_data, sizeof(ft5406_touch_data_t));
|
||||
|
||||
FTDEBUG("GEST_ID: %02x, TD_STATUS: %02x\n", touch_data.GEST_ID, touch_data.TD_STATUS);
|
||||
FTDEBUG("XH: %02x, XL: %02x, XH: %02x, XH: %02x, XH: %02x, RESERVED[0]: %02x, RESERVED[1]: %02x\n",
|
||||
touch_data.TOUCH.XH, touch_data.TOUCH.XL,
|
||||
touch_data.TOUCH.YH, touch_data.TOUCH.YL,
|
||||
touch_data.TOUCH.RESERVED[0], touch_data.TOUCH.RESERVED[1]);
|
||||
|
||||
dp->TOUCH_X = TOUCH_POINT_GET_Y(touch_data.TOUCH);
|
||||
dp->TOUCH_Y = TOUCH_POINT_GET_X(touch_data.TOUCH);
|
||||
|
||||
FTDEBUG(" ==> status : %d (%d, %d)\n", touch_data.TD_STATUS, dp->TOUCH_X, dp->TOUCH_Y);
|
||||
|
||||
if (touch_data.TD_STATUS != 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void _touch_session()
|
||||
{
|
||||
touch_point_t tpd;
|
||||
#ifdef RT_USING_RTGUI
|
||||
struct rtgui_event_mouse emouse;
|
||||
#endif
|
||||
|
||||
ft5406_read_touch(&tpd);
|
||||
|
||||
#ifdef RT_USING_RTGUI
|
||||
emouse.parent.sender = RT_NULL;
|
||||
emouse.wid = RT_NULL;
|
||||
|
||||
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
|
||||
emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN;
|
||||
emouse.x = tpd.TOUCH_X;
|
||||
emouse.y = tpd.TOUCH_Y;
|
||||
emouse.ts = rt_tick_get();
|
||||
emouse.id = emouse.ts;
|
||||
if (emouse.id == 0) emouse.id = 1;
|
||||
rtgui_server_post_event(&emouse.parent, sizeof(emouse));
|
||||
#endif
|
||||
|
||||
do
|
||||
{
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / BSP_TOUCH_SAMPLE_HZ);
|
||||
if (ft5406_read_touch(&tpd) != 0)
|
||||
break;
|
||||
|
||||
#ifdef RT_USING_RTGUI
|
||||
emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION;
|
||||
emouse.x = tpd.TOUCH_X;
|
||||
emouse.y = tpd.TOUCH_Y;
|
||||
emouse.ts = rt_tick_get();
|
||||
rtgui_server_post_event(&emouse.parent, sizeof(emouse));
|
||||
#endif
|
||||
}
|
||||
while (1);
|
||||
|
||||
#ifdef RT_USING_RTGUI
|
||||
/* Always send touch up event. */
|
||||
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
|
||||
emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP;
|
||||
emouse.x = tpd.TOUCH_X;
|
||||
emouse.y = tpd.TOUCH_Y;
|
||||
emouse.ts = rt_tick_get();
|
||||
rtgui_server_post_event(&emouse.parent, sizeof(emouse));
|
||||
#endif
|
||||
|
||||
//} while (rt_sem_take(&_tp_sem, TOUCH_SLP_TIME) == RT_EOK);
|
||||
}
|
||||
|
||||
void touch_down(void)
|
||||
{
|
||||
rt_sem_release(&_tp_sem);
|
||||
}
|
||||
|
||||
static void _touch(void *p)
|
||||
{
|
||||
int io_s;
|
||||
|
||||
gpio_pin_config_t pin_config =
|
||||
{
|
||||
kGPIO_DigitalInput, 0,
|
||||
};
|
||||
|
||||
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_11_GPIO1_IO11, 0U);
|
||||
|
||||
/* Enable touch panel controller */
|
||||
GPIO_PinInit(GPIO1, 11, &pin_config);
|
||||
|
||||
while(1)
|
||||
{
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 60);
|
||||
|
||||
io_s = GPIO_ReadPinInput(GPIO1, 11);
|
||||
if (io_s == 0)
|
||||
{
|
||||
_touch_session();
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
static rt_device_t _i2c_find(const char *name)
|
||||
{
|
||||
rt_device_t dev;
|
||||
|
||||
dev = rt_device_find(name);
|
||||
if (!dev)
|
||||
{
|
||||
rt_kprintf("search device failed: %s\n", name);
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
if (rt_device_open(dev, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
|
||||
{
|
||||
rt_kprintf("open device failed: %s\n", name);
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
rt_kprintf("open i2c bus: %s\n", name);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void ft5406_hw_reset(void)
|
||||
{
|
||||
gpio_pin_config_t pin_config =
|
||||
{
|
||||
kGPIO_DigitalOutput, 0,
|
||||
};
|
||||
|
||||
CLOCK_EnableClock(kCLOCK_Gpio1);
|
||||
|
||||
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, 0U);
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, 0x10B0u);
|
||||
|
||||
/* Enable touch panel controller */
|
||||
GPIO_PinInit(GPIO1, 2, &pin_config);
|
||||
GPIO_WritePinOutput(GPIO1, 2, 1);
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 20);
|
||||
GPIO_WritePinOutput(GPIO1, 2, 0);
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 20);
|
||||
GPIO_WritePinOutput(GPIO1, 2, 1);
|
||||
}
|
||||
|
||||
int ft5406_hw_init(void)
|
||||
{
|
||||
rt_thread_t tid;
|
||||
|
||||
rt_device_t dev = _i2c_find(I2CBUS_NAME);
|
||||
if (dev == RT_NULL)
|
||||
{
|
||||
FTDEBUG("search i2c device faild: %s\n", I2CBUS_NAME);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FTDEBUG("ft5406 set i2c bus to %s\n", I2CBUS_NAME);
|
||||
_i2c_bus = (struct rt_i2c_bus_device *)dev;
|
||||
}
|
||||
|
||||
ft5406_hw_reset();
|
||||
|
||||
rt_sem_init(&_tp_sem, "touch", 0, RT_IPC_FLAG_FIFO);
|
||||
tid = rt_thread_create("touch", _touch, RT_NULL, 2048, 10, 20);
|
||||
if (!tid)
|
||||
{
|
||||
rt_device_close(dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rt_thread_startup(tid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_APP_EXPORT(ft5406_hw_init);
|
|
@ -35,13 +35,19 @@ struct rt1050_lcd
|
|||
};
|
||||
|
||||
static struct rt1050_lcd lcd;
|
||||
ALIGN(64) static uint16_t frame_buffer[LCD_HEIGHT][LCD_WIDTH] SECTION("NonCacheable");
|
||||
|
||||
static volatile int fb_index = 0;
|
||||
static volatile rt_bool_t fb_modified = RT_TRUE;
|
||||
|
||||
ALIGN(64) static uint16_t frame_buffer0[LCD_HEIGHT][LCD_WIDTH] SECTION("NonCacheable");
|
||||
ALIGN(64) static uint16_t frame_buffer1[LCD_HEIGHT][LCD_WIDTH] SECTION("NonCacheable");
|
||||
|
||||
static rt_err_t rt1050_lcd_init(rt_device_t device)
|
||||
{
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
|
||||
rt_memset(frame_buffer, 0x00, sizeof(frame_buffer));
|
||||
memset(frame_buffer0, 0x00, sizeof(frame_buffer0));
|
||||
memset(frame_buffer1, 0x00, sizeof(frame_buffer1));
|
||||
|
||||
/* DeInit Video PLL. */
|
||||
CLOCK_DeinitVideoPll();
|
||||
|
@ -145,7 +151,7 @@ static rt_err_t rt1050_lcd_init(rt_device_t device)
|
|||
lcd_config.panelHeight = LCD_HEIGHT;
|
||||
lcd_config.pixelFormat = kELCDIF_PixelFormatRGB565;
|
||||
lcd_config.dataBus = kELCDIF_DataBus16Bit;
|
||||
lcd_config.bufferAddr = (uint32_t)frame_buffer;
|
||||
lcd_config.bufferAddr = (uint32_t)frame_buffer0;
|
||||
|
||||
ELCDIF_RgbModeInit(LCDIF, &lcd_config);
|
||||
ELCDIF_RgbModeStart(LCDIF);
|
||||
|
@ -155,16 +161,58 @@ static rt_err_t rt1050_lcd_init(rt_device_t device)
|
|||
lcd.info.height = LCD_HEIGHT;
|
||||
lcd.info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565;
|
||||
lcd.info.bits_per_pixel = 16;
|
||||
lcd.info.framebuffer = (void *)frame_buffer;
|
||||
lcd.info.framebuffer = (void *)rt_malloc_align(LCD_WIDTH * LCD_HEIGHT * 2, 32);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
void LCDIF_IRQHandler(void)
|
||||
{
|
||||
uint32_t intStatus;
|
||||
|
||||
intStatus = ELCDIF_GetInterruptStatus(LCDIF);
|
||||
|
||||
ELCDIF_ClearInterruptStatus(LCDIF, intStatus);
|
||||
if (intStatus & kELCDIF_CurFrameDone)
|
||||
{
|
||||
fb_modified = RT_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static rt_err_t rt1050_lcd_control(rt_device_t device, int cmd, void *args)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case RTGRAPHIC_CTRL_RECT_UPDATE:
|
||||
{
|
||||
uint8_t *ptr;
|
||||
|
||||
if (fb_index == 0)
|
||||
{
|
||||
ptr = (uint8_t *)&frame_buffer1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = (uint8_t *)&frame_buffer0[0];
|
||||
}
|
||||
|
||||
while(LCDIF->CUR_BUF != LCDIF->NEXT_BUF);
|
||||
|
||||
memcpy(ptr, lcd.info.framebuffer, LCD_WIDTH * LCD_HEIGHT * 2);
|
||||
|
||||
if (fb_index == 0)
|
||||
{
|
||||
/* use fb1 */
|
||||
ELCDIF_SetNextBufferAddr(LCDIF, (uint32_t)&frame_buffer1[0]);
|
||||
fb_index = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use fb0 */
|
||||
ELCDIF_SetNextBufferAddr(LCDIF, (uint32_t)&frame_buffer0[0]);
|
||||
fb_index = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case RTGRAPHIC_CTRL_POWERON:
|
||||
|
@ -176,7 +224,7 @@ static rt_err_t rt1050_lcd_control(rt_device_t device, int cmd, void *args)
|
|||
break;
|
||||
|
||||
case RTGRAPHIC_CTRL_GET_INFO:
|
||||
rt_memcpy(args, &lcd.info, sizeof(lcd.info));
|
||||
memcpy(args, &lcd.info, sizeof(lcd.info));
|
||||
break;
|
||||
|
||||
case RTGRAPHIC_CTRL_SET_MODE:
|
||||
|
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-02-08 Zhangyihong the first version
|
||||
* 2018-10-29 XY
|
||||
*/
|
||||
#include "drv_touch.h"
|
||||
|
||||
|
||||
#define TOUCH_I2C_NAME "i2c1"
|
||||
|
||||
#ifndef TOUCH_SAMPLE_HZ
|
||||
#define TOUCH_SAMPLE_HZ (50)
|
||||
#endif
|
||||
|
||||
#ifndef TOUCH_I2C_NAME
|
||||
#error "Please define touch i2c name!"
|
||||
#endif
|
||||
|
||||
#ifdef PKG_USING_GUIENGINE
|
||||
#include <rtgui/event.h>
|
||||
#include <rtgui/rtgui_server.h>
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define TPDEBUG rt_kprintf
|
||||
#else
|
||||
#define TPDEBUG(...)
|
||||
#endif
|
||||
|
||||
static rt_slist_t _driver_list;
|
||||
static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
|
||||
|
||||
static void post_down_event(rt_uint16_t x, rt_uint16_t y, rt_uint32_t id)
|
||||
{
|
||||
#ifdef PKG_USING_GUIENGINE
|
||||
rt_err_t result;
|
||||
struct rtgui_event_mouse emouse;
|
||||
|
||||
emouse.parent.sender = RT_NULL;
|
||||
emouse.wid = RT_NULL;
|
||||
|
||||
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
|
||||
emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN;
|
||||
emouse.x = x;
|
||||
emouse.y = y;
|
||||
emouse.ts = rt_tick_get();
|
||||
emouse.id = id;
|
||||
|
||||
do
|
||||
{
|
||||
result = rtgui_server_post_event(&emouse.parent, sizeof(emouse));
|
||||
if (result != RT_EOK)
|
||||
{
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / TOUCH_SAMPLE_HZ);
|
||||
}
|
||||
}
|
||||
while (result != RT_EOK);
|
||||
|
||||
TPDEBUG("[TP] touch down [%d, %d]\n", emouse.x, emouse.y);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void post_motion_event(rt_uint16_t x, rt_uint16_t y, rt_uint32_t id)
|
||||
{
|
||||
#ifdef PKG_USING_GUIENGINE
|
||||
struct rtgui_event_mouse emouse;
|
||||
|
||||
emouse.parent.sender = RT_NULL;
|
||||
emouse.wid = RT_NULL;
|
||||
|
||||
emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN;
|
||||
emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION;
|
||||
emouse.x = x;
|
||||
emouse.y = y;
|
||||
emouse.ts = rt_tick_get();
|
||||
emouse.id = id;
|
||||
rtgui_server_post_event(&emouse.parent, sizeof(emouse));
|
||||
TPDEBUG("[TP] touch motion [%d, %d]\n", emouse.x, emouse.y);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void post_up_event(rt_uint16_t x, rt_uint16_t y, rt_uint32_t id)
|
||||
{
|
||||
#ifdef PKG_USING_GUIENGINE
|
||||
rt_err_t result;
|
||||
struct rtgui_event_mouse emouse;
|
||||
|
||||
emouse.parent.sender = RT_NULL;
|
||||
emouse.wid = RT_NULL;
|
||||
|
||||
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
|
||||
emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP;
|
||||
emouse.x = x;
|
||||
emouse.y = y;
|
||||
emouse.ts = rt_tick_get();
|
||||
emouse.id = id;
|
||||
|
||||
do
|
||||
{
|
||||
result = rtgui_server_post_event(&emouse.parent, sizeof(emouse));
|
||||
if (result != RT_EOK)
|
||||
{
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / TOUCH_SAMPLE_HZ);
|
||||
}
|
||||
}
|
||||
while (result != RT_EOK);
|
||||
|
||||
TPDEBUG("[TP] touch up [%d, %d]\n", emouse.x, emouse.y);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void touch_run(void* parameter)
|
||||
{
|
||||
rt_tick_t emouse_id = 0;
|
||||
struct touch_message msg;
|
||||
rt_slist_t *driver_list = NULL;
|
||||
struct touch_driver *current_driver = RT_NULL;
|
||||
|
||||
i2c_bus = rt_i2c_bus_device_find(TOUCH_I2C_NAME);
|
||||
RT_ASSERT(i2c_bus);
|
||||
|
||||
if(rt_device_open(&i2c_bus->parent, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rt_slist_for_each(driver_list, &_driver_list)
|
||||
{
|
||||
current_driver = (struct touch_driver *)driver_list;
|
||||
if(current_driver->probe(i2c_bus) == RT_TRUE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
current_driver = RT_NULL;
|
||||
}
|
||||
|
||||
if(current_driver == RT_NULL)
|
||||
{
|
||||
rt_kprintf("[TP] No touch pad or driver.\n");
|
||||
rt_device_close((rt_device_t)i2c_bus);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
current_driver->ops->init(i2c_bus);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (rt_sem_take(current_driver->isr_sem, RT_WAITING_FOREVER) != RT_EOK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current_driver->ops->read_point(&msg) != RT_EOK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (msg.event)
|
||||
{
|
||||
case TOUCH_EVENT_MOVE:
|
||||
post_motion_event(msg.x, msg.y, emouse_id);
|
||||
break;
|
||||
|
||||
case TOUCH_EVENT_DOWN:
|
||||
emouse_id = rt_tick_get();
|
||||
post_down_event(msg.x, msg.y, emouse_id);
|
||||
break;
|
||||
|
||||
case TOUCH_EVENT_UP:
|
||||
post_up_event(msg.x, msg.y, emouse_id);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / TOUCH_SAMPLE_HZ);
|
||||
}
|
||||
}
|
||||
|
||||
rt_err_t rt_touch_drivers_register(touch_driver_t drv)
|
||||
{
|
||||
RT_ASSERT(drv != RT_NULL);
|
||||
RT_ASSERT(drv->ops != RT_NULL);
|
||||
RT_ASSERT(drv->probe != RT_NULL);
|
||||
|
||||
rt_slist_append(&_driver_list, &drv->list);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int rt_touch_list_init(void)
|
||||
{
|
||||
rt_slist_init(&_driver_list);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
INIT_BOARD_EXPORT(rt_touch_list_init);
|
||||
|
||||
static int rt_touch_init(void)
|
||||
{
|
||||
rt_thread_t thread = RT_NULL;
|
||||
|
||||
thread = rt_thread_create("touch", touch_run, RT_NULL, 2048, 28, 20);
|
||||
if(thread)
|
||||
{
|
||||
return rt_thread_startup(thread);
|
||||
}
|
||||
|
||||
return RT_ERROR;
|
||||
}
|
||||
INIT_APP_EXPORT(rt_touch_init);
|
||||
|
||||
int rt_touch_read(rt_uint16_t addr, void *cmd_buf, size_t cmd_len, void *data_buf, size_t data_len)
|
||||
{
|
||||
struct rt_i2c_msg msgs[2];
|
||||
|
||||
msgs[0].addr = addr;
|
||||
msgs[0].flags = RT_I2C_WR;
|
||||
msgs[0].buf = cmd_buf;
|
||||
msgs[0].len = cmd_len;
|
||||
|
||||
msgs[1].addr = addr;
|
||||
msgs[1].flags = RT_I2C_RD;
|
||||
msgs[1].buf = data_buf;
|
||||
msgs[1].len = data_len;
|
||||
|
||||
if (rt_i2c_transfer(i2c_bus, msgs, 2) == 2)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rt_touch_write(rt_uint16_t addr, void *data_buf, size_t data_len)
|
||||
{
|
||||
struct rt_i2c_msg msgs[1];
|
||||
|
||||
msgs[0].addr = addr;
|
||||
msgs[0].flags = RT_I2C_WR;
|
||||
msgs[0].buf = data_buf;
|
||||
msgs[0].len = data_len;
|
||||
|
||||
if (rt_i2c_transfer(i2c_bus, msgs, 1) == 1)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-02-08 Zhangyihong the first version
|
||||
* 2018-10-29 XY
|
||||
*/
|
||||
#ifndef __DRV_TOUCH_H__
|
||||
#define __DRV_TOUCH_H__
|
||||
|
||||
#include "rtthread.h"
|
||||
#include "rtdevice.h"
|
||||
|
||||
#define TOUCH_EVENT_UP (0x01)
|
||||
#define TOUCH_EVENT_DOWN (0x02)
|
||||
#define TOUCH_EVENT_MOVE (0x03)
|
||||
#define TOUCH_EVENT_NONE (0x80)
|
||||
|
||||
struct touch_message
|
||||
{
|
||||
rt_uint16_t x;
|
||||
rt_uint16_t y;
|
||||
rt_uint8_t event;
|
||||
};
|
||||
typedef struct touch_message *touch_message_t;
|
||||
|
||||
struct touch_ops
|
||||
{
|
||||
void (*init)(struct rt_i2c_bus_device *);
|
||||
void (*deinit)(void);
|
||||
rt_err_t (*read_point)(touch_message_t);
|
||||
};
|
||||
typedef struct touch_ops *touch_ops_t;
|
||||
|
||||
struct touch_driver
|
||||
{
|
||||
rt_slist_t list;
|
||||
rt_bool_t (*probe)(struct rt_i2c_bus_device *i2c_bus);
|
||||
rt_sem_t isr_sem;
|
||||
touch_ops_t ops;
|
||||
void *user_data;
|
||||
};
|
||||
typedef struct touch_driver *touch_driver_t;
|
||||
|
||||
rt_err_t rt_touch_drivers_register(touch_driver_t drv);
|
||||
|
||||
int rt_touch_read(rt_uint16_t addr, void *cmd_buf, size_t cmd_len, void *data_buf, size_t data_len);
|
||||
int rt_touch_write(rt_uint16_t addr, void *data_buf, size_t data_len);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* 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
|
||||
* 2018-10-29 XY
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#include "drv_touch.h"
|
||||
#include "fsl_iomuxc.h"
|
||||
#include "fsl_gpio.h"
|
||||
|
||||
|
||||
#define TP_INT_PIN 54 /* GPIO_AD_B0_11 */
|
||||
#define TP_RST_PIN 45 /* GPIO_AD_B0_02 */
|
||||
|
||||
#define FT5x06_TS_ADDR (0x38)
|
||||
|
||||
#if 0
|
||||
#define TPDEBUG rt_kprintf
|
||||
#else
|
||||
#define TPDEBUG(...)
|
||||
#endif
|
||||
|
||||
static struct touch_driver ft5x06_driver;
|
||||
|
||||
typedef enum _touch_event
|
||||
{
|
||||
kTouch_Down = 0, /*!< The state changed to touched. */
|
||||
kTouch_Up = 1, /*!< The state changed to not touched. */
|
||||
kTouch_Contact = 2, /*!< There is a continuous touch being detected. */
|
||||
kTouch_Reserved = 3 /*!< No touch information available. */
|
||||
} touch_event_t;
|
||||
|
||||
typedef struct _touch_point
|
||||
{
|
||||
touch_event_t TOUCH_EVENT; /*!< Indicates the state or event of the touch point. */
|
||||
uint8_t TOUCH_ID; /*!< Id of the touch point. This numeric value stays constant between down and up event. */
|
||||
uint16_t TOUCH_X; /*!< X coordinate of the touch point */
|
||||
uint16_t TOUCH_Y; /*!< Y coordinate of the touch point */
|
||||
} touch_point_t;
|
||||
|
||||
typedef struct _ft5406_touch_point
|
||||
{
|
||||
uint8_t XH;
|
||||
uint8_t XL;
|
||||
uint8_t YH;
|
||||
uint8_t YL;
|
||||
uint8_t RESERVED[2];
|
||||
} ft5406_touch_point_t;
|
||||
|
||||
typedef struct _ft5406_touch_data
|
||||
{
|
||||
uint8_t DEVIDE_MODE;
|
||||
uint8_t GEST_ID;
|
||||
uint8_t TD_STATUS;
|
||||
ft5406_touch_point_t TOUCH;
|
||||
} ft5406_touch_data_t;
|
||||
|
||||
#define TOUCH_POINT_GET_EVENT(T) ((touch_event_t)((T).XH >> 6))
|
||||
#define TOUCH_POINT_GET_ID(T) ((T).YH >> 4)
|
||||
#define TOUCH_POINT_GET_X(T) ((((T).XH & 0x0f) << 8) | (T).XL)
|
||||
#define TOUCH_POINT_GET_Y(T) ((((T).YH & 0x0f) << 8) | (T).YL)
|
||||
|
||||
static int ft5406_read_touch(touch_point_t *dp)
|
||||
{
|
||||
rt_uint8_t cmd = 0;
|
||||
ft5406_touch_data_t touch_data;
|
||||
|
||||
if (rt_touch_read(FT5x06_TS_ADDR, &cmd, 1, &touch_data, sizeof(ft5406_touch_data_t)) != 0)
|
||||
return -1;
|
||||
|
||||
dp->TOUCH_X = TOUCH_POINT_GET_Y(touch_data.TOUCH);
|
||||
dp->TOUCH_Y = TOUCH_POINT_GET_X(touch_data.TOUCH);
|
||||
dp->TOUCH_EVENT = TOUCH_POINT_GET_EVENT(touch_data.TOUCH);
|
||||
dp->TOUCH_ID = TOUCH_POINT_GET_ID(touch_data.TOUCH);
|
||||
|
||||
if (dp->TOUCH_EVENT == 3) return -1;
|
||||
|
||||
if (touch_data.TD_STATUS != 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void ft5x06_isr_enable(rt_bool_t enable)
|
||||
{
|
||||
if(enable == RT_TRUE)
|
||||
{
|
||||
rt_pin_irq_enable(TP_INT_PIN, PIN_IRQ_ENABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_pin_irq_enable(TP_INT_PIN, PIN_IRQ_DISABLE);
|
||||
}
|
||||
}
|
||||
|
||||
static void ft5x06_touch_isr(void *parameter)
|
||||
{
|
||||
TPDEBUG("[TP] ft5x06_touch_isr\n");
|
||||
|
||||
ft5x06_isr_enable(RT_FALSE);
|
||||
rt_sem_release(ft5x06_driver.isr_sem);
|
||||
}
|
||||
|
||||
static rt_err_t ft5x06_read_point(touch_message_t msg)
|
||||
{
|
||||
touch_point_t dp;
|
||||
|
||||
if (ft5406_read_touch(&dp) != 0)
|
||||
{
|
||||
msg->event = TOUCH_EVENT_UP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dp.TOUCH_EVENT == kTouch_Up)
|
||||
{
|
||||
msg->event = TOUCH_EVENT_UP;
|
||||
}
|
||||
else if (dp.TOUCH_EVENT == kTouch_Down)
|
||||
{
|
||||
msg->event = TOUCH_EVENT_DOWN;
|
||||
}
|
||||
else if (dp.TOUCH_EVENT == kTouch_Contact)
|
||||
{
|
||||
msg->event = TOUCH_EVENT_MOVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->event = TOUCH_EVENT_UP;
|
||||
}
|
||||
}
|
||||
|
||||
msg->x = dp.TOUCH_X;
|
||||
msg->y = dp.TOUCH_Y;
|
||||
|
||||
TPDEBUG("[TP] [%d, %d] %s\n", msg->x, msg->y,
|
||||
msg->event == TOUCH_EVENT_DOWN ? "DOWN" : (msg->event == TOUCH_EVENT_MOVE ? "MOVE" : (msg->event == TOUCH_EVENT_UP ? "UP" : "NONE")));
|
||||
|
||||
if (msg->event != TOUCH_EVENT_UP)
|
||||
{
|
||||
rt_sem_release(ft5x06_driver.isr_sem);
|
||||
}
|
||||
else
|
||||
{
|
||||
ft5x06_isr_enable(RT_TRUE);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static void ft5x06_init(struct rt_i2c_bus_device *i2c_bus)
|
||||
{
|
||||
ft5x06_driver.isr_sem = rt_sem_create("ft5x06", 0, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(ft5x06_driver.isr_sem);
|
||||
|
||||
rt_pin_attach_irq(TP_INT_PIN, PIN_IRQ_MODE_LOW_LEVEL, ft5x06_touch_isr, &ft5x06_driver);
|
||||
rt_pin_irq_enable(TP_INT_PIN, PIN_IRQ_ENABLE);
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 5);
|
||||
}
|
||||
|
||||
static void ft5x06_deinit(void)
|
||||
{
|
||||
if (ft5x06_driver.isr_sem)
|
||||
{
|
||||
rt_sem_delete(ft5x06_driver.isr_sem);
|
||||
ft5x06_driver.isr_sem = RT_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct touch_ops ft5x06_ops =
|
||||
{
|
||||
ft5x06_init,
|
||||
ft5x06_deinit,
|
||||
ft5x06_read_point,
|
||||
};
|
||||
|
||||
static void ft5406_hw_reset(void)
|
||||
{
|
||||
gpio_pin_config_t pin_config =
|
||||
{
|
||||
kGPIO_DigitalOutput, 0,
|
||||
};
|
||||
|
||||
CLOCK_EnableClock(kCLOCK_Gpio1);
|
||||
|
||||
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, 0U);
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, 0x10B0u);
|
||||
|
||||
/* Enable touch panel controller */
|
||||
GPIO_PinInit(GPIO1, 2, &pin_config);
|
||||
GPIO_WritePinOutput(GPIO1, 2, 1);
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 20);
|
||||
GPIO_WritePinOutput(GPIO1, 2, 0);
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 20);
|
||||
GPIO_WritePinOutput(GPIO1, 2, 1);
|
||||
}
|
||||
|
||||
static rt_bool_t ft5x06_probe(struct rt_i2c_bus_device *i2c_bus)
|
||||
{
|
||||
rt_uint16_t cmd = 0x000c;
|
||||
rt_uint16_t tmp[2];
|
||||
rt_uint16_t CurVersion;
|
||||
|
||||
ft5406_hw_reset();
|
||||
|
||||
if (rt_touch_read(FT5x06_TS_ADDR, &cmd, 2, tmp, 2) != 0)
|
||||
{
|
||||
TPDEBUG("[TP] %s failed!\n", __func__);
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
CurVersion = (tmp[0]<<8) | tmp[1];
|
||||
rt_kprintf("[TP] FT5X06 Touch Version : %d\n", CurVersion);
|
||||
|
||||
return RT_TRUE;
|
||||
}
|
||||
|
||||
int ft5x06_driver_register(void)
|
||||
{
|
||||
ft5x06_driver.probe = ft5x06_probe;
|
||||
ft5x06_driver.ops = &ft5x06_ops;
|
||||
ft5x06_driver.user_data = RT_NULL;
|
||||
|
||||
rt_touch_drivers_register(&ft5x06_driver);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_ENV_EXPORT(ft5x06_driver_register);
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-02-08 Zhangyihong the first version
|
||||
* 2018-04-03 XY gt9xx for 1024 * 600
|
||||
* 2018-04-14 liu2guang optimize int and rst to pin framework
|
||||
* 2018-10-29 XY
|
||||
*/
|
||||
|
||||
#include "drv_touch.h"
|
||||
#include "string.h"
|
||||
#include "drv_pin.h"
|
||||
|
||||
|
||||
#define TP_INT_PIN 54 /* GPIO_AD_B0_11 */
|
||||
#define TP_RST_PIN 45 /* GPIO_AD_B0_02 */
|
||||
|
||||
#ifndef TP_INT_PIN
|
||||
#error "Please config touch panel INT pin."
|
||||
#endif
|
||||
#ifndef TP_RST_PIN
|
||||
#error "Please config touch panel RST pin."
|
||||
#endif
|
||||
|
||||
#ifndef IIC_RETRY_NUM
|
||||
#define IIC_RETRY_NUM 2
|
||||
#endif
|
||||
|
||||
#define GT9xx_TS_ADDR (0x5D)
|
||||
|
||||
#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) /* 产品ID */
|
||||
#define gt9xx_VENDOR_ID_REG (0x814A) /* 当前模组选项信息 */
|
||||
#define gt9xx_CONFIG_VERSION_REG (0x8047) /* 配置文件版本号 */
|
||||
#define gt9xx_CONFIG_CHECKSUM_REG (0x80FF) /* 配置文件校验码 */
|
||||
#define gt9xx_FIRMWARE_VERSION_REG (0x8144) /* 固件版本号 */
|
||||
|
||||
#if 0
|
||||
#define TPDEBUG rt_kprintf
|
||||
#else
|
||||
#define TPDEBUG(...)
|
||||
#endif
|
||||
|
||||
static struct touch_driver gt9xx_driver;
|
||||
|
||||
static void gt9xx_hw_reset(rt_uint8_t address)
|
||||
{
|
||||
rt_pin_mode(TP_INT_PIN, PIN_MODE_OUTPUT);
|
||||
rt_pin_mode(TP_RST_PIN, PIN_MODE_OUTPUT);
|
||||
|
||||
if(address == 0x5D)
|
||||
{
|
||||
rt_pin_write(TP_INT_PIN, PIN_LOW);
|
||||
rt_pin_write(TP_RST_PIN, PIN_LOW);
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 50);
|
||||
|
||||
rt_pin_write(TP_RST_PIN, PIN_HIGH);
|
||||
rt_pin_write(TP_INT_PIN, PIN_LOW);
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 50);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_pin_write(TP_INT_PIN, PIN_LOW);
|
||||
rt_pin_write(TP_RST_PIN, PIN_LOW);
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 50);
|
||||
|
||||
rt_pin_write(TP_RST_PIN, PIN_LOW);
|
||||
rt_pin_write(TP_INT_PIN, PIN_HIGH);
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 50);
|
||||
|
||||
rt_pin_write(TP_RST_PIN, PIN_HIGH);
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 50);
|
||||
}
|
||||
}
|
||||
|
||||
static void gt9xx_soft_reset(struct rt_i2c_bus_device *i2c_bus)
|
||||
{
|
||||
rt_uint8_t buf[3];
|
||||
|
||||
buf[0] = (rt_uint8_t)((gt9xx_COMMAND_REG >> 8) & 0xFF);
|
||||
buf[1] = (rt_uint8_t)(gt9xx_COMMAND_REG & 0xFF);
|
||||
buf[2] = 0x02;
|
||||
rt_touch_write(GT9xx_TS_ADDR, buf, 3);
|
||||
}
|
||||
|
||||
static rt_bool_t gt9xx_probe(struct rt_i2c_bus_device *i2c_bus)
|
||||
{
|
||||
rt_uint8_t cmd[2];
|
||||
rt_uint8_t buffer[5] = {0};
|
||||
|
||||
gt9xx_hw_reset(GT9xx_TS_ADDR);
|
||||
//gt9xx_soft_reset(i2c_bus);
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 5);
|
||||
|
||||
cmd[0] = (rt_uint8_t)((gt9xx_PRODUCT_ID_REG >> 8) & 0xFF);
|
||||
cmd[1] = (rt_uint8_t)(gt9xx_PRODUCT_ID_REG & 0xFF);
|
||||
if (rt_touch_read(GT9xx_TS_ADDR, &cmd, 2, buffer, 4) != 0)
|
||||
return RT_FALSE;
|
||||
|
||||
buffer[4] = '\0';
|
||||
|
||||
TPDEBUG("%#X %#X %#X %#X %#X\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4]);
|
||||
|
||||
if(!rt_strcmp((const char*)buffer, "911"))
|
||||
{
|
||||
rt_kprintf("[TP] Found chip gt911\r\n");
|
||||
return RT_TRUE;
|
||||
}
|
||||
else if(!rt_strcmp((const char*)buffer, "9147"))
|
||||
{
|
||||
rt_kprintf("[TP] Found chip gt9147\r\n");
|
||||
return RT_TRUE;
|
||||
}
|
||||
else if(!rt_strcmp((const char*)buffer, "9157"))
|
||||
{
|
||||
rt_kprintf("[TP] Found chip gt9157\r\n");
|
||||
return RT_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
TPDEBUG("[TP] Uknow chip gt9xx device: [%s]\r\n", buffer);
|
||||
}
|
||||
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
static void gt9xx_init(struct rt_i2c_bus_device *i2c_bus)
|
||||
{
|
||||
rt_uint8_t buf = 0;
|
||||
rt_uint8_t cmd[2];
|
||||
|
||||
gt9xx_driver.isr_sem = rt_sem_create("gt9xx", 0, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(gt9xx_driver.isr_sem);
|
||||
|
||||
cmd[0] = (rt_uint8_t)((gt9xx_CONFIG_VERSION_REG >> 8) & 0xFF);
|
||||
cmd[1] = (rt_uint8_t)(gt9xx_CONFIG_VERSION_REG & 0xFF);
|
||||
rt_touch_read(GT9xx_TS_ADDR, &cmd, 2, &buf, 1);
|
||||
rt_kprintf("[TP] GT9xx Config version: 0x%02X\n", buf);
|
||||
|
||||
cmd[0] = (rt_uint8_t)((gt9xx_VENDOR_ID_REG >> 8) & 0xFF);
|
||||
cmd[1] = (rt_uint8_t)(gt9xx_VENDOR_ID_REG & 0xFF);
|
||||
rt_touch_read(GT9xx_TS_ADDR, &cmd, 2, &buf, 1);
|
||||
rt_kprintf("[TP] GT9xx Sensor id: 0x%02X\n", buf);
|
||||
|
||||
rt_sem_release(gt9xx_driver.isr_sem);
|
||||
}
|
||||
|
||||
static void gt9xx_deinit(void)
|
||||
{
|
||||
rt_sem_delete(gt9xx_driver.isr_sem);
|
||||
}
|
||||
|
||||
static rt_err_t gt9xx_read_point(touch_message_t msg)
|
||||
{
|
||||
rt_uint8_t cmd[2];
|
||||
rt_uint8_t buf[8] = {0};
|
||||
static rt_uint8_t s_tp_down = 0;
|
||||
|
||||
cmd[0] = (rt_uint8_t)((gt9xx_READ_XY_REG >> 8) & 0xFF);
|
||||
cmd[1] = (rt_uint8_t)(gt9xx_READ_XY_REG & 0xFF);
|
||||
rt_touch_read(GT9xx_TS_ADDR, &cmd, 2, buf, 8);
|
||||
|
||||
if((buf[0] & 0x01) == 0)
|
||||
{
|
||||
if(s_tp_down)
|
||||
{
|
||||
s_tp_down = 0;
|
||||
msg->event = TOUCH_EVENT_UP;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->event = TOUCH_EVENT_NONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->event = TOUCH_EVENT_DOWN;
|
||||
s_tp_down = 1;
|
||||
}
|
||||
}
|
||||
|
||||
buf[0] = ((gt9xx_CLEARBUF_REG >> 8) & 0xFF);
|
||||
buf[1] = (gt9xx_CLEARBUF_REG & 0xFF);
|
||||
buf[2] = 0x00;
|
||||
rt_touch_write(GT9xx_TS_ADDR, buf, 3);
|
||||
|
||||
rt_sem_release(gt9xx_driver.isr_sem);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
struct touch_ops gt9xx_ops =
|
||||
{
|
||||
.init = gt9xx_init,
|
||||
.deinit = gt9xx_deinit,
|
||||
.read_point = gt9xx_read_point,
|
||||
};
|
||||
|
||||
static int gt9xx_driver_register(void)
|
||||
{
|
||||
gt9xx_driver.probe = gt9xx_probe;
|
||||
gt9xx_driver.ops = >9xx_ops;
|
||||
gt9xx_driver.user_data = RT_NULL;
|
||||
|
||||
rt_touch_drivers_register(>9xx_driver);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
INIT_ENV_EXPORT(gt9xx_driver_register);
|
Loading…
Reference in New Issue