Browse Source

Merge pull request #1937 from yangfasheng/master

add touch driver; update lcd driver;
Bernard Xiong 6 years ago
parent
commit
62c3e74e3d

+ 3 - 2
bsp/imxrt/Libraries/imxrt1050/drivers/SConscript

@@ -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'):
@@ -67,6 +65,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)
 

+ 0 - 340
bsp/imxrt/Libraries/imxrt1050/drivers/drv_ft5406.c

@@ -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);

+ 57 - 9
bsp/imxrt/Libraries/imxrt1050/drivers/drv_lcd.c

@@ -16,16 +16,16 @@
 #include "fsl_elcdif.h"
 
 #if !defined(LCD_WIDTH) || !defined(LCD_HEIGHT)
-    #error "Please config lcd pixel parameters."
+#error "Please config lcd pixel parameters."
 #endif
 
 #if !defined(LCD_HFP) || !defined(LCD_HBP) || !defined(LCD_HSW) || \
     !defined(LCD_VFP) || !defined(LCD_VBP) || !defined(LCD_VSW)
-    #error "Please config lcd timing parameters."
+#error "Please config lcd timing parameters."
 #endif
 
 #if !defined(LCD_BL_PIN) || !defined(LCD_RST_PIN)
-    #error "Please config lcd backlight or reset pin."
+#error "Please config lcd backlight or reset pin."
 #endif
 
 struct rt1050_lcd
@@ -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,17 +161,59 @@ 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:
-        break;
+    {
+        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:
         rt_pin_write(LCD_BL_PIN, PIN_HIGH);
@@ -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:

+ 253 - 0
bsp/imxrt/Libraries/imxrt1050/drivers/touch/drv_touch.c

@@ -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;
+}

+ 53 - 0
bsp/imxrt/Libraries/imxrt1050/drivers/touch/drv_touch.h

@@ -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

+ 235 - 0
bsp/imxrt/Libraries/imxrt1050/drivers/touch/drv_touch_ft5x06.c

@@ -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);

+ 225 - 0
bsp/imxrt/Libraries/imxrt1050/drivers/touch/drv_touch_gt9xx.c

@@ -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       = &gt9xx_ops;
+    gt9xx_driver.user_data = RT_NULL;
+
+    rt_touch_drivers_register(&gt9xx_driver);
+
+    return RT_EOK;
+}
+INIT_ENV_EXPORT(gt9xx_driver_register);