SAMA5 ADC/Touchscreen: A little more progress. Still not complete

This commit is contained in:
Gregory Nutt 2013-09-30 14:28:42 -06:00
parent 647aff0ded
commit 4cecf0b618
6 changed files with 369 additions and 113 deletions

View File

@ -289,6 +289,8 @@
#define ADC_INT_EOC7 (1 << 9) /* Bit 9: End of Conversion 9 */
#define ADC_INT_EOC7 (1 << 10) /* Bit 10: End of Conversion 10 */
#define ADC_INT_EOC7 (1 << 11) /* Bit 11: End of Conversion 11 */
#define ADC_INT_EOCALL (0x00000fff)
#define ADC_INT_XRDY (1 << 20) /* Bit 20: TS Measure XPOS Ready Interrupt */
#define ADC_INT_YRDY (1 << 21) /* Bit 21: TS Measure YPOS Ready Interrupt */
#define ADC_INT_PRDY (1 << 22) /* Bit 22: TS Measure Pressure Ready Interrupt */

View File

@ -1,7 +1,6 @@
/************************************************************************************
* arch/arm/src/sama5/sam_adc.c
*
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
@ -65,6 +64,64 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Get the set of channel interrupts to enable */
#define SAMA5_CHAN0_ENABLE 0
#define SAMA5_CHAN1_ENABLE 0
#define SAMA5_CHAN2_ENABLE 0
#define SAMA5_CHAN3_ENABLE 0
#define SAMA5_CHAN4_ENABLE 0
#define SAMA5_CHAN5_ENABLE 0
#define SAMA5_CHAN6_ENABLE 0
#define SAMA5_CHAN7_ENABLE 0
#define SAMA5_CHAN8_ENABLE 0
#define SAMA5_CHAN9_ENABLE 0
#define SAMA5_CHAN10_ENABLE 0
#define SAMA5_CHAN11_ENABLE 0
#if defined(CONFIG_SAMA5_ADC_CHAN0)
# undef SAMA5_CHAN0_ENABLE
# define SAMA5_CHAN0_ENABLE ADC_INT_EOC0
#elif defined(CONFIG_SAMA5_ADC_CHAN1)
# undef SAMA5_CHAN1_ENABLE
# define SAMA5_CHAN1_ENABLE ADC_INT_EOC1
#elif defined(CONFIG_SAMA5_ADC_CHAN2)
# undef SAMA5_CHAN2_ENABLE
# define SAMA5_CHAN2_ENABLE ADC_INT_EOC2
#elif defined(CONFIG_SAMA5_ADC_CHAN3)
# undef SAMA5_CHAN3_ENABLE
# define SAMA5_CHAN3_ENABLE ADC_INT_EOC3
#elif defined(CONFIG_SAMA5_ADC_CHAN4)
# undef SAMA5_CHAN4_ENABLE
# define SAMA5_CHAN4_ENABLE ADC_INT_EOC4
#elif defined(CONFIG_SAMA5_ADC_CHAN5)
# undef SAMA5_CHAN5_ENABLE
# define SAMA5_CHAN5_ENABLE ADC_INT_EOC5
#elif defined(CONFIG_SAMA5_ADC_CHAN6)
# undef SAMA5_CHAN6_ENABLE
# define SAMA5_CHAN6_ENABLE ADC_INT_EOC6
#elif defined(CONFIG_SAMA5_ADC_CHAN7)
# undef SAMA5_CHAN7_ENABLE
# define SAMA5_CHAN7_ENABLE ADC_INT_EOC7
#elif defined(CONFIG_SAMA5_ADC_CHAN8)
# undef SAMA5_CHAN8_ENABLE
# define SAMA5_CHAN8_ENABLE ADC_INT_EOC8
#elif defined(CONFIG_SAMA5_ADC_CHAN9)
# undef SAMA5_CHAN9_ENABLE
# define SAMA5_CHAN9_ENABLE ADC_INT_EOC9
#elif defined(CONFIG_SAMA5_ADC_CHAN10)
# undef SAMA5_CHAN10_ENABLE
# define SAMA5_CHAN10_ENABLE ADC_INT_EOC10
#elif defined(CONFIG_SAMA5_ADC_CHAN11)
# undef SAMA5_CHAN11_ENABLE
# define SAMA5_CHAN11_ENABLE ADC_INT_EOC11
#endif
#define SAMA5_CHAN_ENABLE \
(SAMA5_CHAN0_ENABLE || SAMA5_CHAN1_ENABLE || SAMA5_CHAN2_ENABLE || \
SAMA5_CHAN3_ENABLE || SAMA5_CHAN4_ENABLE || SAMA5_CHAN5_ENABLE || \
SAMA5_CHAN6_ENABLE || SAMA5_CHAN7_ENABLE || SAMA5_CHAN8_ENABLE || \
SAMA5_CHAN9_ENABLE || SAMA5_CHAN10_ENABLE || SAMA5_CHAN11_ENABLE)
/****************************************************************************
* Private Types
@ -74,13 +131,17 @@
struct sam_adc_s
{
#ifdef SAMA5_ADC_HAVE_CHANNELS
struct adc_dev_s dev; /* The external via of the ADC device */
#endif
/* Debug stuff */
#ifdef CONFIG_SAMA5_ADC_REGDEBUG
bool wrlast; /* Last was a write */
uintptr_t addrlast; /* Last address */
uint32_t vallast; /* Last value */
int ntimes; /* Number of times */
bool wrlast; /* Last was a write */
uintptr_t addrlast; /* Last address */
uint32_t vallast; /* Last value */
int ntimes; /* Number of times */
#endif
};
@ -90,31 +151,32 @@ struct sam_adc_s
/* Register operations ******************************************************/
#if defined(CONFIG_SAMA5_ADC_REGDEBUG) && defined(CONFIG_DEBUG)
static bool sam_adc_checkreg(struct sam_gmac_s *priv, bool wr,
uint32_t regval, uintptr_t address);
static uint32_t sam_adc_getreg(struct sam_gmac_s *priv, uintptr_t addr);
static void sam_adc_putreg(struct sam_gmac_s *priv, uintptr_t addr, uint32_t val);
#else
# define sam_adc_getreg(priv,addr) getreg32(addr)
# define sam_adc_putreg(priv,addr,val) putreg32(val,addr)
static bool sam_adc_checkreg(struct sam_adc_s *priv, bool wr,
uint32_t regval, uintptr_t address);
#endif
/* ADC interrupt handling */
#ifdef SAMA5_ADC_HAVE_CHANNELS
static void sam_adc_endconversion(struct sam_adc_s *priv, uint32_t pending);
#endif
static int sam_adc_interrupt(int irq, void *context);
/* ADC methods */
static void sam_adc_reset(FAR struct adc_dev_s *dev);
static int sam_adc_setup(FAR struct adc_dev_s *dev);
static void sam_adc_shutdown(FAR struct adc_dev_s *dev);
static void sam_adc_rxint(FAR struct adc_dev_s *dev, bool enable);
static int sam_adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg);
#ifdef SAMA5_ADC_HAVE_CHANNELS
static void sam_adc_reset(struct adc_dev_s *dev);
static int sam_adc_setup(struct adc_dev_s *dev);
static void sam_adc_shutdown(struct adc_dev_s *dev);
static void sam_adc_rxint(struct adc_dev_s *dev, bool enable);
static int sam_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg);
#endif
/****************************************************************************
* Private Data
****************************************************************************/
#ifdef SAMA5_ADC_HAVE_CHANNELS
/* ADC lower half device operations */
static const struct adc_ops_s g_adcops =
@ -125,20 +187,21 @@ static const struct adc_ops_s g_adcops =
.ao_rxint = sam_adc_rxint,
.ao_ioctl = sam_adc_ioctl,
};
#endif
/* ADC internal state */
static struct sam_adc_s g_adcpriv =
{
};
static struct sam_adc_s g_adcpriv;
#ifdef SAMA5_ADC_HAVE_CHANNELS
/* ADC device instance */
static struct adc_dev_s g_adcdev =
{
.ad_ops = &g_adcops,
.ad_priv = &g_adcpriv,
.ad_priv = &g_adcpriv.dev,
};
#endif
/****************************************************************************
* Private Functions
@ -161,7 +224,7 @@ static struct adc_dev_s g_adcdev =
****************************************************************************/
#ifdef CONFIG_SAMA5_ADC_REGDEBUG
static bool sam_adc_checkreg(struct sam_gmac_s *priv, bool wr,
static bool sam_adc_checkreg(struct sam_adc_s *priv, bool wr,
uint32_t regval, uintptr_t address)
{
if (wr == priv->wrlast && /* Same kind of access? */
@ -198,48 +261,7 @@ static bool sam_adc_checkreg(struct sam_gmac_s *priv, bool wr,
}
#endif
/****************************************************************************
* Name: sam_adc_getreg
*
* Description:
* Read any 32-bit register using an absolute address.
*
****************************************************************************/
#ifdef CONFIG_SAMA5_ADC_REGDEBUG
static uint32_t sam_adc_getreg(struct sam_gmac_s *priv, uintptr_t address)
{
uint32_t regval = getreg32(address);
if (sam_adc_checkreg(priv, false, regval, address))
{
lldbg("%08x->%08x\n", address, regval);
}
return regval;
}
#endif
/****************************************************************************
* Name: sam_adc_putreg
*
* Description:
* Write to any 32-bit register using an absolute address.
*
****************************************************************************/
#ifdef CONFIG_SAMA5_ADC_REGDEBUG
static void sam_adc_putreg(struct sam_gmac_s *priv, uintptr_t address,
uint32_t regval)
{
if (sam_adc_checkreg(priv, true, regval, address))
{
lldbg("%08x<-%08x\n", address, regval);
}
putreg32(regval, address);
}
#endif
#ifdef SAMA5_ADC_HAVE_CHANNELS
/****************************************************************************
* Name: sam_adc_reset
@ -250,15 +272,20 @@ static void sam_adc_putreg(struct sam_gmac_s *priv, uintptr_t address,
*
****************************************************************************/
static void sam_adc_reset(FAR struct adc_dev_s *dev)
static void sam_adc_reset(struct adc_dev_s *dev)
{
FAR struct sam_adc_s *priv = (FAR struct sam_adc_s *)dev->ad_priv;
struct sam_adc_s *priv = (struct sam_adc_s *)dev->ad_priv;
irqstate_t flags;
uint32_t regval;
flags = irqsave();
#warning Missing logic
/* Reset the ADC controller */
flags = irqsave();
sam_adc_putreg(priv, SAM_ADC_CR, ADC_CR_SWRST);
/* Reset Mode Register */
sam_adc_putreg(priv, SAM_ADC_MR, 0);
irqrestore(flags);
}
@ -273,9 +300,9 @@ static void sam_adc_reset(FAR struct adc_dev_s *dev)
*
****************************************************************************/
static int sam_adc_setup(FAR struct adc_dev_s *dev)
static int sam_adc_setup(struct adc_dev_s *dev)
{
FAR struct sam_adc_s *priv = (FAR struct sam_adc_s *)dev->ad_priv;
struct sam_adc_s *priv = (struct sam_adc_s *)dev->ad_priv;
int ret;
/* Attach the ADC interrupt */
@ -302,15 +329,15 @@ static int sam_adc_setup(FAR struct adc_dev_s *dev)
*
****************************************************************************/
static void sam_adc_shutdown(FAR struct adc_dev_s *dev)
static void sam_adc_shutdown(struct adc_dev_s *dev)
{
FAR struct sam_adc_s *priv = (FAR struct sam_adc_s *)dev->ad_priv;
struct sam_adc_s *priv = (struct sam_adc_s *)dev->ad_priv;
/* Disable ADC interrupts, both at the level of the ADC device and at the
* level of the NVIC.
*/
#warning Missing logic
sam_adc_putreg32(priv, SAM_ADC_IDR, ADC_TSD_INTS);
up_disable_irq(SAM_IRQ_ADC);
/* Then detach the ADC interrupt handler. */
@ -326,18 +353,23 @@ static void sam_adc_shutdown(FAR struct adc_dev_s *dev)
*
****************************************************************************/
static void sam_adc_rxint(FAR struct adc_dev_s *dev, bool enable)
static void sam_adc_rxint(struct adc_dev_s *dev, bool enable)
{
FAR struct sam_adc_s *priv = (FAR struct sam_adc_s *)dev->ad_priv;
struct sam_adc_s *priv = (struct sam_adc_s *)dev->ad_priv;
/* Are we enabling or disabling? */
if (enable)
{
#warning Missing logic
/* Enable channel interrupts */
sam_adc_putreg32(priv, SAM_ADC_IER, SAMA5_CHAN_ENABLE);
}
else
{
#warning Missing logic
/* Disable channel interrupts */
sam_adc_putreg32(priv, SAM_ADC_IDR, ADC_INT_EOCALL);
}
}
@ -349,13 +381,44 @@ static void sam_adc_rxint(FAR struct adc_dev_s *dev, bool enable)
*
****************************************************************************/
static int sam_adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg)
static int sam_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg)
{
/* No ioctl commands supported */
return -ENOTTY;
}
/****************************************************************************
* Name: sam_adc_endconversion
*
* Description:
* End of conversion interrupt handler
*
****************************************************************************/
static void sam_adc_endconversion(struct sam_adc_s *priv, uint32_t pending)
{
uint32_t regval;
int chan;
/* Check for the end of conversion event on each channel */
for (chan = 0; chan < SAM_ADC_NCHANNELS && pending != 0; chan++)
{
uint32_t bit = ADC_INT_EOC(chan);
if ((pending & bit) != 0)
{
/* Read the ADC sample and pass it to the upper half */
regval = sam_adc_getreg(priv, SAM_ADC_CDR(chan));
ret = adc_receive(&priv->dev, chan, regval & ADC_CDR_DATA_MASK);
pending &= ~bit;
}
}
}
#endif /* SAMA5_ADC_HAVE_CHANNELS */
/****************************************************************************
* Name: sam_adc_interrupt
*
@ -366,11 +429,46 @@ static int sam_adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg)
static int sam_adc_interrupt(int irq, void *context)
{
FAR struct sam_adc_s *priv = (FAR struct sam_adc_s *)g_adcdev.ad_priv;
struct sam_adc_s *priv = (struct sam_adc_s *)g_adcdev.ad_priv;
uint32_t regval;
struct sam_adc_s *priv = &g_adcpriv;
uint32_t isr;
uint32_t imr;
uint32_t pending;
#warning Missing logic
/* Get the set of unmasked, pending ADC interrupts */
isr = sam_adc_getreg(priv, SAM_ADC_ISR);
imr = sam_adc_getreg(priv, SAM_ADC_IMR);
pending = isr & imr;
/* Handle pending touchscreen interrupts */
#ifdef CONFIG_SAMA5_TOUCHSCREEN
if ((pending & ADC_TSD_INTS) != 0)
{
/* Let the touchscreen handle its interrupts */
sam_tsd_interrupt(pending);
pending &= ~ADC_TSD_INTS;
}
#endif
#ifdef SAMA5_ADC_HAVE_CHANNELS
/* Check for end-of-conversion interrupts */
if ((pending & ADC_INT_EOCALL) != 0)
{
/* Let the touchscreen handle its interrupts */
sam_adc_endconversion(pending);
pending &= ~ADC_INT_EOCALL;
}
#endif
/* Make sure that all interrupts were handled */
DEBUGASSERT(pending == 0);
return OK;
}
@ -389,12 +487,54 @@ static int sam_adc_interrupt(int irq, void *context)
*
****************************************************************************/
FAR struct adc_dev_s *sam_adc_initialize(void)
struct adc_dev_s *sam_adc_initialize(void)
{
/* Enable the ADC peripheral clock*/
sam_adc_enableclk();
/* Configure ADC pins */
#ifdef CONFIG_SAMA5_ADC_CHAN0
sam_configpio(PIO_ADC_AD0);
#endif
#ifdef CONFIG_SAMA5_ADC_CHAN1
sam_configpio(PIO_ADC_AD1);
#endif
#ifdef CONFIG_SAMA5_ADC_CHAN2
sam_configpio(PIO_ADC_AD2);
#endif
#ifdef CONFIG_SAMA5_ADC_CHAN3
sam_configpio(PIO_ADC_AD3);
#endif
#ifdef CONFIG_SAMA5_ADC_CHAN4
sam_configpio(PIO_ADC_AD4);
#endif
#ifdef CONFIG_SAMA5_ADC_CHAN5
sam_configpio(PIO_ADC_AD5);
#endif
#ifdef CONFIG_SAMA5_ADC_CHAN6
sam_configpio(PIO_ADC_AD6);
#endif
#ifdef CONFIG_SAMA5_ADC_CHAN7
sam_configpio(PIO_ADC_AD7);
#endif
#ifdef CONFIG_SAMA5_ADC_CHAN8
sam_configpio(PIO_ADC_AD8);
#endif
#ifdef CONFIG_SAMA5_ADC_CHAN9
sam_configpio(PIO_ADC_AD9);
#endif
#ifdef CONFIG_SAMA5_ADC_CHAN10
sam_configpio(PIO_ADC_AD10);
#endif
#ifdef CONFIG_SAMA5_ADC_CHAN11
sam_configpio(PIO_ADC_AD11);
#endif
#if 0
sam_configpio(PIO_ADC_TRG);
#endif
/* Reset the ADC controller */
sam_adc_putreg(priv, SAM_ADC_CR, ADC_CR_SWRST);
@ -408,4 +548,49 @@ FAR struct adc_dev_s *sam_adc_initialize(void)
return &g_adcdev;
}
/****************************************************************************
* Name: sam_adc_getreg
*
* Description:
* Read any 32-bit register using an absolute address.
*
****************************************************************************/
#ifdef CONFIG_SAMA5_ADC_REGDEBUG
static uint32_t sam_adc_getreg(ADC_HANDLE handle, uintptr_t address)
{
struct sam_adc_s *priv = (struct sam_adc_s *)handle;
uint32_t regval = getreg32(address);
if (sam_adc_checkreg(priv, false, regval, address))
{
lldbg("%08x->%08x\n", address, regval);
}
return regval;
}
#endif
/****************************************************************************
* Name: sam_adc_putreg
*
* Description:
* Write to any 32-bit register using an absolute address.
*
****************************************************************************/
#ifdef CONFIG_SAMA5_ADC_REGDEBUG
void sam_adc_putreg(ADC_HANDLE handle, uintptr_t address, uint32_t regval)
{
struct sam_adc_s *priv = (struct sam_adc_s *)handle;
if (sam_adc_checkreg(priv, true, regval, address))
{
lldbg("%08x<-%08x\n", address, regval);
}
putreg32(regval, address);
}
#endif
#endif /* CONFIG_SAMA5_ADC */

View File

@ -50,6 +50,40 @@
****************************************************************************/
/* Configuration ************************************************************/
#ifndef CONFIG_DEBUG
# undef CONFIG_SAMA5_ADC_REGDEBUG
#endif
/* ADC channels 0-3 or 0-4 are not available to the ADC driver if touchscreen
* support is enabled.
*/
#ifdef CONFIG_SAMA5_TOUCHSCREEN
# undef CONFIG_SAMA5_ADC_CHAN0
# undef CONFIG_SAMA5_ADC_CHAN1
# undef CONFIG_SAMA5_ADC_CHAN2
# undef CONFIG_SAMA5_ADC_CHAN3
# ifdef CONFIG_SAMA5_TOUCHSCREEN_5WIRE
# undef CONFIG_SAMA5_ADC_CHAN4
# endif
#endif
/* Do we have any ADC channels enabled? If not, then the ADC driver may
* still need to exist to support the touchscreen.
*/
#undef SAMA5_ADC_HAVE_CHANNELS
#if defined(CONFIG_SAMA5_ADC_CHAN0) || defined(CONFIG_SAMA5_ADC_CHAN1) || \
defined(CONFIG_SAMA5_ADC_CHAN2) || defined(CONFIG_SAMA5_ADC_CHAN3) || \
defined(CONFIG_SAMA5_ADC_CHAN4) || defined(CONFIG_SAMA5_ADC_CHAN5) || \
defined(CONFIG_SAMA5_ADC_CHAN6) || defined(CONFIG_SAMA5_ADC_CHAN7) || \
defined(CONFIG_SAMA5_ADC_CHAN8) || defined(CONFIG_SAMA5_ADC_CHAN9) || \
defined(CONFIG_SAMA5_ADC_CHAN10) || defined(CONFIG_SAMA5_ADC_CHAN11)
# define SAMA5_ADC_HAVE_CHANNELS 1
#elif !defined(CONFIG_SAMA5_TOUCHSCREEN)
# error "No ADC channels nor touchscreen"
#endif
/****************************************************************************
* Public Types
****************************************************************************/
@ -88,6 +122,35 @@ FAR struct adc_dev_s *sam_adcinitialize(void);
* Interfaces exported from the ADC to the touchscreen driver
****************************************************************************/
/****************************************************************************
* Name: sam_adc_getreg
*
* Description:
* Read any 32-bit register using an absolute address.
*
****************************************************************************/
#ifdef CONFIG_SAMA5_ADC_REGDEBUG
uint32_t sam_adc_getreg(FAR struct adc_dev_s *, uintptr_t address)
#else
# define sam_adc_getreg(handle,addr) getreg32(addr)
#endif
/****************************************************************************
* Name: sam_adc_putreg
*
* Description:
* Write to any 32-bit register using an absolute address.
*
****************************************************************************/
#ifdef CONFIG_SAMA5_ADC_REGDEBUG
void sam_adc_putreg(FAR struct adc_dev_s *dev, uintptr_t address,
uint32_t regval)
#else
# define sam_adc_putreg(handle,addr,val) putreg32(val,addr)
#endif
#undef EXTERN
#ifdef __cplusplus
}

View File

@ -94,7 +94,7 @@ enum sam_contact_3
CONTACT_UP, /* Contact lost */
};
/* This structure describes the results of one ADS7843E sample */
/* This structure describes the results of one touchscreen sample */
struct sam_sample_s
{
@ -105,11 +105,11 @@ struct sam_sample_s
uint16_t y; /* Measured Y position */
};
/* This structure describes the state of one ADS7843E driver instance */
/* This structure describes the state of one touchscreen driver instance */
struct sam_dev_s
{
uint8_t nwaiters; /* Number of threads waiting for ADS7843E data */
uint8_t nwaiters; /* Number of threads waiting for touchscreen data */
uint8_t id; /* Current touch point ID */
volatile bool penchange; /* An unreported event is buffered */
uint16_t threshx; /* Thresholding X value */
@ -117,6 +117,7 @@ struct sam_dev_s
sem_t devsem; /* Manages exclusive access to this structure */
sem_t waitsem; /* Used to wait for the availability of data */
struct adc_dev_s *dev; /* ADC device handle */
struct work_s work; /* Supports the interrupt handling "bottom half" */
struct sam_sample_s sample; /* Last sampled touch point data */
WDOG_ID wdog; /* Poll the position while the pen is down */
@ -127,7 +128,7 @@ struct sam_dev_s
*/
#ifndef CONFIG_DISABLE_POLL
struct pollfd *fds[CONFIG_ADS7843E_NPOLLWAITERS];
struct pollfd *fds[CONFIG_SAMA5_TSD_NPOLLWAITERS];
#endif
};
@ -198,14 +199,14 @@ static void sam_notify(FAR struct sam_dev_s *priv)
if (priv->nwaiters > 0)
{
/* After posting this semaphore, we need to exit because the ADS7843E
/* After posting this semaphore, we need to exit because the touchscreen
* is no longer available.
*/
sem_post(&priv->waitsem);
}
/* If there are threads waiting on poll() for ADS7843E data to become available,
/* If there are threads waiting on poll() for touchscreen data to become available,
* then wake them up now. NOTE: we wake up all waiting threads because we
* do not know that they are going to do. If they all try to read the data,
* then some make end up blocking after all.
@ -242,7 +243,7 @@ static int sam_sample(FAR struct sam_dev_s *priv,
flags = irqsave();
/* Is there new ADS7843E sample data available? */
/* Is there new touchscreen sample data available? */
if (priv->penchange)
{
@ -368,10 +369,11 @@ static int sam_schedule(FAR struct sam_dev_s *priv)
{
int ret;
/* Disable further interrupts. touchscreen ADC interrupts will be re-enabled
* after the worker thread executes.
/* Disable further touchscreen interrupts. Touchscreen interrupts will be
* re-enabled after the worker thread executes.
*/
#warning "Missing logic"
sam_adc_putreg32(priv->dev, SAM_ADC_IDR, ADC_TSD_INTS);
/* Disable the watchdog timer. It will be re-enabled in the worker thread
* while the pen remains down.
@ -545,19 +547,16 @@ static void sam_bottomhalf(FAR void *arg)
priv->sample.id = priv->id;
priv->penchange = true;
/* Notify any waiters that new ADS7843E data is available */
/* Notify any waiters that new touchscreen data is available */
sam_notify(priv);
/* Exit, re-enabling ADS7843E interrupts */
/* Exit, re-enabling touchscreen interrupts */
ignored:
/* Re-enable touchscreen interrupts. */
/* Re-enable the PENIRQ interrupts */
#warning Missing logic
/* Re-enable the PENIRQ interrupt at the MCU's interrupt controller */
#warning Missing logic
sam_adc_putreg32(priv->dev, SAM_ADC_IER, ADC_TSD_INTS);
/* Release our lock on the state structure */
@ -658,7 +657,7 @@ static ssize_t sam_read(FAR struct file *filep, FAR char *buffer, size_t len)
}
}
/* In any event, we now have sampled ADS7843E data that we can report
/* In any event, we now have sampled touchscreen data that we can report
* to the caller.
*/
@ -870,9 +869,9 @@ errout:
*
****************************************************************************/
int sam_tsd_register(int minor)
int sam_tsd_register(struct adc_dev_s *dev, int minor)
{
FAR struct sam_dev_s *priv = &g_tsd;
struct sam_dev_s *priv = &g_tsd;
char devname[DEV_NAMELEN];
int ret;
@ -880,11 +879,12 @@ int sam_tsd_register(int minor)
/* Debug-only sanity checks */
DEBUGASSERT(minor >= 0 && minor < 100);
DEBUGASSERT(dev && minor >= 0 && minor < 100);
/* Initialize the touchscreen device driver instance */
memset(priv, 0, sizeof(struct sam_dev_s));
priv->dev = dev; /* Save the ADC device handle */
priv->wdog = wd_create(); /* Create a watchdog timer */
priv->threshx = INVALID_THRESHOLD; /* Initialize thresholding logic */
priv->threshy = INVALID_THRESHOLD; /* Initialize thresholding logic */
@ -945,20 +945,25 @@ errout_with_priv:
*
* Returned Value:
* None
*
*
****************************************************************************/
void sam_tsd_interrupt(void)
{
FAR struct sam_dev_s *priv = &g_tsd;
struct sam_dev_s *priv = &g_tsd;
int ret;
/* Disable further touchscreen interrupts */
sam_adc_putreg32(priv->dev, SAM_ADC_IDR, ADC_TSD_INTS);
/* Schedule sampling to occur on the worker thread */
ret = sam_schedule(priv);
/* Clear any pending interrupts and return success */
#warning Missing logic
if (ret < 0)
{
idbg("ERROR: sam_schedule failed: %d\n", ret);
}
return ret;
}

View File

@ -79,7 +79,8 @@ extern "C"
* /dev/inputN where N is the minor device number
*
* Input Parameters:
* minor - The input device minor number
* dev - The ADC device handle received from sam_adc_initialize()
* minor - The input device minor number
*
* Returned Value:
* Zero is returned on success. Otherwise, a negated errno value is
@ -87,7 +88,7 @@ extern "C"
*
****************************************************************************/
int sam_tsd_register(int minor);
int sam_tsd_register(FAR struct adc_dev_s *dev, int minor);
/****************************************************************************
* Interfaces exported from the touchscreen to the ADC driver
@ -99,14 +100,14 @@ int sam_tsd_register(int minor);
* Handles ADC interrupts associated with touchscreen channels
*
* Input parmeters:
* None
* pending - Current set of pending interrupts being handled
*
* Returned Value:
* None
*
*
****************************************************************************/
void sam_tsd_interrupt(void);
void sam_tsd_interrupt(uint32_t pending);
#undef EXTERN
#ifdef __cplusplus

View File

@ -129,7 +129,7 @@ struct adc_ops_s
};
/* This is the device structure used by the driver. The caller of
* can_register() must allocate and initialize this structure. The
* adc_register() must allocate and initialize this structure. The
* calling logic need only set all fields to zero except:
*
* The elements of 'ad_ops', and 'ad_priv'