From 44e6516213f0307ede53436cbf00de75271dbc75 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 12 Jul 2014 14:00:33 -0600 Subject: [PATCH] maXTouch: Add thresholding so that MOVE reports are not generated unless there is a significant change in the reported position --- drivers/input/Kconfig | 56 ++++++++++++++++++++++++---- drivers/input/mxt.c | 77 +++++++++++++++++++++++++++++++++------ include/nuttx/input/mxt.h | 20 ++++++++++ 3 files changed, 134 insertions(+), 19 deletions(-) diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 19ac438501..c45f63b3ca 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -113,8 +113,8 @@ config ADS7843E_THRESHX default 12 ---help--- New touch positions will only be reported when the X or Y data changes by these - thresholds. This trades reduces data rate for some loss in dragging accuracy. For - 12-bit values so the raw ranges are 0-4095. So for example, if your display is + thresholds. This trades reduced data rates for some loss in dragging accuracy. For + 12-bit values the raw ranges are 0-4095. So for example, if your display is 320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12 config ADS7843E_THRESHY @@ -122,8 +122,8 @@ config ADS7843E_THRESHY default 12 ---help--- New touch positions will only be reported when the X or Y data changes by these - thresholds. This trades reduces data rate for some loss in dragging accuracy. For - 12-bit values so the raw ranges are 0-4095. So for example, if your display is + thresholds. This trades reduced data rates for some loss in dragging accuracy. For + 12-bit values the raw ranges are 0-4095. So for example, if your display is 320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12 endif @@ -136,6 +136,32 @@ config INPUT_MXT if INPUT_MXT +config MXT_THRESHX + int "X threshold" + default 5 + ---help--- + New touch positions will only be reported when the X or Y data + changes by these thresholds. This trades reduced data rates for some + loss in dragging accuracy. For 12-bit values the raw ranges are + 0-4095. So for example, if your display is 800x480, then THRESHX=5 + and THRESHY=8 would correspond to a one pixel change. Default: 5 + + NOTE: This does nothing to reduce the interrupt rate. It only + reduces the rate at which touch events are reports. + +config MXT_THRESHY + int "Y threshold" + default 8 + ---help--- + New touch positions will only be reported when the X or Y data + changes by these thresholds. This trades reduced data rates for some + loss in dragging accuracy. For 12-bit values the raw ranges are + 0-4095. So for example, if your display is 800x480, then THRESHX=5 + and THRESHY=8 would correspond to a one pixel change. Default: 8 + + NOTE: This does nothing to reduce the interrupt rate. It only + reduces the rate at which touch events are reports. + config MXT_NPOLLWAITERS int "Number poll waiters" default 4 @@ -143,6 +169,20 @@ config MXT_NPOLLWAITERS ---help--- Maximum number of threads that can be waiting on poll() +config MXT_DISABLE_DEBUG_VERBOSE + bool "Disable verbose debug output" + default y + depends on DEBUG_VERBOSE && DEBUG_INPUT + ---help--- + The maXTouch tends to generate interrupts at a high rate during the + contact. If verbose debug is enabled in this driver, you may not + be able to get anything done because of the high debug output rate. + + This setting will allow you to keep verbose touchscreen debug output + in other modules, but to specifically suppress the debug out from + the MXT driver. Debug (non-verbose) errors will still be generated, + but the chit-chat level will be eliminated. + endif # INPUT_MXT config INPUT_STMPE811 @@ -223,8 +263,8 @@ config STMPE811_THRESHX ---help--- STMPE811 touchscreen data comes in a a very high rate. New touch positions will only be reported when the X or Y data changes by these thresholds. - This trades reduces data rate for some loss in dragging accuracy. The - STMPE811 is configure for 12-bit values so the raw ranges are 0-4095. So + This trades reduced data rates for some loss in dragging accuracy. The + STMPE811 is configure for 12-bit values the raw ranges are 0-4095. So for example, if your display is 320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12 @@ -235,8 +275,8 @@ config STMPE811_THRESHY ---help--- STMPE811 touchscreen data comes in a a very high rate. New touch positions will only be reported when the X or Y data changes by these thresholds. - This trades reduces data rate for some loss in dragging accuracy. The - STMPE811 is configure for 12-bit values so the raw ranges are 0-4095. So + This trades reduced data rates for some loss in dragging accuracy. The + STMPE811 is configure for 12-bit values the raw ranges are 0-4095. So for example, if your display is 320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12 diff --git a/drivers/input/mxt.c b/drivers/input/mxt.c index cf7725076f..f8937d70c7 100644 --- a/drivers/input/mxt.c +++ b/drivers/input/mxt.c @@ -39,6 +39,12 @@ #include +/* Suppress verbose debug output so that we don't swamp the system */ + +#ifdef CONFIG_MXT_DISABLE_DEBUG_VERBOSE +# undef CONFIG_DEBUG_VERBOSE +#endif + #include #include @@ -74,6 +80,12 @@ #define DEV_FORMAT "/dev/input%d" #define DEV_NAMELEN 16 +/* This is a value for the threshold that guarantees a big difference on the + * first pendown (but can't overflow). + */ + +#define INVALID_POSITION 0x1000 + /* Get a 16-bit value in little endian order (not necessarily aligned). The * source data is in little endian order. The host byte order does not * matter in this case. @@ -123,6 +135,8 @@ struct mxt_sample_s bool valid; /* True: x,y,pressure contain valid, sampled data */ uint16_t x; /* Measured X position */ uint16_t y; /* Measured Y position */ + uint16_t lastx; /* Last reported X position */ + uint16_t lasty; /* Last reported Y position */ uint8_t area; /* Contact area */ uint8_t pressure; /* Contact pressure */ }; @@ -824,6 +838,13 @@ static void mxt_touch_event(FAR struct mxt_dev_s *priv, */ sample->contact = CONTACT_LOST; + + /* Reset the last position so that we guarantee that the next position + * will pass the thresholding test. + */ + + sample->lastx = INVALID_POSITION; + sample->lasty = INVALID_POSITION; } else { @@ -847,21 +868,49 @@ static void mxt_touch_event(FAR struct mxt_dev_s *priv, sample->valid = true; /* If this is not the first touch report, then report it as a move: - * Same contact, same ID, but a potentially new position. If - * The move event has not been reported, then just overwrite the - * move. That is harmless. + * Same contact, same ID, but with a new, updated position. + * The CONTACT_REPORT state means that a contacted has been detected, + * but all contact events have been successfully reported. */ - if (sample->contact == CONTACT_REPORT || - sample->contact == CONTACT_MOVE) + if (sample->contact == CONTACT_REPORT) { - /* Not a new contact. Indicate a contact move event */ + uint16_t xdiff; + uint16_t ydiff; - sample->contact = CONTACT_MOVE; - - /* This state will be set to CONTACT_REPORT after it - * been reported. + /* Not a new contact. Check if the new measurements represent a + * non-trivial change in position. A trivial change is detected + * by comparing the change in position since the last report + * against configurable threshold values. + * + * REVISIT: Should a large change in pressure also generate a + * event? */ + + xdiff = x > sample->lastx ? (x - sample->lastx) : (sample->lastx - x); + ydiff = y > sample->lasty ? (y - sample->lasty) : (sample->lasty - y); + + /* Check the thresholds */ + + if (xdiff < CONFIG_MXT_THRESHX && ydiff < CONFIG_MXT_THRESHY) + { + /* Report a contact move event. This state will be set back + * to CONTACT_REPORT after it been reported. + */ + + sample->contact = CONTACT_MOVE; + + /* Update the last position for next threshold calculations */ + + sample->lastx = x; + sample->lasty = y; + } + else + { + /* Bail without reporting anything for this event */ + + return; + } } /* If we have seen this contact before but it has not yet been @@ -872,7 +921,8 @@ static void mxt_touch_event(FAR struct mxt_dev_s *priv, * above) and we have a new contact with a new ID. */ - else if (sample->contact != CONTACT_NEW) + else if (sample->contact != CONTACT_NEW && + sample->contact != CONTACT_MOVE) { /* First contact. Save the contact event and assign a new * ID to the contact. @@ -881,6 +931,11 @@ static void mxt_touch_event(FAR struct mxt_dev_s *priv, sample->contact = CONTACT_NEW; sample->id = priv->id++; + /* Update the last position for next threshold calculations */ + + sample->lastx = x; + sample->lasty = y; + /* This state will be set to CONTACT_REPORT after it * been reported. */ diff --git a/include/nuttx/input/mxt.h b/include/nuttx/input/mxt.h index 855e1bd029..2b4f1359f1 100644 --- a/include/nuttx/input/mxt.h +++ b/include/nuttx/input/mxt.h @@ -59,6 +59,26 @@ # define CONFIG_MXT_NPOLLWAITERS 2 #endif +/* Thresholding + * + * New touch positions will only be reported when the X or Y data + * changes by these thresholds. This trades reduced data rates for some + * loss in dragging accuracy. For 12-bit values the raw ranges are + * 0-4095. So for example, if your display is 800x480, then THRESHX=5 + * and THRESHY=8 would correspond to a one pixel change. + * + * NOTE: This does nothing to reduce the interrupt rate. It only + * reduces the rate at which touch events are reports. + */ + +#ifndef CONFIG_MXT_MXT_THRESHX +# define CONFIG_MXT_MXT_THRESHX 5 +#endif + +#ifndef CONFIG_MXT_MXT_THRESHY +# define CONFIG_MXT_MXT_THRESHY 8 +#endif + /* Buttons are not supported */ #undef CONFIG_MXT_BUTTONS