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-
|
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
|
based poll instead of interrupts. This is very inefficient in that it
|
||||||
will introduce delays in touchscreen response and will consume more CPU
|
will introduce delays in touchscreen response and will consume more CPU
|
||||||
bandwidth.
|
bandwidth. The driver appears to be functional.
|
||||||
|
|
||||||
The FT5x06 driver is not, however, functional. It is generating hard
|
|
||||||
faults.
|
|
||||||
|
|
||||||
Configurations
|
Configurations
|
||||||
==============
|
==============
|
||||||
|
@ -178,8 +175,23 @@ Configurations
|
||||||
Touch panel I2C address: 0x38
|
Touch panel I2C address: 0x38
|
||||||
|
|
||||||
4. The touchscreen test program at apps/examples/touchscreen is also
|
4. The touchscreen test program at apps/examples/touchscreen is also
|
||||||
included in this configuration. As of this writing, touchscreen
|
included in this configuration.
|
||||||
is not yet functional, however.
|
|
||||||
|
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:
|
nsh:
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ CONFIG_FAT_LFN=y
|
||||||
CONFIG_FS_FAT=y
|
CONFIG_FS_FAT=y
|
||||||
CONFIG_FS_PROCFS=y
|
CONFIG_FS_PROCFS=y
|
||||||
CONFIG_FT5X06_POLLMODE=y
|
CONFIG_FT5X06_POLLMODE=y
|
||||||
|
CONFIG_FT5X06_SINGLEPOINT=y
|
||||||
CONFIG_GRAPHICS_PDCURSES=y
|
CONFIG_GRAPHICS_PDCURSES=y
|
||||||
CONFIG_I2CTOOL_MAXBUS=9
|
CONFIG_I2CTOOL_MAXBUS=9
|
||||||
CONFIG_INPUT_FT5X06=y
|
CONFIG_INPUT_FT5X06=y
|
||||||
|
|
|
@ -78,7 +78,7 @@ config INPUT_FT5336
|
||||||
if INPUT_FT5X06
|
if INPUT_FT5X06
|
||||||
|
|
||||||
config FT5X06_POLLMODE
|
config FT5X06_POLLMODE
|
||||||
bool " FT5336/FT5x06 polled mode"
|
bool "Polled mode"
|
||||||
default n
|
default n
|
||||||
---help---
|
---help---
|
||||||
Run the FT5x06 in a non-interrupt driven polled mode. Events will
|
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
|
in detecting touch related events and (2) it will consume a
|
||||||
significant amount of CPU time to perform the polling.
|
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
|
config FT5X06_NPOLLWAITERS
|
||||||
int "Number FT5336/FT5x06 poll waiters"
|
int "Number FT5336/FT5x06 poll waiters"
|
||||||
default 4
|
default 4
|
||||||
|
|
|
@ -120,6 +120,12 @@ struct ft5x06_dev_s
|
||||||
* FT5x06 data */
|
* FT5x06 data */
|
||||||
volatile bool valid; /* True: New, valid touch data in
|
volatile bool valid; /* True: New, valid touch data in
|
||||||
* touchbuf[] */
|
* 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
|
sem_t devsem; /* Manages exclusive access to this
|
||||||
* structure */
|
* structure */
|
||||||
sem_t waitsem; /* Used to wait for the
|
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].buffer = ®addr; /* Send one byte of data (no STOP) */
|
||||||
msg[0].length = 1;
|
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].frequency = priv->frequency; /* I2C frequency */
|
||||||
msg[1].addr = config->address; /* 7-bit address */
|
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
|
* 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,
|
static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
|
||||||
size_t len)
|
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 ft5x06_touch_point_s *touch;
|
||||||
FAR struct touch_sample_s *sample;
|
FAR struct touch_sample_s *sample;
|
||||||
FAR struct touch_point_s *point;
|
FAR struct touch_point_s *point;
|
||||||
unsigned int ntouches;
|
|
||||||
unsigned int maxtouches;
|
unsigned int maxtouches;
|
||||||
|
unsigned int ntouches;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
maxtouches = (len - sizeof(int)) / sizeof(struct touch_point_s);
|
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 */
|
/* Decode number of touches */
|
||||||
|
|
||||||
ntouches = raw->tdstatus;
|
ntouches = raw->tdstatus;
|
||||||
|
DEBUGASSERT(ntouches <= FT5x06_MAX_TOUCHES);
|
||||||
|
|
||||||
if (ntouches > maxtouches)
|
if (ntouches > maxtouches)
|
||||||
{
|
{
|
||||||
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. */
|
return 0; /* No touches read. */
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGASSERT(ntouches <= FT5x06_MAX_TOUCHES);
|
|
||||||
|
|
||||||
/* User data buffer points (sink) */
|
/* User data buffer points (sink) */
|
||||||
|
|
||||||
sample = (FAR struct touch_sample_s *)buffer;
|
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 */
|
/* 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]);
|
int event = TOUCH_POINT_GET_EVENT(touch[i]);
|
||||||
|
|
||||||
point[i].id = TOUCH_POINT_GET_ID(touch[i]);
|
point[i].id = TOUCH_POINT_GET_ID(touch[i]);
|
||||||
point[i].flags = g_event_map[event];
|
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].x = TOUCH_POINT_GET_X(touch[i]);
|
||||||
point[i].y = TOUCH_POINT_GET_Y(touch[i]);
|
point[i].y = TOUCH_POINT_GET_Y(touch[i]);
|
||||||
|
#endif
|
||||||
point[i].h = 0;
|
point[i].h = 0;
|
||||||
point[i].w = 0;
|
point[i].w = 0;
|
||||||
point[i].pressure = 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;
|
priv->valid = false;
|
||||||
return SIZEOF_TOUCH_SAMPLE_S(ntouches);
|
return SIZEOF_TOUCH_SAMPLE_S(ntouches);
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_FT5X06_SINGLEPOINT */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ft5x06_waitsample
|
* Name: ft5x06_waitsample
|
||||||
|
|
Loading…
Reference in New Issue