PIC32MX7 MMB touchscreen driver update
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4806 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
cb4999caa8
commit
f0a7756f43
@ -2889,7 +2889,8 @@
|
|||||||
* configs/pic32mx7mmb/src/up_mio283qt2.c: Add support for the MIO283QT2
|
* configs/pic32mx7mmb/src/up_mio283qt2.c: Add support for the MIO283QT2
|
||||||
LCD on the PIC32MX7 MMB board.
|
LCD on the PIC32MX7 MMB board.
|
||||||
* configs/pic32mx7mmb/src/up_touchscreen.c: Add an ACD-based touchscreen
|
* 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-
|
* 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
|
unknown reason, interrupts are left in an unhealthy state in the IDLE
|
||||||
when the work queue is enabled. This is partially because some interrupt
|
when the work queue is enabled. This is partially because some interrupt
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<tr align="center" bgcolor="#e4e4e4">
|
<tr align="center" bgcolor="#e4e4e4">
|
||||||
<td>
|
<td>
|
||||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -2281,7 +2281,14 @@
|
|||||||
(2) Verified SPI driver,
|
(2) Verified SPI driver,
|
||||||
(3) SPI-based SD Card support,
|
(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) 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>
|
</p>
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
|
@ -74,6 +74,10 @@
|
|||||||
|
|
||||||
#undef CONFIG_TOUCHSCREEN_REFCNT
|
#undef CONFIG_TOUCHSCREEN_REFCNT
|
||||||
|
|
||||||
|
/* Should we try again on bad samples? */
|
||||||
|
|
||||||
|
#undef CONFIG_TOUCHSCREEN_RESAMPLE
|
||||||
|
|
||||||
/* Work queue support is required */
|
/* Work queue support is required */
|
||||||
|
|
||||||
#ifndef CONFIG_SCHED_WORKQUEUE
|
#ifndef CONFIG_SCHED_WORKQUEUE
|
||||||
@ -130,12 +134,19 @@
|
|||||||
|
|
||||||
#define MAX_ADC (1023)
|
#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 ***************************************************************************/
|
/* 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_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_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
|
* Private Types
|
||||||
@ -147,6 +158,7 @@ enum tc_state_e
|
|||||||
TC_READY = 0, /* Ready to begin next sample */
|
TC_READY = 0, /* Ready to begin next sample */
|
||||||
TC_YMPENDOWN, /* Allowing time for the Y- pen down sampling */
|
TC_YMPENDOWN, /* Allowing time for the Y- pen down sampling */
|
||||||
TC_DEBOUNCE, /* Allowing a debounce time for the first sample */
|
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_YMSAMPLE, /* Allowing time for the Y- sampling */
|
||||||
TC_YPSAMPLE, /* Allowing time for the Y+ sampling */
|
TC_YPSAMPLE, /* Allowing time for the Y+ sampling */
|
||||||
TC_XPSAMPLE, /* Allowing time for the X+ 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_yplus_sample(void);
|
||||||
static void tc_xplus_sample(void);
|
static void tc_xplus_sample(void);
|
||||||
static void tc_xminus_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 void tc_notify(FAR struct tc_dev_s *priv);
|
||||||
static int tc_sample(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 */
|
/* Configure X- as an input and X+, Y+, and Y- as outputs */
|
||||||
|
|
||||||
putreg32(LCD_XPLUS_BIT | LCD_YPLUS_BIT | LCD_YMINUS_BIT,
|
putreg32(LCD_XPLUS_BIT | LCD_YPLUS_BIT | LCD_YMINUS_BIT, PIC32MX_IOPORTB_TRISCLR);
|
||||||
PIC32MX_IOPORTB_TRISCLR);
|
|
||||||
putreg32(LCD_XMINUS_BIT, PIC32MX_IOPORTB_TRISSET);
|
putreg32(LCD_XMINUS_BIT, PIC32MX_IOPORTB_TRISSET);
|
||||||
|
|
||||||
/* Energize the X plate: Y+ and Y- high, X+ low */
|
/* 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 */
|
/* Configure X+ as an input and X-, Y+, and Y- as outputs */
|
||||||
|
|
||||||
putreg32(LCD_XMINUS_BIT | LCD_YPLUS_BIT | LCD_YMINUS_BIT,
|
putreg32(LCD_XMINUS_BIT | LCD_YPLUS_BIT | LCD_YMINUS_BIT, PIC32MX_IOPORTB_TRISCLR);
|
||||||
PIC32MX_IOPORTB_TRISCLR);
|
|
||||||
putreg32(LCD_XPLUS_BIT, PIC32MX_IOPORTB_TRISSET);
|
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_XMINUS_BIT, PIC32MX_IOPORTB_PORTCLR);
|
||||||
putreg32(LCD_YPLUS_BIT | LCD_YMINUS_BIT, PIC32MX_IOPORTB_PORTSET);
|
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 */
|
/* Configure Y+ as an input and X+, X-, and Y- as outputs */
|
||||||
|
|
||||||
putreg32(LCD_XPLUS_BIT | LCD_XMINUS_BIT | LCD_YMINUS_BIT,
|
putreg32(LCD_XPLUS_BIT | LCD_XMINUS_BIT | LCD_YMINUS_BIT, PIC32MX_IOPORTB_TRISCLR);
|
||||||
PIC32MX_IOPORTB_TRISCLR);
|
|
||||||
putreg32(LCD_YPLUS_BIT, PIC32MX_IOPORTB_TRISSET);
|
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_YMINUS_BIT, PIC32MX_IOPORTB_PORTCLR);
|
||||||
putreg32(LCD_XPLUS_BIT | LCD_XMINUS_BIT, PIC32MX_IOPORTB_PORTSET);
|
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 */
|
/* Configure Y- as an input and X+, Y+, and X- as outputs */
|
||||||
|
|
||||||
putreg32(LCD_XPLUS_BIT | LCD_XMINUS_BIT | LCD_YPLUS_BIT,
|
putreg32(LCD_XPLUS_BIT | LCD_XMINUS_BIT | LCD_YPLUS_BIT, PIC32MX_IOPORTB_TRISCLR);
|
||||||
PIC32MX_IOPORTB_TRISCLR);
|
|
||||||
putreg32(LCD_YMINUS_BIT, PIC32MX_IOPORTB_TRISSET);
|
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_YPLUS_BIT, PIC32MX_IOPORTB_PORTCLR);
|
||||||
putreg32(LCD_XPLUS_BIT | LCD_XMINUS_BIT, PIC32MX_IOPORTB_PORTSET);
|
putreg32(LCD_XPLUS_BIT | LCD_XMINUS_BIT, PIC32MX_IOPORTB_PORTSET);
|
||||||
@ -455,6 +464,15 @@ static void tc_xminus_sample(void)
|
|||||||
tc_adc_sample(LCD_YMINUS_PIN);
|
tc_adc_sample(LCD_YMINUS_PIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: tc_valid_sample
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline bool tc_valid_sample(uint16_t sample)
|
||||||
|
{
|
||||||
|
return (sample > LOWER_THRESHOLD /* && sample < UPPER_THRESHOLD */);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: tc_notify
|
* Name: tc_notify
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -655,11 +673,11 @@ static void tc_worker(FAR void *arg)
|
|||||||
|
|
||||||
value = tc_adc_convert();
|
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.
|
* and that the sampling period is complete.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (value == 0)
|
if (!tc_valid_sample(value))
|
||||||
{
|
{
|
||||||
priv->state = TC_PENUP;
|
priv->state = TC_PENUP;
|
||||||
}
|
}
|
||||||
@ -677,6 +695,7 @@ static void tc_worker(FAR void *arg)
|
|||||||
* the touchscreen.
|
* the touchscreen.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
case TC_RESAMPLE:
|
||||||
case TC_DEBOUNCE:
|
case TC_DEBOUNCE:
|
||||||
{
|
{
|
||||||
/* (Re-)start Y- sampling */
|
/* (Re-)start Y- sampling */
|
||||||
@ -700,11 +719,12 @@ static void tc_worker(FAR void *arg)
|
|||||||
|
|
||||||
value = tc_adc_convert();
|
value = tc_adc_convert();
|
||||||
|
|
||||||
/* A converted value of zero would mean that the there is no touch
|
/* A converted value at the minimum would mean that there is no touch
|
||||||
* and that the sampling period is complete.
|
* 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;
|
priv->state = TC_PENUP;
|
||||||
}
|
}
|
||||||
@ -729,20 +749,39 @@ static void tc_worker(FAR void *arg)
|
|||||||
|
|
||||||
case TC_YPSAMPLE: /* Allowing time for the Y+ sampling */
|
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();
|
value = tc_adc_convert();
|
||||||
priv->newy = (value + priv->value) >> 1;
|
|
||||||
ivdbg("Y-=%d Y+=%d Y=%d\n", priv->value, value, priv->newy);
|
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
||||||
/* Allow time for the X+ sampling */
|
/* Start X+ sampling */
|
||||||
|
|
||||||
|
tc_xplus_sample();
|
||||||
|
|
||||||
|
/* Allow time for the X+ sampling */
|
||||||
|
|
||||||
priv->state = TC_XPSAMPLE;
|
priv->state = TC_XPSAMPLE;
|
||||||
delay = TC_SAMPLE_TICKS;
|
delay = TC_SAMPLE_TICKS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -752,18 +791,39 @@ static void tc_worker(FAR void *arg)
|
|||||||
|
|
||||||
case TC_XPSAMPLE:
|
case TC_XPSAMPLE:
|
||||||
{
|
{
|
||||||
/* Convert and save the X+ sample value */
|
/* Convert the X+ sample value */
|
||||||
|
|
||||||
priv->value = tc_adc_convert();
|
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_xminus_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
|
||||||
|
{
|
||||||
|
/* Save the X+ sample value */
|
||||||
|
|
||||||
/* Allow time for the X- pend down sampling */
|
priv->value = value;
|
||||||
|
|
||||||
|
/* Start X- sampling */
|
||||||
|
|
||||||
|
tc_xminus_sample();
|
||||||
|
|
||||||
|
/* Allow time for the X- pend down sampling */
|
||||||
|
|
||||||
priv->state = TC_XMSAMPLE;
|
priv->state = TC_XMSAMPLE;
|
||||||
delay = TC_SAMPLE_TICKS;
|
delay = TC_SAMPLE_TICKS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -773,15 +833,36 @@ static void tc_worker(FAR void *arg)
|
|||||||
|
|
||||||
case TC_XMSAMPLE: /* Allowing time for the X- sampling */
|
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();
|
value = tc_adc_convert();
|
||||||
newx = (value + priv->value) >> 1;
|
|
||||||
ivdbg("X+=%d X-=%d Y=%d\n", priv->value, value, newx);
|
|
||||||
|
|
||||||
/* 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;
|
break;
|
||||||
}
|
}
|
||||||
@ -851,9 +932,10 @@ static void tc_worker(FAR void *arg)
|
|||||||
ydiff = -ydiff;
|
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.x = newx;
|
||||||
priv->sample.y = priv->newy;
|
priv->sample.y = priv->newy;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user