summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-05-21 17:36:26 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-05-21 17:36:26 +0000
commite633774b61f42363d4b7c66218c1e99ebc3fa6bb (patch)
tree2d2dbecb4e03dbbc056748dca54a4ee617fa18be /nuttx
parent1d1cb9be06ee80a0d3dbcc77561a7d173ff7a659 (diff)
downloadnuttx-e633774b61f42363d4b7c66218c1e99ebc3fa6bb.tar.gz
nuttx-e633774b61f42363d4b7c66218c1e99ebc3fa6bb.tar.bz2
nuttx-e633774b61f42363d4b7c66218c1e99ebc3fa6bb.zip
Add a timeout to the STMPE11 touchscreen driver to catch missing pen up events
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4758 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/ChangeLog2
-rw-r--r--nuttx/TODO18
-rw-r--r--nuttx/drivers/input/stmpe11.h10
-rw-r--r--nuttx/drivers/input/stmpe11_base.c21
-rw-r--r--nuttx/drivers/input/stmpe11_tsc.c99
5 files changed, 132 insertions, 18 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 71534b470..3705363b2 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -2796,5 +2796,7 @@
keyboard data in multi-user mode.
* graphics/nxconsole/nxcon_kdbind.c: Fixed unmatched sem_wait and sem_post.
Fix some conditional compilation that included a few too many lines of code.
+ * drivers/input/stmpe11_tsc.c and stmpe11.h: Add a timeout to catch missed
+ pen up events. Now the STM3240G-EVAL touchscreen works very smoothly.
diff --git a/nuttx/TODO b/nuttx/TODO
index 33f29d2dc..b75691420 100644
--- a/nuttx/TODO
+++ b/nuttx/TODO
@@ -17,7 +17,7 @@ nuttx/
(3) USB (drivers/usbdev, drivers/usbhost)
(8) Libraries (lib/)
(10) File system/Generic drivers (fs/, drivers/)
- (4) Graphics subystem (graphics/)
+ (5) Graphics subystem (graphics/)
(1) Pascal add-on (pcode/)
(1) Documentation (Documentation/)
(7) Build system / Toolchains
@@ -757,6 +757,8 @@ o File system / Generic drivers (fs/, drivers/)
o Graphics subystem (graphics/)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ See also the NxWidgets TODO list file for related issues.
+
Title: UNTESTED GRAPHICS APIS
Description: Testing of all APIs is not complete. See
http://nuttx.sourceforge.net/NXGraphicsSubsystem.html#testcoverage
@@ -781,7 +783,7 @@ o Graphics subystem (graphics/)
Priority: Low
Title: AUTO-RAISE DISABLED
- Descption: Auto-raise is currently disabled in NX multi-server mode. The
+ Description: Auto-raise is currently disabled in NX multi-server mode. The
reason is complex:
- Most touchscreen controls send touch data a high rates
- In multi-server mode, touch events get queued in a message
@@ -795,6 +797,18 @@ o Graphics subystem (graphics/)
Status: Open
Priority: Medium low
+ Title: IMPROVED NXCONSOLE FONT CACHING
+ Description: Now each NxConsole instance has its own private font cache
+ whose size is determined by CONFIG_NXCONSOLE_MXCHARS. If there
+ are multiple NxConsole instances using the same font, each will
+ have a separate font cache. This is inefficient and wasteful
+ of memory: Each NxConsole instance should share a common font
+ cache.
+ Status: Open
+ Priority: Medium. Not important for day-to-day testing but would be
+ a critical improvement if NxConsole were to be used in a
+ product.
+
o Pascal Add-On (pcode/)
^^^^^^^^^^^^^^^^^^^^^^
diff --git a/nuttx/drivers/input/stmpe11.h b/nuttx/drivers/input/stmpe11.h
index b637ec644..05917fc37 100644
--- a/nuttx/drivers/input/stmpe11.h
+++ b/nuttx/drivers/input/stmpe11.h
@@ -46,8 +46,10 @@
#include <nuttx/config.h>
+#include <wdog.h>
#include <semaphore.h>
+#include <nuttx/clock.h>
#include <nuttx/wqueue.h>
#include <nuttx/input/stmpe11.h>
@@ -92,6 +94,10 @@
#define STMPE11_FLAGS_ADC_INITIALIZED (1 << 2) /* 1: The ADC block has been initialized */
#define STMPE11_FLAGS_TS_INITIALIZED (1 << 3) /* 1: The TS block has been initialized */
+/* Timeout to detect missing pen up events */
+
+#define STMPE11_PENUP_TICKS ((100 + (MSEC_PER_TICK-1)) / MSEC_PER_TICK)
+
/********************************************************************************************
* Public Types
********************************************************************************************/
@@ -137,6 +143,7 @@ struct stmpe11_dev_s
uint8_t inuse; /* SMTPE11 pins in use */
uint8_t flags; /* See SMTPE11_FLAGS_* definitions */
+ struct work_s work; /* Supports the interrupt handling "bottom half" */
/* Fields that may be disabled to save size if touchscreen support is not used. */
@@ -153,7 +160,8 @@ struct stmpe11_dev_s
uint16_t threshy; /* Thresholded Y value */
sem_t waitsem; /* Used to wait for the availability of data */
- struct work_s work; /* Supports the interrupt handling "bottom half" */
+ struct work_s timeout; /* Supports tiemeout work */
+ WDOG_ID wdog; /* Timeout to detect missing pen down events */
struct stmpe11_sample_s sample; /* Last sampled touch point data */
/* The following is a list if poll structures of threads waiting for
diff --git a/nuttx/drivers/input/stmpe11_base.c b/nuttx/drivers/input/stmpe11_base.c
index 546f1d901..8e2900610 100644
--- a/nuttx/drivers/input/stmpe11_base.c
+++ b/nuttx/drivers/input/stmpe11_base.c
@@ -183,16 +183,23 @@ static int stmpe11_interrupt(int irq, FAR void *context)
config->enable(config, false);
- /* Transfer processing to the worker thread. Since STMPE11 interrupts are
- * disabled while the work is pending, no special action should be required
- * to protected the work queue.
+ /* Check if interrupt work is already queue. If it is already busy, then
+ * we already have interrupt processing in the pipeline and we need to do
+ * nothing more.
*/
- DEBUGASSERT(work_available(&priv->work));
- ret = work_queue(&priv->work, stmpe11_worker, priv, 0);
- if (ret != 0)
+ if (work_available(&priv->work))
{
- illdbg("Failed to queue work: %d\n", ret);
+ /* Yes.. Transfer processing to the worker thread. Since STMPE11
+ * interrupts are disabled while the work is pending, no special
+ * action should be required to protect the work queue.
+ */
+
+ ret = work_queue(&priv->work, stmpe11_worker, priv, 0);
+ if (ret != 0)
+ {
+ illdbg("Failed to queue work: %d\n", ret);
+ }
}
/* Clear any pending interrupts and return success */
diff --git a/nuttx/drivers/input/stmpe11_tsc.c b/nuttx/drivers/input/stmpe11_tsc.c
index ca6d92ce0..03ede7302 100644
--- a/nuttx/drivers/input/stmpe11_tsc.c
+++ b/nuttx/drivers/input/stmpe11_tsc.c
@@ -315,7 +315,7 @@ static inline int stmpe11_waitsample(FAR struct stmpe11_dev_s *priv,
* the failure now.
*/
- idbg("sem_wait failed: %d\n", errval);
+ idbg("ERROR: sem_wait failed: %d\n", errval);
DEBUGASSERT(errval == EINTR);
#endif
ret = -EINTR;
@@ -677,7 +677,7 @@ static int stmpe11_poll(FAR struct file *filep, FAR struct pollfd *fds,
if ((fds->events & POLLIN) == 0)
{
- idbg("Missing POLLIN: revents: %08x\n", fds->revents);
+ idbg("ERROR: Missing POLLIN: revents: %08x\n", fds->revents);
ret = -EDEADLK;
goto errout;
}
@@ -702,7 +702,7 @@ static int stmpe11_poll(FAR struct file *filep, FAR struct pollfd *fds,
if (i >= CONFIG_STMPE11_NPOLLWAITERS)
{
- idbg("No availabled slot found: %d\n", i);
+ idbg("ERROR: No availabled slot found: %d\n", i);
fds->priv = NULL;
ret = -EBUSY;
goto errout;
@@ -735,6 +735,64 @@ errout:
#endif
/****************************************************************************
+ * Name: stmpe11_timeoutworker
+ *
+ * Description:
+ * A timer has expired without receiving a pen up event. Check again.
+ *
+ ****************************************************************************/
+
+static void stmpe11_timeoutworker(FAR void *arg)
+{
+ FAR struct stmpe11_dev_s *priv = (FAR struct stmpe11_dev_s *)arg;
+
+ DEBUGASSERT(priv);
+
+ /* Treat the timeout just like an interrupt occurred */
+
+ stmpe11_tscworker(priv, stmpe11_getreg8(priv, STMPE11_INT_STA));
+}
+
+/****************************************************************************
+ * Name: stmpe11_timeout
+ *
+ * Description:
+ * A timer has expired without receiving a pen up event. Schedule work
+ * to check again.
+ *
+ ****************************************************************************/
+
+static void stmpe11_timeout(int argc, uint32_t arg1, ...)
+{
+ FAR struct stmpe11_dev_s *priv = (FAR struct stmpe11_dev_s *)((uintptr_t)arg1);
+ int ret;
+
+ /* Are we still stuck in the pen down state? */
+
+ if (priv->sample.contact == CONTACT_MOVE ||
+ priv->sample.contact == CONTACT_MOVE)
+ {
+ /* Yes... is the worker thread available? If not, then apparently
+ * we have work already pending?
+ */
+
+ if (work_available(&priv->timeout))
+ {
+ /* Yes.. Transfer processing to the worker thread. Since STMPE11
+ * interrupts are disabled while the work is pending, no special
+ * action should be required to protect the work queue.
+ */
+
+ ret = work_queue(&priv->timeout, stmpe11_timeoutworker, priv, 0);
+ if (ret != 0)
+ {
+ illdbg("Failed to queue work: %d\n", ret);
+ }
+ }
+ }
+}
+
+/****************************************************************************
* Name: stmpe11_tscinitialize
*
* Description:
@@ -849,7 +907,7 @@ int stmpe11_register(STMPE11_HANDLE handle, int minor)
if (ret < 0)
{
int errval = errno;
- idbg("sem_wait failed: %d\n", errval);
+ idbg("ERROR: sem_wait failed: %d\n", errval);
return -errval;
}
@@ -857,25 +915,35 @@ int stmpe11_register(STMPE11_HANDLE handle, int minor)
if ((priv->inuse & TSC_PIN_SET) != 0)
{
- idbg("TSC pins is already in-use: %02x\n", priv->inuse);
+ idbg("ERROR: TSC pins is already in-use: %02x\n", priv->inuse);
sem_post(&priv->exclsem);
return -EBUSY;
}
- /* Initialize the TS structure to their default values */
+ /* Initialize the TS structure fields to their default values */
priv->minor = minor;
priv->penchange = false;
priv->threshx = 0;
priv->threshy = 0;
+ /* Create a timer for catching missed pen up conditions */
+
+ priv->wdog = wd_create();
+ if (!priv->wdog)
+ {
+ idbg("ERROR: Failed to create a watchdog\n", errno);
+ sem_post(&priv->exclsem);
+ return -ENOSPC;
+ }
+
/* Register the character driver */
snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor);
ret = register_driver(devname, &g_stmpe11fops, 0666, priv);
if (ret < 0)
{
- idbg("Failed to register driver %s: %d\n", devname, ret);
+ idbg("ERROR: Failed to register driver %s: %d\n", devname, ret);
sem_post(&priv->exclsem);
return ret;
}
@@ -913,6 +981,10 @@ void stmpe11_tscworker(FAR struct stmpe11_dev_s *priv, uint8_t intsta)
ASSERT(priv != NULL);
+ /* Cancel the missing pen up timer */
+
+ (void)wd_cancel(priv->wdog);
+
/* Get a pointer the callbacks for convenience (and so the code is not so
* ugly).
*/
@@ -1050,9 +1122,20 @@ void stmpe11_tscworker(FAR struct stmpe11_dev_s *priv, uint8_t intsta)
stmpe11_notify(priv);
- /* Reset and clear all data in the FIFO */
+ /* If we think that the pend is still down, the start/re-start the pen up
+ * timer.
+ */
ignored:
+ if (priv->sample.contact == CONTACT_MOVE ||
+ priv->sample.contact == CONTACT_MOVE)
+ {
+ (void)wd_start(priv->wdog, STMPE11_PENUP_TICKS, stmpe11_timeout,
+ 1, (uint32_t)((uintptr_t)priv));
+ }
+
+ /* Reset and clear all data in the FIFO */
+
stmpe11_putreg8(priv, STMPE11_FIFO_STA, FIFO_STA_FIFO_RESET);
stmpe11_putreg8(priv, STMPE11_FIFO_STA, 0);
}