summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-06-06 16:10:45 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-06-06 16:10:45 +0000
commit1bc2fa2af9ccdc3217d54bd4c3219797217dd946 (patch)
treeecebb8f6012b4f4b230d6de9f0a2fcdb2b28df0a
parent7b6936598c0f53b68c26ac827d2d33e89c52c2b5 (diff)
downloadnuttx-1bc2fa2af9ccdc3217d54bd4c3219797217dd946.tar.gz
nuttx-1bc2fa2af9ccdc3217d54bd4c3219797217dd946.tar.bz2
nuttx-1bc2fa2af9ccdc3217d54bd4c3219797217dd946.zip
PIC32MX7 MMB touchscreen driver update
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4806 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/ChangeLog3
-rw-r--r--nuttx/Documentation/NuttX.html11
-rw-r--r--nuttx/configs/pic32mx7mmb/src/up_touchscreen.c166
3 files changed, 135 insertions, 45 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 25f29319d..5b3063c30 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -2889,7 +2889,8 @@
* configs/pic32mx7mmb/src/up_mio283qt2.c: Add support for the MIO283QT2
LCD on the PIC32MX7 MMB board.
* configs/pic32mx7mmb/src/up_touchscreen.c: Add an ACD-based touchscreen
- driver for the PIC32MX7 MMB board.
+ driver for the PIC32MX7 MMB board. Kind of works, but needs more
+ verification and tuning.
* arch/mips/src/common/up_idle.c: Strange but important fix. For some still-
unknown reason, interrupts are left in an unhealthy state in the IDLE
when the work queue is enabled. This is partially because some interrupt
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index 2f649ac62..a467917f0 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
- <p>Last Updated: June 4, 2012</p>
+ <p>Last Updated: June 6, 2012</p>
</td>
</tr>
</table>
@@ -2281,7 +2281,14 @@
(2) Verified SPI driver,
(3) SPI-based SD Card support,
(4) USB device support (including configuration options for the USB mass storage device and the CDC/ACM serial class), and
- (4) Support for the MIO873QT2 LCD on the PIC32MX7 MMB.
+ (5) Support for the MIO873QT2 LCD on the PIC32MX7 MMB.
+ </p>
+ </p>
+ The PIC32MX7 MMB's touchscreen is connected directly to the MCU via ADC pins.
+ A touchscreen driver has been developed using the PIC32's ADC capabilities and can be enabled in the NSH configuration.
+ However, additional verification and tuning of this driver is required.
+ Further display/touchscreen verification would require C++ support (for NxWidgets and NxWM).
+ Since I there is no PIC32 C++ is the free version of the MPLAB C32 toolchain, further graphics development is stalled.
</p>
</ul>
</td>
diff --git a/nuttx/configs/pic32mx7mmb/src/up_touchscreen.c b/nuttx/configs/pic32mx7mmb/src/up_touchscreen.c
index 2cffbe93e..33d7dcbe3 100644
--- a/nuttx/configs/pic32mx7mmb/src/up_touchscreen.c
+++ b/nuttx/configs/pic32mx7mmb/src/up_touchscreen.c
@@ -74,6 +74,10 @@
#undef CONFIG_TOUCHSCREEN_REFCNT
+/* Should we try again on bad samples? */
+
+#undef CONFIG_TOUCHSCREEN_RESAMPLE
+
/* Work queue support is required */
#ifndef CONFIG_SCHED_WORKQUEUE
@@ -130,12 +134,19 @@
#define MAX_ADC (1023)
+/* A measured value has to be within this range to be considered */
+
+#define UPPER_THRESHOLD (MAX_ADC-1)
+#define LOWER_THRESHOLD (1)
+
/* Delays ***************************************************************************/
+/* All values will be increased by one system timer tick (probably 10MS). */
#define TC_PENUP_POLL_TICKS (100 / MSEC_PER_TICK) /* IDLE polling rate: 100 MSec */
-#define TC_PENDOWN_POLL_TICKS (80 / MSEC_PER_TICK) /* Active polling rate: 80 MSec */
+#define TC_PENDOWN_POLL_TICKS (60 / MSEC_PER_TICK) /* Active polling rate: 60 MSec */
#define TC_DEBOUNCE_TICKS (30 / MSEC_PER_TICK) /* Delay before re-sampling: 30 MSec */
-#define TC_SAMPLE_TICKS (80 / MSEC_PER_TICK) /* Delay for A/D conversion: 80 MSec */
+#define TC_SAMPLE_TICKS (4 / MSEC_PER_TICK) /* Delay for A/D sampling: 4 MSec */
+#define TC_RESAMPLE_TICKS TC_SAMPLE_TICKS
/************************************************************************************
* Private Types
@@ -147,6 +158,7 @@ enum tc_state_e
TC_READY = 0, /* Ready to begin next sample */
TC_YMPENDOWN, /* Allowing time for the Y- pen down sampling */
TC_DEBOUNCE, /* Allowing a debounce time for the first sample */
+ TC_RESAMPLE, /* Restart sampling on a bad measurement */
TC_YMSAMPLE, /* Allowing time for the Y- sampling */
TC_YPSAMPLE, /* Allowing time for the Y+ sampling */
TC_XPSAMPLE, /* Allowing time for the X+ sampling */
@@ -214,6 +226,7 @@ static void tc_yminus_sample(void);
static void tc_yplus_sample(void);
static void tc_xplus_sample(void);
static void tc_xminus_sample(void);
+static inline bool tc_valid_sample(uint16_t sample);
static void tc_notify(FAR struct tc_dev_s *priv);
static int tc_sample(FAR struct tc_dev_s *priv,
@@ -363,8 +376,7 @@ static void tc_yminus_sample(void)
{
/* Configure X- as an input and X+, Y+, and Y- as outputs */
- putreg32(LCD_XPLUS_BIT | LCD_YPLUS_BIT | LCD_YMINUS_BIT,
- PIC32MX_IOPORTB_TRISCLR);
+ putreg32(LCD_XPLUS_BIT | LCD_YPLUS_BIT | LCD_YMINUS_BIT, PIC32MX_IOPORTB_TRISCLR);
putreg32(LCD_XMINUS_BIT, PIC32MX_IOPORTB_TRISSET);
/* Energize the X plate: Y+ and Y- high, X+ low */
@@ -389,11 +401,10 @@ static void tc_yplus_sample(void)
{
/* Configure X+ as an input and X-, Y+, and Y- as outputs */
- putreg32(LCD_XMINUS_BIT | LCD_YPLUS_BIT | LCD_YMINUS_BIT,
- PIC32MX_IOPORTB_TRISCLR);
+ putreg32(LCD_XMINUS_BIT | LCD_YPLUS_BIT | LCD_YMINUS_BIT, PIC32MX_IOPORTB_TRISCLR);
putreg32(LCD_XPLUS_BIT, PIC32MX_IOPORTB_TRISSET);
- /* Energize the X plate: Y+ and Y- High, X- low*/
+ /* Energize the X plate: Y+ and Y- High, X- low (X+ is an input) */
putreg32(LCD_XMINUS_BIT, PIC32MX_IOPORTB_PORTCLR);
putreg32(LCD_YPLUS_BIT | LCD_YMINUS_BIT, PIC32MX_IOPORTB_PORTSET);
@@ -415,11 +426,10 @@ static void tc_xplus_sample(void)
{
/* Configure Y+ as an input and X+, X-, and Y- as outputs */
- putreg32(LCD_XPLUS_BIT | LCD_XMINUS_BIT | LCD_YMINUS_BIT,
- PIC32MX_IOPORTB_TRISCLR);
+ putreg32(LCD_XPLUS_BIT | LCD_XMINUS_BIT | LCD_YMINUS_BIT, PIC32MX_IOPORTB_TRISCLR);
putreg32(LCD_YPLUS_BIT, PIC32MX_IOPORTB_TRISSET);
- /* Energize the Y plate: X+ and X- high, Y- low*/
+ /* Energize the Y plate: X+ and X- high, Y- low (Y+ is an input) */
putreg32(LCD_YMINUS_BIT, PIC32MX_IOPORTB_PORTCLR);
putreg32(LCD_XPLUS_BIT | LCD_XMINUS_BIT, PIC32MX_IOPORTB_PORTSET);
@@ -441,11 +451,10 @@ static void tc_xminus_sample(void)
{
/* Configure Y- as an input and X+, Y+, and X- as outputs */
- putreg32(LCD_XPLUS_BIT | LCD_XMINUS_BIT | LCD_YPLUS_BIT,
- PIC32MX_IOPORTB_TRISCLR);
+ putreg32(LCD_XPLUS_BIT | LCD_XMINUS_BIT | LCD_YPLUS_BIT, PIC32MX_IOPORTB_TRISCLR);
putreg32(LCD_YMINUS_BIT, PIC32MX_IOPORTB_TRISSET);
- /* Energize the Y plate: X+ and X- high, Y+ low */
+ /* Energize the Y plate: X+ and X- high, Y+ low (Y- is an input) */
putreg32(LCD_YPLUS_BIT, PIC32MX_IOPORTB_PORTCLR);
putreg32(LCD_XPLUS_BIT | LCD_XMINUS_BIT, PIC32MX_IOPORTB_PORTSET);
@@ -456,6 +465,15 @@ static void tc_xminus_sample(void)
}
/****************************************************************************
+ * Name: tc_valid_sample
+ ****************************************************************************/
+
+static inline bool tc_valid_sample(uint16_t sample)
+{
+ return (sample > LOWER_THRESHOLD /* && sample < UPPER_THRESHOLD */);
+}
+
+/****************************************************************************
* Name: tc_notify
****************************************************************************/
@@ -655,11 +673,11 @@ static void tc_worker(FAR void *arg)
value = tc_adc_convert();
- /* A converted value of zero would mean that there is no touch
+ /* A converted value at the minimum would mean that there is no touch
* and that the sampling period is complete.
*/
- if (value == 0)
+ if (!tc_valid_sample(value))
{
priv->state = TC_PENUP;
}
@@ -677,6 +695,7 @@ static void tc_worker(FAR void *arg)
* the touchscreen.
*/
+ case TC_RESAMPLE:
case TC_DEBOUNCE:
{
/* (Re-)start Y- sampling */
@@ -700,11 +719,12 @@ static void tc_worker(FAR void *arg)
value = tc_adc_convert();
- /* A converted value of zero would mean that the there is no touch
- * and that the sampling period is complete.
+ /* A converted value at the minimum would mean that there is no touch
+ * and that the sampling period is complete. At converted value at
+ * the maximum value is probably bad too.
*/
- if (value == 0)
+ if (!tc_valid_sample(value))
{
priv->state = TC_PENUP;
}
@@ -729,20 +749,39 @@ static void tc_worker(FAR void *arg)
case TC_YPSAMPLE: /* Allowing time for the Y+ sampling */
{
- /* Read and calculate the Y+ axis position */
+ /* Read the Y+ axis position */
- value = MAX_ADC - tc_adc_convert();
- priv->newy = (value + priv->value) >> 1;
- ivdbg("Y-=%d Y+=%d Y=%d\n", priv->value, value, priv->newy);
+ value = tc_adc_convert();
- /* Start X+ sampling */
+ /* A converted value at the minimum would mean that we lost the contact
+ * before all of the conversions were completed. At converted value at
+ * the maximum value is probably bad too.
+ */
- tc_xplus_sample();
+ if (!tc_valid_sample(value))
+ {
+#ifdef CONFIG_TOUCHSCREEN_RESAMPLE
+ priv->state = TC_RESAMPLE;
+ delay = TC_RESAMPLE_TICKS;
+#else
+ priv->state = TC_PENUP;
+#endif
+ }
+ else
+ {
+ value = MAX_ADC - value;
+ priv->newy = (value + priv->value) >> 1;
+ ivdbg("Y-=%d Y+=%d[%d] Y=%d\n", priv->value, value, MAX_ADC - value, priv->newy);
+
+ /* Start X+ sampling */
- /* Allow time for the X+ sampling */
+ tc_xplus_sample();
+
+ /* Allow time for the X+ sampling */
- priv->state = TC_XPSAMPLE;
- delay = TC_SAMPLE_TICKS;
+ priv->state = TC_XPSAMPLE;
+ delay = TC_SAMPLE_TICKS;
+ }
}
break;
@@ -752,18 +791,39 @@ static void tc_worker(FAR void *arg)
case TC_XPSAMPLE:
{
- /* Convert and save the X+ sample value */
+ /* Convert the X+ sample value */
+
+ value = tc_adc_convert();
- priv->value = tc_adc_convert();
+ /* A converted value at the minimum would mean that we lost the contact
+ * before all of the conversions were completed. At converted value at
+ * the maximum value is probably bad too.
+ */
+
+ if (!tc_valid_sample(value))
+ {
+#ifdef CONFIG_TOUCHSCREEN_RESAMPLE
+ priv->state = TC_RESAMPLE;
+ delay = TC_RESAMPLE_TICKS;
+#else
+ priv->state = TC_PENUP;
+#endif
+ }
+ else
+ {
+ /* Save the X+ sample value */
+
+ priv->value = value;
- /* Start X- sampling */
+ /* Start X- sampling */
- tc_xminus_sample();
+ tc_xminus_sample();
- /* Allow time for the X- pend down sampling */
+ /* Allow time for the X- pend down sampling */
- priv->state = TC_XMSAMPLE;
- delay = TC_SAMPLE_TICKS;
+ priv->state = TC_XMSAMPLE;
+ delay = TC_SAMPLE_TICKS;
+ }
}
break;
@@ -773,15 +833,36 @@ static void tc_worker(FAR void *arg)
case TC_XMSAMPLE: /* Allowing time for the X- sampling */
{
- /* Read and calculate the X- axis position */
+ /* Read the converted X- axis position */
- value = MAX_ADC - tc_adc_convert();
- newx = (value + priv->value) >> 1;
- ivdbg("X+=%d X-=%d Y=%d\n", priv->value, value, newx);
+ value = tc_adc_convert();
- /* Samples are available */
+ /* A converted value at the minimum would mean that we lost the contact
+ * before all of the conversions were completed. At converted value at
+ * the maximum value is probably bad too.
+ */
- priv->state = TC_PENDOWN;
+ if (!tc_valid_sample(value))
+ {
+#ifdef CONFIG_TOUCHSCREEN_RESAMPLE
+ priv->state = TC_RESAMPLE;
+ delay = TC_RESAMPLE_TICKS;
+#else
+ priv->state = TC_PENUP;
+#endif
+ }
+ else
+ {
+ /* Calculate the X- axis position */
+
+ value = MAX_ADC - value;
+ newx = (value + priv->value) >> 1;
+ ivdbg("X+=%d X-=%d[%d] X=%d\n", priv->value, value, MAX_ADC - value, newx);
+
+ /* Samples are available */
+
+ priv->state = TC_PENDOWN;
+ }
}
break;
}
@@ -851,9 +932,10 @@ static void tc_worker(FAR void *arg)
ydiff = -ydiff;
}
- if (xdiff >= CONFIG_TOUCHSCREEN_THRESHX && ydiff >= CONFIG_TOUCHSCREEN_THRESHY)
+ if (xdiff >= CONFIG_TOUCHSCREEN_THRESHX ||
+ ydiff >= CONFIG_TOUCHSCREEN_THRESHY)
{
- /* There is some change above the threshole... Report the change. */
+ /* There is some change above the threshold... Report the change. */
priv->sample.x = newx;
priv->sample.y = priv->newy;