From e15526f6838676143bf0bbca1d5584671ff4cda5 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 25 Feb 2018 11:20:39 -0600 Subject: [PATCH] apps/graphics/ft80x: Add more touchscreen interfaces. apps/examples/ft80x: Add an interactive example using buttons, keys, and touchscreen input. --- examples/ft80x/ft80x.h | 1 + examples/ft80x/ft80x_coprocessor.c | 373 +++++++++++++++++++++++++++++ examples/ft80x/ft80x_main.c | 4 +- graphics/ft80x/Kconfig | 8 + graphics/ft80x/ft80x.h | 2 +- graphics/ft80x/ft80x_regs.c | 2 +- graphics/ft80x/ft80x_touch.c | 307 +++++++++++++++++++++++- include/graphics/ft80x.h | 95 ++++++++ 8 files changed, 788 insertions(+), 4 deletions(-) diff --git a/examples/ft80x/ft80x.h b/examples/ft80x/ft80x.h index 2dbd5daf2..fa4bb3e8d 100644 --- a/examples/ft80x/ft80x.h +++ b/examples/ft80x/ft80x.h @@ -169,6 +169,7 @@ int ft80x_coproc_spinner(int fd, FAR struct ft80x_dlbuffer_s *buffer); #endif int ft80x_coproc_screensaver(int fd, FAR struct ft80x_dlbuffer_s *buffer); int ft80x_coproc_logo(int fd, FAR struct ft80x_dlbuffer_s *buffer); +int ft80x_coproc_interactive(int fd, FAR struct ft80x_dlbuffer_s *buffer); #undef EXTERN #ifdef __cplusplus diff --git a/examples/ft80x/ft80x_coprocessor.c b/examples/ft80x/ft80x_coprocessor.c index c0b4331b0..e2af7ae7a 100644 --- a/examples/ft80x/ft80x_coprocessor.c +++ b/examples/ft80x/ft80x_coprocessor.c @@ -49,6 +49,12 @@ #include "graphics/ft80x.h" #include "ft80x.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define INTERACTIVE_TEXTSIZE (512) + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -4099,3 +4105,370 @@ int ft80x_coproc_logo(int fd, FAR struct ft80x_dlbuffer_s *buffer) return ret; } + +/**************************************************************************** + * Name: ft80x_coproc_interactive + * + * Description: + * Demonstrate the keys HMI interactions + * + ****************************************************************************/ + +int ft80x_coproc_interactive(int fd, FAR struct ft80x_dlbuffer_s *buffer) +{ + int16_t fontid; + int16_t width ; + int16_t height; + int16_t ydist; + int16_t yoffset; + char text[INTERACTIVE_TEXTSIZE]; + char ch = '|'; + uint8_t currtag = 0; + uint8_t prevtag = 0; + int32_t textndx = 0; + int ret; + int i; + + /* Formatted output chunks */ + + union + { + struct + { + struct ft80x_cmd32_s clearrgb; + struct ft80x_cmd32_s clear; + struct ft80x_cmd32_s colorrgb; + } a; + struct + { + struct ft80x_cmd32_s tagmask; + struct ft80x_cmd_text_s text; + } b; + struct + { + struct ft80x_cmd32_s tagmask; + struct ft80x_cmd_gradcolor_s gradcolor; + struct ft80x_cmd_keys_s keys; + } c; + struct + { + struct ft80x_cmd_gradcolor_s gradcolor; + struct ft80x_cmd_keys_s keys; + } d; + struct + { + struct ft80x_cmd32_s tag; + struct ft80x_cmd_button_s button; + } e; + struct + { + struct ft80x_cmd32_s colora; + struct ft80x_cmd_keys_s keys; + } f; + struct ft80x_cmd_keys_s keys; + } cmds; + +#ifdef CONFIG_LCD_FT80X_QVGA + fontid = 27; + width = 22; + height = 22; + ydist = 3; +#else + fontid = 29; + width = 30; + height = 30; + ydist = 5; +#endif + + for (i = 0; i < 600; i++) + { + /* Check the user input and then add the characters into array. + * Hmmm... a better example might use the FT80X_IOC_EVENTNOTIFY ioctl + * command to wait for a touch event. + */ + + currtag = ft80x_touch_tag(fd); + + ch = currtag; + if (currtag == 0) + { + /* No touch */ + + ch = '|'; + + /* Check if we lost the touch */ + + if (prevtag != 0) + { + textndx++; + + /* Clear all the characters after 100 are pressed */ + + if (textndx > 24) + { + textndx = 0; + } + } + } + + /* Create the hardware display list */ + + ret = ft80x_dl_start(fd, buffer, true); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_start failed: %d\n", ret); + return ret; + } + + cmds.a.clearrgb.cmd = FT80X_CLEAR_COLOR_RGB(64, 64, 64); + cmds.a.clear.cmd = FT80X_CLEAR(1 ,1, 1); + cmds.a.colorrgb.cmd = FT80X_COLOR_RGB(0xff, 0xff, 0xff); + + /* Copy the commands into the display list */ + + ret = ft80x_dl_data(fd, buffer, &cmds.a, sizeof(cmds.a)); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret); + return ret; + } + + /* Draw text entered by user */ + /* Make sure the array is a NUL terminated string */ + + text[textndx] = ch; + text[textndx + 1] = '\0'; + + cmds.b.tagmask.cmd = FT80X_TAG_MASK(0); + + cmds.b.text.cmd = FT80X_CMD_TEXT; /* Text */ + cmds.b.text.x = FT80X_DISPLAY_WIDTH / 2; + cmds.b.text.y = 40; + cmds.b.text.font = fontid; + cmds.b.text.options = FT80X_OPT_CENTER; + + ret = ft80x_dl_data(fd, buffer, &cmds.b, sizeof(cmds.b)); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret); + return ret; + } + + ret = ft80x_dl_string(fd, buffer, text); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_string failed: %d\n", ret); + return ret; + } + + cmds.c.tagmask.cmd = FT80X_TAG_MASK(1); + + /* Construct a simple keyboard - note that the tags associated with + * the keys are the character values given in the arguments. + */ + + yoffset = 80 + 10; + + cmds.c.gradcolor.cmd = FT80X_CMD_GRADCOLOR; /* Gradient color */ + cmds.c.gradcolor.c = 0x00ffff; + + cmds.c.keys.cmd = FT80X_CMD_KEYS; /* Keys */ + cmds.c.keys.x = ydist; + cmds.c.keys.y = yoffset; + cmds.c.keys.w = 10 * width; + cmds.c.keys.h = height; + cmds.c.keys.font = fontid; + cmds.c.keys.options = (FT80X_OPT_CENTER | currtag); + + ret = ft80x_dl_data(fd, buffer, &cmds.c, sizeof(cmds.c)); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret); + return ret; + } + + ret = ft80x_dl_string(fd, buffer, "qwertyuiop"); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_string failed: %d\n", ret); + return ret; + } + + yoffset += height + ydist; + + cmds.d.gradcolor.cmd = FT80X_CMD_GRADCOLOR; /* Gradient color */ + cmds.d.gradcolor.c = 0x00ffff; + + cmds.d.keys.cmd = FT80X_CMD_KEYS; /* Keys */ + cmds.d.keys.x = ydist; + cmds.d.keys.y = yoffset; + cmds.d.keys.w = 10 * width; + cmds.d.keys.h = height; + cmds.d.keys.font = fontid; + cmds.d.keys.options = (FT80X_OPT_CENTER | currtag); + + ret = ft80x_dl_data(fd, buffer, &cmds.d, sizeof(cmds.d)); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret); + return ret; + } + + ret = ft80x_dl_string(fd, buffer, "asdfghijkl"); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_string failed: %d\n", ret); + return ret; + } + + yoffset += height + ydist; + cmds.d.gradcolor.c = 0xffff00; + cmds.d.keys.y = yoffset; + + ret = ft80x_dl_data(fd, buffer, &cmds.d, sizeof(cmds.d)); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret); + return ret; + } + + ret = ft80x_dl_string(fd, buffer, "zxcvbnm"); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_string failed: %d\n", ret); + return ret; + } + + yoffset += height + ydist; + + cmds.e.tag.cmd = FT80X_TAG(' '); + + cmds.e.button.cmd = FT80X_CMD_BUTTON; + cmds.e.button.x = ydist; + cmds.e.button.y = yoffset; + cmds.e.button.w = 10 *width; + cmds.e.button.h = height; + cmds.e.button.font = fontid; + + if (currtag == ' ') + { + cmds.e.button.options = (FT80X_OPT_CENTER | FT80X_OPT_FLAT); + } + else + { + cmds.e.button.options = FT80X_OPT_CENTER; + } + + ret = ft80x_dl_data(fd, buffer, &cmds.e, sizeof(cmds.e)); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret); + return ret; + } + + ret = ft80x_dl_string(fd, buffer, " "); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_string failed: %d\n", ret); + return ret; + } + + yoffset = 80 + 10; + + cmds.keys.cmd = FT80X_CMD_KEYS; /* Keys */ + cmds.keys.x = 11 * width; + cmds.keys.y = yoffset; + cmds.keys.w = 3 * width; + cmds.keys.h = height; + cmds.keys.font = fontid; + cmds.keys.options = (0 | currtag); + + ret = ft80x_dl_data(fd, buffer, &cmds.keys, sizeof(cmds.keys)); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret); + return ret; + } + + ret = ft80x_dl_string(fd, buffer, "789"); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_string failed: %d\n", ret); + return ret; + } + + yoffset += height + ydist; + cmds.keys.y = yoffset; + + ret = ft80x_dl_data(fd, buffer, &cmds.keys, sizeof(cmds.keys)); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret); + return ret; + } + + ret = ft80x_dl_string(fd, buffer, "456"); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_string failed: %d\n", ret); + return ret; + } + + yoffset += height + ydist; + cmds.keys.y = yoffset; + + ret = ft80x_dl_data(fd, buffer, &cmds.keys, sizeof(cmds.keys)); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret); + return ret; + } + + ret = ft80x_dl_string(fd, buffer, "123"); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_string failed: %d\n", ret); + return ret; + } + + yoffset += height + ydist; + + cmds.f.colora.cmd = FT80X_COLOR_A(255); + + cmds.f.keys.cmd = FT80X_CMD_KEYS; /* Keys */ + cmds.f.keys.x = 11 * width; + cmds.f.keys.y = yoffset; + cmds.f.keys.w = 3 * width; + cmds.f.keys.h = height; + cmds.f.keys.font = fontid; + cmds.f.keys.options = (9 | currtag); + + ret = ft80x_dl_data(fd, buffer, &cmds.f, sizeof(cmds.f)); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret); + return ret; + } + + ret = ft80x_dl_string(fd, buffer, "0."); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_string failed: %d\n", ret); + return ret; + } + + /* Terminate the display list */ + + ret = ft80x_dl_end(fd, buffer); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_dl_end failed: %d\n", ret); + return ret; + } + + usleep(10 * 1000); + prevtag = currtag; + } + + return OK; +} diff --git a/examples/ft80x/ft80x_main.c b/examples/ft80x/ft80x_main.c index 8ead4a8c2..9e0d31252 100644 --- a/examples/ft80x/ft80x_main.c +++ b/examples/ft80x/ft80x_main.c @@ -126,6 +126,7 @@ static const struct ft80x_exampleinfo_s g_primitives[] = * (To be provided) CMD_SNAPSHOT Take a snapshot of the current screen * ft80x_coproc_logo CMD_LOGO Play device log animation + * ft80x_coproc_interactive CMD_KEYS Interactive keys */ static const struct ft80x_exampleinfo_s g_coproc[] = @@ -145,7 +146,8 @@ static const struct ft80x_exampleinfo_s g_coproc[] = #ifndef CONFIG_EXAMPLES_FT80X_EXCLUDE_BITMAPS { "Screen Saver", ft80x_coproc_screensaver }, #endif - { "Logo", ft80x_coproc_logo } + { "Logo", ft80x_coproc_logo }, + { "Interactive", ft80x_coproc_interactive }, }; #define NCOPROC (sizeof(g_primitives) / sizeof(ft80x_example_t)) diff --git a/graphics/ft80x/Kconfig b/graphics/ft80x/Kconfig index ad4bd7d41..3e64b47c6 100644 --- a/graphics/ft80x/Kconfig +++ b/graphics/ft80x/Kconfig @@ -28,6 +28,14 @@ config GRAPHICS_FT80X_CMDEMPTY_SIGNAL This is the signal that will be received when the co-processor CMD FIFO becomes empty. +config GRAPHICS_FT80X_TAG_SIGNAL + int "TAG event signal" + default 18 + range 1 31 + ---help--- + This is the signal that will be received when the co-processor the + detected touch tag changes. + config GRAPHICS_FT80X_DEBUG_ERROR bool "Enable error output" default y diff --git a/graphics/ft80x/ft80x.h b/graphics/ft80x/ft80x.h index 807ae0590..fc77effa3 100644 --- a/graphics/ft80x/ft80x.h +++ b/graphics/ft80x/ft80x.h @@ -137,7 +137,7 @@ struct ft80x_dlbuffer_s; /* Forward reference3 */ int ft80x_getreg8(int fd, uint32_t addr, FAR uint8_t *value); int ft80x_getreg16(int fd, uint32_t addr, FAR uint16_t *value); -int ft80x_getreg32(int fd, uint32_t addr, FAR uint16_t *value); +int ft80x_getreg32(int fd, uint32_t addr, FAR uint32_t *value); /**************************************************************************** * Name: ft80x_getregs diff --git a/graphics/ft80x/ft80x_regs.c b/graphics/ft80x/ft80x_regs.c index e9566ecfc..802404e36 100644 --- a/graphics/ft80x/ft80x_regs.c +++ b/graphics/ft80x/ft80x_regs.c @@ -135,7 +135,7 @@ int ft80x_getreg16(int fd, uint32_t addr, FAR uint16_t *value) return ret; } -int ft80x_getreg32(int fd, uint32_t addr, FAR uint16_t *value) +int ft80x_getreg32(int fd, uint32_t addr, FAR uint32_t *value) { struct ft80x_register_s reg; int ret; diff --git a/graphics/ft80x/ft80x_touch.c b/graphics/ft80x/ft80x_touch.c index b457d96b2..56e383916 100644 --- a/graphics/ft80x/ft80x_touch.c +++ b/graphics/ft80x/ft80x_touch.c @@ -41,6 +41,7 @@ #include #include +#include #include #include @@ -82,4 +83,308 @@ int ft80x_touch_gettransform(int fd, FAR uint32_t matrix[6]) } return ret; -} \ No newline at end of file +} + +/**************************************************************************** + * Name: ft80x_touch_tag + * + * Description: + * Read the current touch tag. The touch tag is an 8-bit value + * identifying the specific graphics object on the screen that is being + * touched. The value zero indicates that there is no graphic object being + * touched. + * + * Only a single touch can be queried. For the FT801 in "extended", + * multi-touch mode, this value indicates only the tag associated with + * touch 0. + * + * Input Parameters: + * fd - The file descriptor of the FT80x device. Opened by the caller + * with write access. + * + * Returned Value: + * A value of 1-255 is returned if a graphics object is touched. Zero is + * returned if no graphics object is touched. A negated errno value on failure. + * + ****************************************************************************/ + +int ft80x_touch_tag(int fd) +{ + uint8_t tag; + int ret; + +#if defined(CONFIG_LCD_FT800) + /* Read REG_TOUCH_TAG */ + + ret = ft80x_getreg8(fd, FT80X_REG_TOUCH_TAG, &tag); + +#elif defined(CONFIG_LCD_FT801) + /* Read REG_CTOUCH_TAG */ + + ret = ft80x_getreg8(fd, FT80X_REG_CTOUCH_TAG, &tag); + +#endif + + if (ret < 0) + { + ft80x_err("ERROR: ft80x_getreg8 failed: %d\n", ret); + return ret; + } + + return (int)tag; +} + +/**************************************************************************** + * Name: ft80x_touch_waittag + * + * Description: + * Wait until there is a change in the touch tag. + * + * Input Parameters: + * fd - The file descriptor of the FT80x device. Opened by the caller + * with write access. + * oldtag - The previous tag value. This function will return when the + * current touch tag differs from this value. + * + * Returned Value: + * A value of 1-255 is returned if a graphics object is touched. Zero is + * returned if no graphics object is touched. A negated errno value on failure. + * + ****************************************************************************/ + +int ft80x_touch_waittag(int fd, uint8_t oldtag) +{ + struct ft80x_notify_s notify; + struct timespec timeout; + sigset_t set; + uint8_t tag; + int ret; + + /* Block the signal so that it will pend if received asynchronously */ + + (void)sigemptyset(&set); + (void)sigaddset(&set, CONFIG_GRAPHICS_FT80X_TAG_SIGNAL); + + ret = pthread_sigmask(SIG_BLOCK, &set, NULL); + if (ret < 0) + { + ret = -errno; + ft80x_err("ERROR: pthread_sigmask for signal %d failed: %d\n", + CONFIG_GRAPHICS_FT80X_TAG_SIGNAL, ret); + return ret; + } + + notify.signo = CONFIG_GRAPHICS_FT80X_TAG_SIGNAL; + notify.pid = getpid(); + notify.event = FT80X_NOTIFY_TAG; + notify.enable = false; + + for (; ; ) + { + /* Read the current touch tag. */ + + ret = ft80x_touch_tag(fd); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_touch_tag failed: %d\n", ret); + return ret; + } + + /* Check if the touch tag has already changed */ + + tag = (uint8_t)(ret & 0xff); + ft80x_info("oldtag=%u tag=%u\n", oldtag, tag); + + if (tag == oldtag) + { + /* The tag has changed... return success */ + + ret = OK; + break; + } + + /* Set up to receive a notification when the touch tag changes. + * NOTE that there is a race condition here between the preceding test + * and the time when the event is registered. We catch this with a + * timeout below. + */ + + notify.enable = true; + ret = ioctl(fd, FT80X_IOC_EVENTNOTIFY, + (unsigned long)((uintptr_t)¬ify)); + if (ret < 0) + { + ret = -errno; + ft80x_err("ERROR: ioctl(FT80X_IOC_EVENTNOTIFY) failed: %d\n", ret); + break; + } + + /* Now wait for the signal event (or a timeout) */ + + timeout.tv_sec = 0; + timeout.tv_nsec = 400 * 1000 * 1000; + + ret = sigtimedwait(&set, NULL, &timeout); + + /* Make sure that the event notification is again disabled */ + + notify.enable = false; + (void)ioctl(fd, FT80X_IOC_EVENTNOTIFY, + (unsigned long)((uintptr_t)¬ify)); + + /* Check if the signal was received correctly or if the timeout occurred. */ + + if (ret < 0) + { + int errcode = errno; + if (errcode != EAGAIN) + { + ft80x_err("ERROR: ioctl(FT80X_IOC_EVENTNOTIFY) failed: %d\n", + errcode); + ret = -errcode; + break; + } + } + } + + (void)pthread_sigmask(SIG_UNBLOCK, &set, NULL); + return tag; +} + +/**************************************************************************** + * Name: ft80x_touch_info + * + * Description: + * Return the current touch tag and touch position information. + * + * For the FT801 in "extended", multi-touch mode, the tag value indicates + * only the tag associated with touch 0. + * + * Touch positions of -32768 indicate that no touch is detected. + * + * Input Parameters: + * fd - The file descriptor of the FT80x device. Opened by the caller + * with write access. + * info - Location in which to return the touch information + * + * Returned Value: + * A value of 1-255 is returned if a graphics object is touched. Zero is + * returned if no graphics object is touched. A negated errno value on failure. + * + ****************************************************************************/ + +int ft80x_touch_info(int fd, FAR struct ft80x_touchinfo_s *info) +{ + int ret; + + DEBUGASSERT(info != NULL); + +#if defined(CONFIG_LCD_FT800) + /* Read REG_TOUCH_TAG */ + + ret = ft80x_getreg8(fd, FT80X_REG_TOUCH_TAG, &info->tag); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_getreg8 failed: %d\n", ret); + return ret; + } + + /* Read the FT80X_REG_TOUCH_TAG_XY register */ + + ret = ft80x_getreg32(fd, FT80X_REG_TOUCH_TAG_XY, &info->tagpos.xy); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_getreg32 failed: %d\n", ret); + return ret; + } + + /* Read the FT80X_REG_TOUCH_RZ register */ + + ret = ft80x_getreg16(fd, FT80X_REG_TOUCH_RZ, + (FAR uint16_t *)&info->pressure); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_getreg16 failed: %d\n", ret); + return ret; + } + + /* Read the FT80X_REG_TOUCH_SCREEN_XY register */ + + ret = ft80x_getreg32(fd, FT80X_REG_TOUCH_SCREEN_XY, &info->pos.xy); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_getreg32 failed: %d\n", ret); + return ret; + } + +#elif defined(CONFIG_LCD_FT801) + /* Read REG_CTOUCH_TAG */ + + ret = ft80x_getreg8(fd, FT80X_REG_CTOUCH_TAG, &tag); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_getreg8 failed: %d\n", ret); + return ret; + } + + /* Read the FT80X_REG_CTOUCH_TAG_XY register */ + + ret = ft80x_getreg32(fd, FT80X_REG_CTOUCH_TAG_XY, &info->tagpos.xy); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_getreg32 failed: %d\n", ret); + return ret; + } + +#ifndef CONFIG_LCD_FT801_MULTITOUCH + /* Read the FT80X_REG_CTOUCH_TOUCH0_XY register */ + + ret = ft80x_getreg32(fd, FT80X_REG_CTOUCH_TOUCH0_XY, &info->pos.xy); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_getreg32 failed: %d\n", ret); + return ret; + } + +#else + /* Read the FT80X_REG_CTOUCH_TOUCH0_XY register */ + + ret = ft80x_getreg32(fd, FT80X_REG_CTOUCH_TOUCH0_XY, &info->pos[0].xy); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_getreg32 failed: %d\n", ret); + return ret; + } + + /* Read the FT80X_REG_CTOUCH_TOUCH1_XY register */ + + ret = ft80x_getreg32(fd, FT80X_REG_CTOUCH_TOUCH1_XY, &info->pos[1].xy); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_getreg32 failed: %d\n", ret); + return ret; + } + + /* Read the FT80X_REG_CTOUCH_TOUCH2_XY register */ + + ret = ft80x_getreg32(fd, FT80X_REG_CTOUCH_TOUCH2_XY, &info->pos[2].xy); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_getreg32 failed: %d\n", ret); + return ret; + } + + /* Read the FT80X_REG_CTOUCH_TOUCH3_XY register */ + + ret = ft80x_getreg32(fd, FT80X_REG_CTOUCH_TOUCH3_XY, &info->pos[3].xy); + if (ret < 0) + { + ft80x_err("ERROR: ft80x_getreg32 failed: %d\n", ret); + return ret; + } + +#endif /* CONFIG_LCD_FT801_MULTITOUCH */ +#endif /* CONFIG_LCD_FT800/1 */ + + return OK; +} diff --git a/include/graphics/ft80x.h b/include/graphics/ft80x.h index 91cb7152c..d8f463e95 100644 --- a/include/graphics/ft80x.h +++ b/include/graphics/ft80x.h @@ -70,6 +70,32 @@ struct ft80x_dlbuffer_s uint32_t dlbuffer[FT80X_DL_BUFWORDS]; }; +/* Describes touch sample */ + +union ft80x_touchpos_u +{ + uint32_t xy; /* To force 32-bit alignment */ + struct /* Little-endian */ + { + int16_t x; /* Touch X position (-32768 if no touch) */ + int16_t y; /* Touch Y position (-32768 if no touch) */ + } u; +}; + +struct ft80x_touchinfo_s +{ + uint8_t tag; /* Touch 0 tag */ +#if defined(CONFIG_LCD_FT800) + int16_t pressure; /* Touch pressure (32767 if not touched) */ +#endif + union ft80x_touchpos_u tagpos; /* Position associated with tag */ +#if defined(CONFIG_LCD_FT800) || !defined(CONFIG_LCD_FT801_MULTITOUCH) + union ft80x_touchpos_u pos; /* Current touch position */ +#else + union ft80x_touchpos_u pos[4]; /* Current touch position for up to 4 touches */ +#endif +}; + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -326,6 +352,75 @@ int ft80x_ramg_write(int fd, unsigned int offset, FAR const void *data, int ft80x_touch_gettransform(int fd, FAR uint32_t matrix[6]); +/**************************************************************************** + * Name: ft80x_touch_tag + * + * Description: + * Read the current touch tag. The touch tag is an 8-bit value + * identifying the specific graphics object on the screen that is being + * touched. The value zero indicates that there is no graphic object being + * touched. + * + * Only a single touch can be queried. For the FT801 in "extended", + * multi-touch mode, this value indicates only the tag associated with + * touch 0. + * + * Input Parameters: + * fd - The file descriptor of the FT80x device. Opened by the caller + * with write access. + * + * Returned Value: + * A value of 1-255 is returned if a graphics object is touched. Zero is + * returned if no graphics object is touched. A negated errno value on failure. + * + ****************************************************************************/ + +int ft80x_touch_tag(int fd); + +/**************************************************************************** + * Name: ft80x_touch_waittag + * + * Description: + * Wait until there is a change in the touch tag. + * + * Input Parameters: + * fd - The file descriptor of the FT80x device. Opened by the caller + * with write access. + * oldtag - The previous tag value. This function will return when the + * current touch tag differs from this value. + * + * Returned Value: + * A value of 1-255 is returned if a graphics object is touched. Zero is + * returned if no graphics object is touched. A negated errno value on failure. + * + ****************************************************************************/ + +int ft80x_touch_waittag(int fd, uint8_t oldtag); + +/**************************************************************************** + * Name: ft80x_touch_info + * + * Description: + * Return the current touch tag and touch position information. + * + * For the FT801 in "extended", multi-touch mode, the tag value indicates + * only the tag associated with touch 0. + * + * Touch positions of -32768 indicate that no touch is detected. + * + * Input Parameters: + * fd - The file descriptor of the FT80x device. Opened by the caller + * with write access. + * info - Location in which to return the touch information + * + * Returned Value: + * A value of 1-255 is returned if a graphics object is touched. Zero is + * returned if no graphics object is touched. A negated errno value on failure. + * + ****************************************************************************/ + +int ft80x_touch_info(int fd, FAR struct ft80x_touchinfo_s *info); + /**************************************************************************** * Name: ft80x_backlight_set *