diff --git a/bsp/imxrt/Libraries/imxrt1050/drivers/SConscript b/bsp/imxrt/Libraries/imxrt1050/drivers/SConscript index 7e9b391e3ebcfb74994f24706fbf9e6379b5e5d4..fa1b4693f54cf346148dcbe5d1fc7e9b57092442 100644 --- a/bsp/imxrt/Libraries/imxrt1050/drivers/SConscript +++ b/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) diff --git a/bsp/imxrt/Libraries/imxrt1050/drivers/drv_ft5406.c b/bsp/imxrt/Libraries/imxrt1050/drivers/drv_ft5406.c deleted file mode 100644 index ab5a8baa392841554a650894a93d0775e2e052c0..0000000000000000000000000000000000000000 --- a/bsp/imxrt/Libraries/imxrt1050/drivers/drv_ft5406.c +++ /dev/null @@ -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 -#include -#include - -#include -#include - -#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); diff --git a/bsp/imxrt/Libraries/imxrt1050/drivers/drv_lcd.c b/bsp/imxrt/Libraries/imxrt1050/drivers/drv_lcd.c index 209fc7787ab5268032788e8413b0b0d3cb6a08b1..06f95acadf9487c9bfc725a738c5442e4cf24320 100644 --- a/bsp/imxrt/Libraries/imxrt1050/drivers/drv_lcd.c +++ b/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: diff --git a/bsp/imxrt/Libraries/imxrt1050/drivers/touch/drv_touch.c b/bsp/imxrt/Libraries/imxrt1050/drivers/touch/drv_touch.c new file mode 100644 index 0000000000000000000000000000000000000000..721752ef4c0373e6074bfd84cb691f63f515c7e3 --- /dev/null +++ b/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 +#include +#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; +} diff --git a/bsp/imxrt/Libraries/imxrt1050/drivers/touch/drv_touch.h b/bsp/imxrt/Libraries/imxrt1050/drivers/touch/drv_touch.h new file mode 100644 index 0000000000000000000000000000000000000000..b12b19d6063a588fa5743b79c5cd2e90d66a9aff --- /dev/null +++ b/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 diff --git a/bsp/imxrt/Libraries/imxrt1050/drivers/touch/drv_touch_ft5x06.c b/bsp/imxrt/Libraries/imxrt1050/drivers/touch/drv_touch_ft5x06.c new file mode 100644 index 0000000000000000000000000000000000000000..bbe71b3b1c67bd11fdb57ec8683352bc42f237f1 --- /dev/null +++ b/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 +#include +#include +#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); diff --git a/bsp/imxrt/Libraries/imxrt1050/drivers/touch/drv_touch_gt9xx.c b/bsp/imxrt/Libraries/imxrt1050/drivers/touch/drv_touch_gt9xx.c new file mode 100644 index 0000000000000000000000000000000000000000..15fb73b1193f4e2a0857c3dfe31a92cbadfacf2a --- /dev/null +++ b/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 = >9xx_ops; + gt9xx_driver.user_data = RT_NULL; + + rt_touch_drivers_register(>9xx_driver); + + return RT_EOK; +} +INIT_ENV_EXPORT(gt9xx_driver_register);