9
0
Fork 0

Add a timeout to the STMPE11 touchscreen driver to catch missing pen up events

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4758 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2012-05-21 17:36:26 +00:00
parent a8cacc56ba
commit 32fc3563e4
6 changed files with 141 additions and 21 deletions

View File

@ -8,6 +8,8 @@ NxWM
(3) NxConsole issues
(1) Platform specific issues
See also the NuttX TODO list graphics/ section for related issues.
o General NxWM Issues
-------------------
@ -85,7 +87,7 @@ o NxConsole Issues
NxConsoles get their input from /dev/console which is the serial
port. The necessary change is to create an NX input device for
/dev/console that will get its input from NX.
Status: Closed with was fixed with the last check of 5/20/2012 (about
Status: Closed with was fixed with the check-in of 5/20/2012 (about
SVN version 4755). The fixed version is available in SVN but
won't be in a released version until NxWidgets-1.2 is released.
Priority: Medium high, basically prohibits the use of multiple NSH windows.
@ -96,7 +98,7 @@ o NxConsole Issues
you close one of the NxConsoles, then the others no longer
received input (or no long generate output -- that cannot be
distinguished).
Status: Closed with was fixed with the last check of 5/20/2012 (about
Status: Closed with was fixed with the check-in of 5/20/2012 (about
SVN version 4755). The fixed version is available in SVN but
won't be in a released version until NxWidgets-1.2 is released.
Priority: Medium high, basically prohibits the use of multiple NSH windows.
@ -120,4 +122,8 @@ o Platform specific issues
is that you touch an icon, it is highlighted but when you release
the touch nothing happens. The icon stays highlighted. Touching
the icon again usually works around this problem.
Status: Open
Status: Closed with was fixed with the check-in of 5/21/2012 (about
SVN version 4758). The was change made to NuttX, not NxWidgets.
The fixed version is available in SVN but won't be in a released
version until NuttX-6.198 is released.
Priorioty: Low, but really annoying.

View File

@ -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.

View File

@ -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/)
^^^^^^^^^^^^^^^^^^^^^^

View File

@ -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

View File

@ -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 */

View File

@ -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;
@ -734,6 +734,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
*
@ -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);
}