drivers/ft5x06.c: Add additional configuration options: Optimize if multi-touch capability is not used. Add options to swap X/Y and thresholding to reduce the rate of false alarm reports (with no motion).
This commit is contained in:
parent
a0004173d4
commit
4a5e18a6db
|
@ -67,10 +67,7 @@ STATUS
|
|||
2017-12-18: Added an option to the FT5x06 driver to support a timer-
|
||||
based poll instead of interrupts. This is very inefficient in that it
|
||||
will introduce delays in touchscreen response and will consume more CPU
|
||||
bandwidth.
|
||||
|
||||
The FT5x06 driver is not, however, functional. It is generating hard
|
||||
faults.
|
||||
bandwidth. The driver appears to be functional.
|
||||
|
||||
Configurations
|
||||
==============
|
||||
|
@ -178,8 +175,23 @@ Configurations
|
|||
Touch panel I2C address: 0x38
|
||||
|
||||
4. The touchscreen test program at apps/examples/touchscreen is also
|
||||
included in this configuration. As of this writing, touchscreen
|
||||
is not yet functional, however.
|
||||
included in this configuration.
|
||||
|
||||
nsh> tc 5
|
||||
tc_main: nsamples: 2
|
||||
tc_main: Initializing external touchscreen device
|
||||
tc_main: Opening /dev/input0
|
||||
Sample :
|
||||
npoints : 1
|
||||
Point 1 :
|
||||
id : 0
|
||||
flags : 1a
|
||||
x : 230
|
||||
y : 84
|
||||
h : 0
|
||||
w : 0
|
||||
pressure : 0
|
||||
etc.
|
||||
|
||||
nsh:
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ CONFIG_FAT_LFN=y
|
|||
CONFIG_FS_FAT=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FT5X06_POLLMODE=y
|
||||
CONFIG_FT5X06_SINGLEPOINT=y
|
||||
CONFIG_GRAPHICS_PDCURSES=y
|
||||
CONFIG_I2CTOOL_MAXBUS=9
|
||||
CONFIG_INPUT_FT5X06=y
|
||||
|
|
|
@ -78,7 +78,7 @@ config INPUT_FT5336
|
|||
if INPUT_FT5X06
|
||||
|
||||
config FT5X06_POLLMODE
|
||||
bool " FT5336/FT5x06 polled mode"
|
||||
bool "Polled mode"
|
||||
default n
|
||||
---help---
|
||||
Run the FT5x06 in a non-interrupt driven polled mode. Events will
|
||||
|
@ -88,6 +88,40 @@ config FT5X06_POLLMODE
|
|||
in detecting touch related events and (2) it will consume a
|
||||
significant amount of CPU time to perform the polling.
|
||||
|
||||
config FT5X06_SWAPXY
|
||||
bool "Swap X/Y"
|
||||
default n
|
||||
---help---
|
||||
Reverse the meaning of X and Y to handle different LCD orientations.
|
||||
|
||||
config FT5X06_SINGLEPOINT
|
||||
bool "Single point"
|
||||
default n
|
||||
---help---
|
||||
Do no report multi-touch events
|
||||
|
||||
if FT5X06_SINGLEPOINT
|
||||
|
||||
config FT5X06_THRESHX
|
||||
int "X threshold"
|
||||
default 12
|
||||
---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
|
||||
320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12
|
||||
|
||||
config FT5X06_THRESHY
|
||||
int "Y threshold"
|
||||
default 12
|
||||
---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
|
||||
320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12
|
||||
|
||||
endif # FT5X06_SINGLEPOINT
|
||||
|
||||
config FT5X06_NPOLLWAITERS
|
||||
int "Number FT5336/FT5x06 poll waiters"
|
||||
default 4
|
||||
|
|
|
@ -120,6 +120,12 @@ struct ft5x06_dev_s
|
|||
* FT5x06 data */
|
||||
volatile bool valid; /* True: New, valid touch data in
|
||||
* touchbuf[] */
|
||||
#ifdef CONFIG_FT5X06_SINGLEPOINT
|
||||
uint8_t lastid; /* Last reported touch id */
|
||||
uint8_t lastevent; /* Last reported event */
|
||||
int16_t lastx; /* Last reported X position */
|
||||
int16_t lasty; /* Last reported Y position */
|
||||
#endif
|
||||
sem_t devsem; /* Manages exclusive access to this
|
||||
* structure */
|
||||
sem_t waitsem; /* Used to wait for the
|
||||
|
@ -299,7 +305,12 @@ static void ft5x06_data_worker(FAR void *arg)
|
|||
msg[0].buffer = ®addr; /* Send one byte of data (no STOP) */
|
||||
msg[0].length = 1;
|
||||
|
||||
/* Set up the data read operation */
|
||||
/* Set up the data read operation.
|
||||
*
|
||||
* REVISIT: If CONFIG_FT5X06_SINGLEPOINT is selected, we we not just
|
||||
* set the length for one sample? Or is there some reason why we have to
|
||||
* read all of the points?
|
||||
*/
|
||||
|
||||
msg[1].frequency = priv->frequency; /* I2C frequency */
|
||||
msg[1].addr = config->address; /* 7-bit address */
|
||||
|
@ -427,6 +438,113 @@ static int ft5x06_data_interrupt(int irq, FAR void *context, FAR void *arg)
|
|||
* Name: ft5x06_sample
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_FT5X06_SINGLEPOINT
|
||||
static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
|
||||
size_t len)
|
||||
{
|
||||
FAR struct ft5x06_touch_data_s *raw;
|
||||
FAR struct ft5x06_touch_point_s *touch;
|
||||
FAR struct touch_sample_s *sample;
|
||||
FAR struct touch_point_s *point;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
uint8_t event;
|
||||
uint8_t id;
|
||||
|
||||
if (!priv->valid)
|
||||
{
|
||||
return 0; /* Nothing to read */
|
||||
}
|
||||
|
||||
/* Raw data pointers (source) */
|
||||
|
||||
raw = (FAR struct ft5x06_touch_data_s *)priv->touchbuf;
|
||||
|
||||
if (raw->tdstatus != 1)
|
||||
{
|
||||
priv->valid = false;
|
||||
return 0; /* No touches read. */
|
||||
}
|
||||
|
||||
/* Get the reported X and Y positions */
|
||||
|
||||
touch = raw->touch;
|
||||
|
||||
#ifdef CONFIG_FT5X06_SWAPXY
|
||||
y = TOUCH_POINT_GET_X(touch[0]);
|
||||
x = TOUCH_POINT_GET_Y(touch[0]);
|
||||
#else
|
||||
x = TOUCH_POINT_GET_X(touch[0]);
|
||||
y = TOUCH_POINT_GET_Y(touch[0]);
|
||||
#endif
|
||||
|
||||
/* Get the touch point ID and event */
|
||||
|
||||
event = TOUCH_POINT_GET_EVENT(touch[0]);
|
||||
id = TOUCH_POINT_GET_ID(touch[0]);
|
||||
|
||||
if (id == priv->lastid && event == priv->lastevent)
|
||||
{
|
||||
int16_t deltax;
|
||||
int16_t deltay;
|
||||
|
||||
/* Same ID and event.. Compare the change in position from the last
|
||||
* report.
|
||||
*/
|
||||
|
||||
deltax = (x - priv->lastx);
|
||||
if (deltax < 0)
|
||||
{
|
||||
deltax = -deltax;
|
||||
}
|
||||
|
||||
if (deltax < CONFIG_FT5X06_THRESHX)
|
||||
{
|
||||
/* There as been no significant change in X, try Y */
|
||||
|
||||
deltay = (y - priv->lasty);
|
||||
if (deltay < 0)
|
||||
{
|
||||
deltay = -deltay;
|
||||
}
|
||||
|
||||
if (deltax < CONFIG_FT5X06_THRESHX)
|
||||
{
|
||||
/* Ignore... no significant change in Y either */
|
||||
|
||||
priv->valid = false;
|
||||
return 0; /* No new touches read. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
priv->lastid = id;
|
||||
priv->lastevent = event;
|
||||
priv->lastx = x;
|
||||
priv->lasty = y;
|
||||
|
||||
/* User data buffer points (sink) */
|
||||
|
||||
/* Return the number of touches read */
|
||||
|
||||
sample = (FAR struct touch_sample_s *)buffer;
|
||||
sample->npoints = 1;
|
||||
|
||||
/* Decode and return the single touch point */
|
||||
|
||||
point = sample->point;
|
||||
point[0].id = id;
|
||||
point[0].flags = g_event_map[event];
|
||||
point[0].x = x;
|
||||
point[0].y = y;
|
||||
point[0].h = 0;
|
||||
point[0].w = 0;
|
||||
point[0].pressure = 0;
|
||||
|
||||
priv->valid = false;
|
||||
return SIZEOF_TOUCH_SAMPLE_S(1);
|
||||
}
|
||||
#else
|
||||
static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
|
||||
size_t len)
|
||||
{
|
||||
|
@ -434,8 +552,8 @@ static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
|
|||
FAR struct ft5x06_touch_point_s *touch;
|
||||
FAR struct touch_sample_s *sample;
|
||||
FAR struct touch_point_s *point;
|
||||
unsigned int ntouches;
|
||||
unsigned int maxtouches;
|
||||
unsigned int ntouches;
|
||||
int i;
|
||||
|
||||
maxtouches = (len - sizeof(int)) / sizeof(struct touch_point_s);
|
||||
|
@ -454,6 +572,8 @@ static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
|
|||
/* Decode number of touches */
|
||||
|
||||
ntouches = raw->tdstatus;
|
||||
DEBUGASSERT(ntouches <= FT5x06_MAX_TOUCHES);
|
||||
|
||||
if (ntouches > maxtouches)
|
||||
{
|
||||
ntouches = maxtouches;
|
||||
|
@ -465,8 +585,6 @@ static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
|
|||
return 0; /* No touches read. */
|
||||
}
|
||||
|
||||
DEBUGASSERT(ntouches <= FT5x06_MAX_TOUCHES);
|
||||
|
||||
/* User data buffer points (sink) */
|
||||
|
||||
sample = (FAR struct touch_sample_s *)buffer;
|
||||
|
@ -478,14 +596,19 @@ static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
|
|||
|
||||
/* Decode and return the touch points */
|
||||
|
||||
for (i = 0; i < raw->tdstatus; i++)
|
||||
for (i = 0; i < ntouches; i++)
|
||||
{
|
||||
int event = TOUCH_POINT_GET_EVENT(touch[i]);
|
||||
|
||||
point[i].id = TOUCH_POINT_GET_ID(touch[i]);
|
||||
point[i].flags = g_event_map[event];
|
||||
#ifdef CONFIG_FT5X06_SWAPXY
|
||||
point[i].y = TOUCH_POINT_GET_X(touch[i]);
|
||||
point[i].x = TOUCH_POINT_GET_Y(touch[i]);
|
||||
#else
|
||||
point[i].x = TOUCH_POINT_GET_X(touch[i]);
|
||||
point[i].y = TOUCH_POINT_GET_Y(touch[i]);
|
||||
#endif
|
||||
point[i].h = 0;
|
||||
point[i].w = 0;
|
||||
point[i].pressure = 0;
|
||||
|
@ -494,6 +617,7 @@ static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
|
|||
priv->valid = false;
|
||||
return SIZEOF_TOUCH_SAMPLE_S(ntouches);
|
||||
}
|
||||
#endif /* CONFIG_FT5X06_SINGLEPOINT */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft5x06_waitsample
|
||||
|
|
Loading…
Reference in New Issue