SAMA5 touchscreen and ADC: A little more progress

This commit is contained in:
Gregory Nutt
2013-10-01 11:23:24 -06:00
parent f71435780a
commit a737c93ea2
3 changed files with 388 additions and 193 deletions
+1 -1
View File
@@ -5683,7 +5683,7 @@
no serial driver) (from Alan Carvalho de Assis, 2013-9-30).
* configs/freedom-kl25z/minnsh: A new configuration that is
an experiement to see how small we can get the NuttX footprint.
From Carvalho de Assis. (2013-9-30).
From Alan Carvalho de Assis. (2013-9-30).
* net/net_sendfile: The high performance sendfile logic is
now functional. From Max Holtzberg (2013-9-30).
* tools/define.sh: 'cut' long because as it once did. Script
+205 -84
View File
@@ -57,6 +57,7 @@
#include "chip.h"
#include "chip/sam_adc.h"
#include "sam_dmac.h"
#include "sam_adc.h"
#if defined(CONFIG_SAMA5_ADC)
@@ -123,6 +124,19 @@
SAMA5_CHAN6_ENABLE || SAMA5_CHAN7_ENABLE || SAMA5_CHAN8_ENABLE || \
SAMA5_CHAN9_ENABLE || SAMA5_CHAN10_ENABLE || SAMA5_CHAN11_ENABLE)
/* DMA configuration flags */
#ifdef CONFIG_SAMA5_ADC_DMA
# define DMA_FLAGS \
DMACH_FLAG_FIFOCFG_LARGEST | \
((SAM_IRQ_ADC << DMACH_FLAG_PERIPHPID_SHIFT) | DMACH_FLAG_PERIPHAHB_AHB_IF2 | \
DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH | \
DMACH_FLAG_PERIPHWIDTH_16BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 | \
((0x3f) << DMACH_FLAG_MEMPID_SHIFT) | DMACH_FLAG_MEMAHB_AHB_IF0 | \
DMACH_FLAG_MEMWIDTH_16BITS | DMACH_FLAG_MEMINCREMENT | \
DMACH_FLAG_MEMCHUNKSIZE_1)
#endif
/****************************************************************************
* Private Types
****************************************************************************/
@@ -133,6 +147,10 @@ struct sam_adc_s
{
#ifdef SAMA5_ADC_HAVE_CHANNELS
struct adc_dev_s dev; /* The external via of the ADC device */
#ifdef CONFIG_SAMA5_ADC_DMA
DMA_HANDLE dma; /* Handle for DMA channel */
#endif
#endif
/* Debug stuff */
@@ -155,6 +173,14 @@ static bool sam_adc_checkreg(struct sam_adc_s *priv, bool wr,
uint32_t regval, uintptr_t address);
#endif
/* DMA helper functions */
#ifdef CONFIG_SAMA5_ADC_DMA
static void sam_adc_dmacallback(DMA_HANDLE handle, void *arg, int result);
static int sam_adc_dmasetup(struct sam_adc_s *priv, FAR uint8_t *buffer,
size_t buflen)
#endif
/* ADC interrupt handling */
#ifdef SAMA5_ADC_HAVE_CHANNELS
@@ -207,6 +233,9 @@ static struct adc_dev_s g_adcdev =
* Private Functions
****************************************************************************/
/****************************************************************************
* Register Operations
****************************************************************************/
/****************************************************************************
* Name: sam_adc_checkreg
*
@@ -263,6 +292,169 @@ static bool sam_adc_checkreg(struct sam_adc_s *priv, bool wr,
#ifdef SAMA5_ADC_HAVE_CHANNELS
/****************************************************************************
* DMA Helpers
****************************************************************************/
/****************************************************************************
* Name: sam_adc_dmacallback
*
* Description:
* Called when HSMCI DMA completes
*
****************************************************************************/
#ifdef CONFIG_SAMA5_ADC_DMA
static void sam_adc_dmacallback(DMA_HANDLE handle, void *arg, int result)
{
struct sam_dev_s *priv = (struct sam_dev_s *)arg;
#warning Missing logic
}
#endif
/****************************************************************************
* Name: sam_adc_dmasetup
*
* Description:
* Setup to perform a read DMA. If the processor supports a data cache,
* then this method will also make sure that the contents of the DMA memory
* and the data cache are coherent. For read transfers this may mean
* invalidating the data cache.
*
* Input Parameters:
* dev - An instance of the SDIO device interface
* buffer - The memory to DMA from
* buflen - The size of the DMA transfer in bytes
*
* Returned Value:
* OK on success; a negated errno on failure
*
****************************************************************************/
#ifdef CONFIG_SAMA5_ADC_DMA
static int sam_adc_dmasetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
size_t buflen)
{
struct sam_dev_s *priv = (struct sam_dev_s *)dev;
uint32_t paddr;
uint32_t maddr;
DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
DEBUGASSERT(((uint32_t)buffer & 3) == 0);
/* Physical address of the ADC LCDR register and of the buffer location in
* RAM.
*/
paddr = sam_physregaddr(SAM_ADC_LCDR);
maddr = sam_physramaddr((uintptr_t)buffer);
/* Configure the RX DMA */
sam_dmarxsetup(priv->dma, paddr, maddr, buflen);
/* Enable DMA handshaking */
#warning Missing logic
/* Start the DMA */
sam_dmastart(priv->dma, sam_adc_dmacallback, priv);
/* Configure DMA-related interrupts */
#warning Missing loic
return OK;
}
#endif
/****************************************************************************
* ADC interrupt handling
****************************************************************************/
/****************************************************************************
* 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
*
* Description:
* ADC interrupt handler
*
****************************************************************************/
static int sam_adc_interrupt(int irq, void *context)
{
struct sam_adc_s *priv = (struct sam_adc_s *)g_adcdev.ad_priv;
uint32_t isr;
uint32_t imr;
uint32_t pending;
uint32_t regval;
/* 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;
}
/****************************************************************************
* ADC methods
****************************************************************************/
/****************************************************************************
* Name: sam_adc_reset
*
@@ -278,6 +470,12 @@ static void sam_adc_reset(struct adc_dev_s *dev)
irqstate_t flags;
uint32_t regval;
#ifdef CONFIG_SAMA5_ADC_DMA
/* Stop any ongoing DMA */
sam_dmastop(priv->dma);
#endif
/* Reset the ADC controller */
flags = irqsave();
@@ -388,90 +586,6 @@ static int sam_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg)
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
*
* Description:
* ADC interrupt handler
*
****************************************************************************/
static int sam_adc_interrupt(int irq, void *context)
{
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;
/* 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;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -535,6 +649,13 @@ struct adc_dev_s *sam_adc_initialize(void)
sam_configpio(PIO_ADC_TRG);
#endif
#ifdef CONFIG_SAMA5_ADC_DMA
/* Allocate a DMA channel */
priv->dma = sam_dmachannel(dmac, DMA_FLAGS);
DEBUGASSERT(priv->dma);
#endif
/* Reset the ADC controller */
sam_adc_putreg(priv, SAM_ADC_CR, ADC_CR_SWRST);
+182 -108
View File
@@ -67,12 +67,12 @@
* defined here so that it will be used consistently in all places.
*/
#define DEV_FORMAT "/dev/input%d"
#define DEV_NAMELEN 16
#define DEV_FORMAT "/dev/input%d"
#define DEV_NAMELEN 16
/* Poll the pen position while the pen is down at this rate (50MS): */
#define TSD_WDOG_DELAY ((50 + (MSEC_PER_TICK-1))/ MSEC_PER_TICK)
#define TSD_WDOG_DELAY ((50 + (MSEC_PER_TICK-1))/ MSEC_PER_TICK)
/* This is a value for the threshold that guantees a big difference on the
* first pendown (but can't overflow).
@@ -80,13 +80,36 @@
#define INVALID_THRESHOLD 0x1000
/* Touchscreen interrupt event sets
*
* ADC_INT_XRDY TS Measure XPOS Ready Interrupt
* ADC_INT_YRDY TS Measure YPOS Ready Interrupt
* ADC_INT_PRDY TS Measure Pressure Ready Interrupt
* ADC_INT_PEN Pen Contact Interrupt
* ADC_INT_NOPEN No Pen Contact Interrupt
* ADC_SR_PENS Pen detect Status (Not an interrupt)
*/
#define ADC_TSD_CMNINTS (ADC_INT_XRDY | ADC_INT_YRDY | ADC_INT_PRDY | ADC_INT_NOPEN)
#define ADC_TSD_ALLINTS (ADC_TSD_CMNINTS | ADC_INT_PEN)
#define ADC_TSD_ALLSTATUS (ADC_TSD_ALLINTS | ADC_INT_PENS)
#define ADC_TSD_RELEASEINTS ADC_TSD_CMNINTS
/* Data ready/pen status bit definitions */
#define TSD_XREADY (1 << 0) /* X value is ready */
#define TSD_YREADY (1 << 1) /* Y value is ready */
#define TSD_PREADY (1 << 2) /* Pressure value is ready */
#define TSD_PENDOWN (1 << 3) /* Pen is down */
#define TSD_ALLREADY (TSD_XREADY | TSD_YREADY | TSD_PREADY)
/****************************************************************************
* Private Types
****************************************************************************/
/* This describes the state of one contact */
enum sam_contact_3
enum sam_contact_e
{
CONTACT_NONE = 0, /* No contact */
CONTACT_DOWN, /* First contact */
@@ -107,13 +130,15 @@ struct sam_sample_s
/* This structure describes the state of one touchscreen driver instance */
struct sam_dev_s
struct sam_tsd_s
{
uint8_t nwaiters; /* Number of threads waiting for touchscreen data */
uint8_t id; /* Current touch point ID */
uint8_t status; /* Data ready/pen status bit set */
volatile bool penchange; /* An unreported event is buffered */
uint16_t threshx; /* Thresholding X value */
uint16_t threshy; /* Thresholding Y value */
volatile uint32_t pending; /* Pending interrupt set set */
sem_t devsem; /* Manages exclusive access to this structure */
sem_t waitsem; /* Used to wait for the availability of data */
@@ -138,22 +163,22 @@ struct sam_dev_s
/* Interrupt bottom half logic and data sampling */
static void sam_notify(FAR struct sam_dev_s *priv);
static int sam_sample(FAR struct sam_dev_s *priv,
FAR struct sam_sample_s *sample);
static int sam_waitsample(FAR struct sam_dev_s *priv,
FAR struct sam_sample_s *sample);
static void sam_bottomhalf(FAR void *arg);
static void sam_notify(struct sam_tsd_s *priv);
static int sam_sample(struct sam_tsd_s *priv, struct sam_sample_s *sample);
static int sam_waitsample(struct sam_tsd_s *priv,
struct sam_sample_s *sample);
static void sam_bottomhalf(void *arg);
static int sam_schedule(struct sam_tsd_s *priv, uint32_t pending);
static void sam_wdog(int argc, uint32_t arg1, ...);
/* Character driver methods */
static int sam_open(FAR struct file *filep);
static int sam_close(FAR struct file *filep);
static ssize_t sam_read(FAR struct file *filep, FAR char *buffer,
size_t len);
static int sam_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
static int sam_open(struct file *filep);
static int sam_close(struct file *filep);
static ssize_t sam_read(struct file *filep, char *buffer, size_t len);
static int sam_ioctl(struct file *filep, int cmd, unsigned long arg);
#ifndef CONFIG_DISABLE_POLL
static int sam_poll(FAR struct file *filep, struct pollfd *fds, bool setup);
static int sam_poll(struct file *filep, struct pollfd *fds, bool setup);
#endif
/****************************************************************************
@@ -177,7 +202,7 @@ static const struct file_operations g_tsdops =
/* The driver state structure is pre-allocated. */
static struct sam_dev_s g_tsd;
static struct sam_tsd_s g_tsd;
/****************************************************************************
* Private Functions
@@ -187,7 +212,7 @@ static struct sam_dev_s g_tsd;
* Name: sam_notify
****************************************************************************/
static void sam_notify(FAR struct sam_dev_s *priv)
static void sam_notify(struct sam_tsd_s *priv)
{
#ifndef CONFIG_DISABLE_POLL
int i;
@@ -230,8 +255,7 @@ static void sam_notify(FAR struct sam_dev_s *priv)
* Name: sam_sample
****************************************************************************/
static int sam_sample(FAR struct sam_dev_s *priv,
FAR struct sam_sample_s *sample)
static int sam_sample(struct sam_tsd_s *priv, struct sam_sample_s *sample)
{
irqstate_t flags;
int ret = -EAGAIN;
@@ -284,8 +308,7 @@ static int sam_sample(FAR struct sam_dev_s *priv,
* Name: sam_waitsample
****************************************************************************/
static int sam_waitsample(FAR struct sam_dev_s *priv,
FAR struct sam_sample_s *sample)
static int sam_waitsample(struct sam_tsd_s *priv, struct sam_sample_s *sample)
{
irqstate_t flags;
int ret;
@@ -361,58 +384,29 @@ errout:
return ret;
}
/****************************************************************************
* Name: sam_schedule
****************************************************************************/
static int sam_schedule(FAR struct sam_dev_s *priv)
{
int ret;
/* Disable further touchscreen interrupts. Touchscreen interrupts will be
* re-enabled after the worker thread executes.
*/
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.
*/
wd_cancel(priv->wdog);
/* Transfer processing to the worker thread. Since touchscreen ADC interrupts are
* disabled while the work is pending, no special action should be required
* to protected the work queue.
*/
DEBUGASSERT(priv->work.worker == NULL);
ret = work_queue(HPWORK, &priv->work, sam_bottomhalf, priv, 0);
if (ret != 0)
{
illdbg("Failed to queue work: %d\n", ret);
}
return OK;
}
/****************************************************************************
* Name: sam_wdog
****************************************************************************/
static void sam_wdog(int argc, uint32_t arg1, ...)
{
FAR struct sam_dev_s *priv = (FAR struct sam_dev_s *)((uintptr_t)arg1);
(void)sam_schedule(priv);
}
/****************************************************************************
* Name: sam_bottomhalf
*
* Description:
* This function executes on the worker thread. It is scheduled by
* sam_tsd_interrupt whenever any interesting, enabled TSD event occurs.
* All TSD interrupts are disabled when this function runs. sam_bottomhalf
* will re-enable TSD interrupts when it completes processing all pending
* TSD events.
*
* Input Parameters
* arg - The touchscreen private data structure cast to (void *)
*
* Returned Value:
* None
*
****************************************************************************/
static void sam_bottomhalf(FAR void *arg)
static void sam_bottomhalf(void *arg)
{
FAR struct sam_dev_s *priv = (FAR struct sam_dev_s *)arg;
struct sam_tsd_s *priv = (struct sam_tsd_s *)arg;
uint32_t pending;
uint32_t regval;
uint16_t x;
uint16_t y;
uint16_t xdiff;
@@ -428,6 +422,10 @@ static void sam_bottomhalf(FAR void *arg)
wd_cancel(priv->wdog);
/* Get the set of unmasked, pending ADC interrupts */
pending = priv->pending;
/* Get exclusive access to the driver data structure */
do
@@ -556,18 +554,81 @@ static void sam_bottomhalf(FAR void *arg)
ignored:
/* Re-enable touchscreen interrupts. */
sam_adc_putreg32(priv->dev, SAM_ADC_IER, ADC_TSD_INTS);
sam_adc_putreg32(priv->dev, SAM_ADC_IER, ADC_TSD_ALLINTS);
/* Release our lock on the state structure */
sem_post(&priv->devsem);
}
/****************************************************************************
* Name: sam_schedule
****************************************************************************/
static int sam_schedule(struct sam_tsd_s *priv, uint32_t pending)
{
int ret;
/* Disable the watchdog timer. It will be re-enabled in the worker thread
* while the pen remains down.
*/
wd_cancel(priv->wdog);
/* Disable further touchscreen interrupts. Touchscreen interrupts will be
* re-enabled after the worker thread executes.
*/
sam_adc_putreg32(priv->dev, SAM_ADC_IDR, ADC_TSD_ALLINTS);
/* Save the set of pending interrupts for the bottom half (in case any
* were cleared by reading the ISR.
*/
priv->pending = pending.
/* Transfer processing to the worker thread. Since touchscreen ADC interrupts are
* disabled while the work is pending, no special action should be required
* to protected the work queue.
*/
DEBUGASSERT(priv->work.worker == NULL);
ret = work_queue(HPWORK, &priv->work, sam_bottomhalf, priv, 0);
if (ret != 0)
{
illdbg("Failed to queue work: %d\n", ret);
}
return OK;
}
/****************************************************************************
* Name: sam_wdog
*
* Description:
* While the pen is pressed, pen position is periodically polled via a
* watchdog timer. This function handles that timer expiration.
*
****************************************************************************/
static void sam_wdog(int argc, uint32_t arg1, ...)
{
struct sam_tsd_s *priv = (struct sam_tsd_s *)((uintptr_t)arg1);
uint32_t pending;
/* There should be no pending TSD interrupts, but we need to get the PENS
* status bit as a minimum.
*/
pending = sam_adc_getreg(priv, SAM_ADC_ISR) & ADC_TSD_ALLSTATUS;
(void)sam_schedule(priv, pending);
}
/****************************************************************************
* Name: sam_open
****************************************************************************/
static int sam_open(FAR struct file *filep)
static int sam_open(struct file *filep)
{
ivdbg("Opening\n");
return OK;
@@ -577,7 +638,7 @@ static int sam_open(FAR struct file *filep)
* Name: sam_close
****************************************************************************/
static int sam_close(FAR struct file *filep)
static int sam_close(struct file *filep)
{
ivdbg("Closing\n");
return OK;
@@ -587,11 +648,11 @@ static int sam_close(FAR struct file *filep)
* Name: sam_read
****************************************************************************/
static ssize_t sam_read(FAR struct file *filep, FAR char *buffer, size_t len)
static ssize_t sam_read(struct file *filep, char *buffer, size_t len)
{
FAR struct inode *inode;
FAR struct sam_dev_s *priv;
FAR struct touch_sample_s *report;
struct inode *inode;
struct sam_tsd_s *priv;
struct touch_sample_s *report;
struct sam_sample_s sample;
int ret;
@@ -600,7 +661,7 @@ static ssize_t sam_read(FAR struct file *filep, FAR char *buffer, size_t len)
inode = filep->f_inode;
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct sam_dev_s *)inode->i_private;
priv = (struct sam_tsd_s *)inode->i_private;
/* Verify that the caller has provided a buffer large enough to receive
* the touch data.
@@ -661,12 +722,12 @@ static ssize_t sam_read(FAR struct file *filep, FAR char *buffer, size_t len)
* to the caller.
*/
report = (FAR struct touch_sample_s *)buffer;
report = (struct touch_sample_s *)buffer;
memset(report, 0, SIZEOF_TOUCH_SAMPLE_S(1));
report->npoints = 1;
report->point[0].id = sample.id;
report->point[0].x = sample.x;
report->point[0].y = sample.y;
report->npoints = 1;
report->point[0].id = sample.id;
report->point[0].x = sample.x;
report->point[0].y = sample.y;
/* Report the appropriate flags */
@@ -716,18 +777,18 @@ errout:
* Name:sam_ioctl
****************************************************************************/
static int sam_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
static int sam_ioctl(struct file *filep, int cmd, unsigned long arg)
{
FAR struct inode *inode;
FAR struct sam_dev_s *priv;
int ret;
struct inode *inode;
struct sam_tsd_s *priv;
int ret;
ivdbg("cmd: %d arg: %ld\n", cmd, arg);
DEBUGASSERT(filep);
inode = filep->f_inode;
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct sam_dev_s *)inode->i_private;
priv = (struct sam_tsd_s *)inode->i_private;
/* Get exclusive access to the driver data structure */
@@ -758,20 +819,19 @@ static int sam_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
****************************************************************************/
#ifndef CONFIG_DISABLE_POLL
static int sam_poll(FAR struct file *filep, FAR struct pollfd *fds,
bool setup)
static int sam_poll(struct file *filep, struct pollfd *fds, bool setup)
{
FAR struct inode *inode;
FAR struct sam_dev_s *priv;
int ret = OK;
int i;
struct inode *inode;
struct sam_tsd_s *priv;
int ret = OK;
int i;
ivdbg("setup: %d\n", (int)setup);
DEBUGASSERT(filep && fds);
inode = filep->f_inode;
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct sam_dev_s *)inode->i_private;
priv = (struct sam_tsd_s *)inode->i_private;
/* Are we setting up the poll? Or tearing it down? */
@@ -871,7 +931,7 @@ errout:
int sam_tsd_register(struct adc_dev_s *dev, int minor)
{
struct sam_dev_s *priv = &g_tsd;
struct sam_tsd_s *priv = &g_tsd;
char devname[DEV_NAMELEN];
int ret;
@@ -883,7 +943,7 @@ int sam_tsd_register(struct adc_dev_s *dev, int minor)
/* Initialize the touchscreen device driver instance */
memset(priv, 0, sizeof(struct sam_dev_s));
memset(priv, 0, sizeof(struct sam_tsd_s));
priv->dev = dev; /* Save the ADC device handle */
priv->wdog = wd_create(); /* Create a watchdog timer */
priv->threshx = INVALID_THRESHOLD; /* Initialize thresholding logic */
@@ -941,29 +1001,43 @@ errout_with_priv:
* 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)
{
struct sam_dev_s *priv = &g_tsd;
struct sam_tsd_s *priv = &g_tsd;
int ret;
/* Disable further touchscreen interrupts */
/* Are there pending TSD interrupts? */
sam_adc_putreg32(priv->dev, SAM_ADC_IDR, ADC_TSD_INTS);
/* Schedule sampling to occur on the worker thread */
ret = sam_schedule(priv);
if (ret < 0)
if ((pending & ADC_TSD_ALLINTS) != 0)
{
idbg("ERROR: sam_schedule failed: %d\n", ret);
/* Disable further touchscreen interrupts */
sam_adc_putreg32(priv->dev, SAM_ADC_IDR, ADC_TSD_ALLINTS);
/* Save the set of pending interrupts for the bottom half (in case any
* were cleared by reading the ISR.
*/
priv->pending = pending & ADC_TSD_ALLSTATUS;
/* Schedule sampling to occur by the interrupt bottom half on the
* worker thread.
*/
ret = sam_schedule(priv, pending);
if (ret < 0)
{
idbg("ERROR: sam_schedule failed: %d\n", ret);
}
}
return ret;
}