Merge branch 'adcbind'
This commit is contained in:
commit
01af4d1af1
@ -2,7 +2,9 @@
|
||||
* arch/arm/src/efm32/efm32_adc.c
|
||||
*
|
||||
* Copyright (C) 2014 Bouteville Pierre-Noel. All rights reserved.
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Authors: Bouteville Pierre-Noel <pnb990@gmail.com>
|
||||
* Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -100,6 +102,7 @@
|
||||
|
||||
struct efm32_dev_s
|
||||
{
|
||||
FAR const struct adc_callback_s *cb;
|
||||
uint8_t irq; /* Interrupt generated by this ADC block */
|
||||
uint8_t nchannels; /* Number of channels */
|
||||
uint8_t current; /* Current ADC channel being converted */
|
||||
@ -124,6 +127,8 @@ static int adc_interrupt(FAR struct adc_dev_s *dev);
|
||||
|
||||
/* ADC Driver Methods */
|
||||
|
||||
static int adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback);
|
||||
static void adc_reset(FAR struct adc_dev_s *dev);
|
||||
static int adc_setup(FAR struct adc_dev_s *dev);
|
||||
static void adc_shutdown(FAR struct adc_dev_s *dev);
|
||||
@ -148,6 +153,7 @@ static void adc_startconv(FAR struct efm32_dev_s *priv, bool enable);
|
||||
|
||||
static const struct adc_ops_s g_adcops =
|
||||
{
|
||||
.ao_bind = adc_bind,
|
||||
.ao_reset = adc_reset,
|
||||
.ao_setup = adc_setup,
|
||||
.ao_shutdown = adc_shutdown,
|
||||
@ -790,7 +796,7 @@ static void adc_startconv(struct efm32_dev_s *priv, bool enable)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_reset
|
||||
* Name: adc_hw_reset
|
||||
*
|
||||
* Description:
|
||||
* Deinitializes the ADCx peripheral registers to their default
|
||||
@ -873,6 +879,25 @@ static void adc_enable(FAR struct efm32_dev_s *priv, bool enable)
|
||||
adc_putreg(priv, EFM32_ADC_CR2_OFFSET, regval);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_bind
|
||||
*
|
||||
* Description:
|
||||
* Bind the upper-half driver callbacks to the lower-half implementation. This
|
||||
* must be called early in order to receive ADC event notifications.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback)
|
||||
{
|
||||
FAR struct efm32_dev_s *priv = (FAR struct efm32_dev_s *)dev->ad_priv;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
priv->cb = callback;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_reset
|
||||
*
|
||||
@ -1180,14 +1205,21 @@ static int adc_interrupt(FAR struct adc_dev_s *dev)
|
||||
value = adc_getreg(priv, EFM32_ADC_DR_OFFSET);
|
||||
value &= ADC_DR_DATA_MASK;
|
||||
|
||||
/* Give the ADC data to the ADC driver. adc_receive accepts 3 parameters:
|
||||
*
|
||||
* 1) The first is the ADC device instance for this ADC block.
|
||||
* 2) The second is the channel number for the data, and
|
||||
* 3) The third is the converted data for the channel.
|
||||
*/
|
||||
/* Verify that the upper-half driver has bound its callback functions */
|
||||
|
||||
adc_receive(dev, priv->chanlist[priv->current], value);
|
||||
if (priv->cb != NULL)
|
||||
{
|
||||
/* Give the ADC data to the ADC driver. The ADC receive method
|
||||
* accepts 3 parameters:
|
||||
*
|
||||
* 1) The first is the ADC device instance for this ADC block.
|
||||
* 2) The second is the channel number for the data, and
|
||||
* 3) The third is the converted data for the channel.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(priv->cb->au_receive != NULL);
|
||||
priv->cb->au_receive(dev, priv->chanlist[priv->current], value);
|
||||
}
|
||||
|
||||
/* Set the channel number of the next channel that will complete conversion */
|
||||
|
||||
@ -1272,7 +1304,8 @@ struct adc_dev_s *efm32_adcinitialize(int intf, const uint8_t *chanlist, int nch
|
||||
|
||||
/* Configure the selected ADC */
|
||||
|
||||
priv = dev->ad_priv;
|
||||
priv = dev->ad_priv;
|
||||
priv->cb = NULL;
|
||||
|
||||
DEBUGASSERT(nchannels <= ADC_MAX_SAMPLES);
|
||||
priv->nchannels = nchannels;
|
||||
|
@ -2,8 +2,9 @@
|
||||
* arch/arm/src/lpc17xx/lpc17_adc.c
|
||||
*
|
||||
* Copyright (C) 2011 Li Zhuoyi. All rights reserved.
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Li Zhuoyi <lzyy.cn@gmail.com>
|
||||
* History: 0.1 2011-08-05 initial version
|
||||
* Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
@ -50,6 +51,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
@ -87,6 +89,7 @@
|
||||
|
||||
struct up_dev_s
|
||||
{
|
||||
FAR const struct adc_callback_s *cb;
|
||||
uint8_t mask;
|
||||
uint32_t sps;
|
||||
int irq;
|
||||
@ -98,8 +101,12 @@ struct up_dev_s
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static void adc_receive(FAR struct up_dev_s *priv, uint8_t ch, int32_t data);
|
||||
|
||||
/* ADC methods */
|
||||
|
||||
static int adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback);
|
||||
static void adc_reset(FAR struct adc_dev_s *dev);
|
||||
static int adc_setup(FAR struct adc_dev_s *dev);
|
||||
static void adc_shutdown(FAR struct adc_dev_s *dev);
|
||||
@ -113,6 +120,7 @@ static int adc_interrupt(int irq, void *context);
|
||||
|
||||
static const struct adc_ops_s g_adcops =
|
||||
{
|
||||
.ao_bind = adc_bind,
|
||||
.ao_reset = adc_reset,
|
||||
.ao_setup = adc_setup,
|
||||
.ao_shutdown = adc_shutdown,
|
||||
@ -137,6 +145,46 @@ static struct adc_dev_s g_adcdev =
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_receive
|
||||
*
|
||||
* Description:
|
||||
* Provide received ADC dat to the upper-half driver.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void adc_receive(FAR struct up_dev_s *priv, uint8_t ch, int32_t data)
|
||||
{
|
||||
/* Verify that the upper-half driver has bound its callback functions. */
|
||||
|
||||
if (priv->cb != NULL)
|
||||
{
|
||||
/* Perform the data received callback */
|
||||
|
||||
DEBUGASSERT(priv->cb->au_receive != NULL);
|
||||
priv->cb->au_receive(&g_adcdev, ch, data);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_bind
|
||||
*
|
||||
* Description:
|
||||
* Bind the upper-half driver callbacks to the lower-half implementation. This
|
||||
* must be called early in order to receive ADC event notifications.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback)
|
||||
{
|
||||
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
priv->cb = callback;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_reset
|
||||
*
|
||||
@ -384,7 +432,7 @@ static int adc_interrupt(int irq, void *context)
|
||||
{
|
||||
value = priv->buf[ch] / priv->count[ch];
|
||||
value <<= 15;
|
||||
adc_receive(&g_adcdev, ch, value);
|
||||
adc_receive(priv, ch, value);
|
||||
priv->buf[ch] = 0;
|
||||
priv->count[ch] = 0;
|
||||
}
|
||||
@ -409,7 +457,7 @@ static int adc_interrupt(int irq, void *context)
|
||||
{
|
||||
value = priv->buf[ch] / priv->count[ch];
|
||||
value <<= 15;
|
||||
adc_receive(&g_adcdev, ch, value);
|
||||
adc_receive(priv, ch, value);
|
||||
priv->buf[ch] = 0;
|
||||
priv->count[ch] = 0;
|
||||
}
|
||||
@ -446,7 +494,7 @@ static int adc_interrupt(int irq, void *context)
|
||||
#else /* CONFIG_ADC_WORKER_THREAD */
|
||||
if ((regVal) & (1 << 31))
|
||||
{
|
||||
adc_receive(&g_adcdev, 0, (regVal >> 4) & 0xFFF);
|
||||
adc_receive(priv, 0, (regVal >> 4) & 0xFFF);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ADC_WORKER_THREAD */
|
||||
@ -473,7 +521,7 @@ static int adc_interrupt(int irq, void *context)
|
||||
#else /* CONFIG_ADC_WORKER_THREAD */
|
||||
if ((regVal) & (1 << 31))
|
||||
{
|
||||
adc_receive(&g_adcdev, 1, (regVal >> 4) & 0xFFF);
|
||||
adc_receive(priv, 1, (regVal >> 4) & 0xFFF);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ADC_WORKER_THREAD */
|
||||
@ -500,7 +548,7 @@ static int adc_interrupt(int irq, void *context)
|
||||
#else /* CONFIG_ADC_WORKER_THREAD */
|
||||
if ((regVal) & (1 << 31))
|
||||
{
|
||||
adc_receive(&g_adcdev, 2, (regVal >> 4) & 0xFFF);
|
||||
adc_receive(priv, 2, (regVal >> 4) & 0xFFF);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ADC_WORKER_THREAD */
|
||||
@ -512,7 +560,7 @@ static int adc_interrupt(int irq, void *context)
|
||||
regVal = getreg32(LPC17_ADC_DR3);
|
||||
if ((regVal) & (1 << 31))
|
||||
{
|
||||
adc_receive(&g_adcdev, 3, (regVal >> 4) & 0xFFF);
|
||||
adc_receive(priv, 3, (regVal >> 4) & 0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
@ -521,7 +569,7 @@ static int adc_interrupt(int irq, void *context)
|
||||
regVal = getreg32(LPC17_ADC_DR4);
|
||||
if ((regVal) & (1 << 31))
|
||||
{
|
||||
adc_receive(&g_adcdev, 4, (regVal >> 4) & 0xFFF);
|
||||
adc_receive(priv, 4, (regVal >> 4) & 0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,7 +578,7 @@ static int adc_interrupt(int irq, void *context)
|
||||
regVal = getreg32(LPC17_ADC_DR5);
|
||||
if ((regVal) & (1 << 31))
|
||||
{
|
||||
adc_receive(&g_adcdev, 5, (regVal >> 4) & 0xFFF);
|
||||
adc_receive(priv, 5, (regVal >> 4) & 0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
@ -539,7 +587,7 @@ static int adc_interrupt(int irq, void *context)
|
||||
regVal = getreg32(LPC17_ADC_DR6);
|
||||
if ((regVal) & (1 << 31))
|
||||
{
|
||||
adc_receive(&g_adcdev, 6, (regVal >> 4) & 0xFFF);
|
||||
adc_receive(priv, 6, (regVal >> 4) & 0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
@ -548,7 +596,7 @@ static int adc_interrupt(int irq, void *context)
|
||||
regVal = getreg32(LPC17_ADC_DR7);
|
||||
if ((regVal) & (1 << 31))
|
||||
{
|
||||
adc_receive(&g_adcdev, 7, (regVal >> 4) & 0xFFF);
|
||||
adc_receive(priv, 7, (regVal >> 4) & 0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,9 @@
|
||||
* Ported from from the LPC17 version:
|
||||
*
|
||||
* Copyright(C) 2011 Li Zhuoyi. All rights reserved.
|
||||
* Copyright(C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Li Zhuoyi <lzyy.cn@gmail.com>
|
||||
* History: 0.1 2011-08-05 initial version
|
||||
* Gregory Nutt
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
@ -55,6 +56,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
@ -112,6 +114,7 @@
|
||||
|
||||
struct up_dev_s
|
||||
{
|
||||
FAR const struct adc_callback_s *cb;
|
||||
uint8_t mask;
|
||||
uint8_t mask_int;
|
||||
uint32_t freq;
|
||||
@ -126,6 +129,8 @@ struct up_dev_s
|
||||
|
||||
/* ADC methods */
|
||||
|
||||
static int adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback);
|
||||
static void adc_reset(FAR struct adc_dev_s *dev);
|
||||
static int adc_setup(FAR struct adc_dev_s *dev);
|
||||
static void adc_shutdown(FAR struct adc_dev_s *dev);
|
||||
@ -139,6 +144,7 @@ static int adc_interrupt(int irq, void *context);
|
||||
|
||||
static const struct adc_ops_s g_adcops =
|
||||
{
|
||||
.ao_bind = adc_bind,
|
||||
.ao_reset = adc_reset,
|
||||
.ao_setup = adc_setup,
|
||||
.ao_shutdown = adc_shutdown,
|
||||
@ -166,6 +172,25 @@ static struct adc_dev_s g_adcdev =
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_bind
|
||||
*
|
||||
* Description:
|
||||
* Bind the upper-half driver callbacks to the lower-half implementation. This
|
||||
* must be called early in order to receive ADC event notifications.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback)
|
||||
{
|
||||
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
priv->cb = callback;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_reset
|
||||
*
|
||||
@ -454,8 +479,20 @@ static int adc_interrupt(int irq, void *context)
|
||||
{
|
||||
if (priv->mask & (1 << i))
|
||||
{
|
||||
int32_t data;
|
||||
|
||||
regval = getreg32(LPC43_ADC0_DR(i));
|
||||
adc_receive(&g_adcdev, i,(regval&ADC_DR_VVREF_MASK)>>ADC_DR_VVREF_SHIFT);
|
||||
data = (regval & ADC_DR_VVREF_MASK) >> ADC_DR_VVREF_SHIFT;
|
||||
|
||||
/* Verify that the upper-half driver has bound its callback functions */
|
||||
|
||||
if (priv->cb != NULL)
|
||||
{
|
||||
/* Perform the data received callback */
|
||||
|
||||
DEBUGASSERT(priv->cb->au_receive != NULL);
|
||||
priv->cb->au_receive(&g_adcdev, i, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
@ -378,6 +379,7 @@
|
||||
|
||||
struct sam_adc_s
|
||||
{
|
||||
FAR const struct adc_callback_s *cb;
|
||||
sem_t exclsem; /* Supports exclusive access to the ADC interface */
|
||||
bool initialized; /* The ADC driver is already initialized */
|
||||
uint32_t frequency; /* ADC clock frequency */
|
||||
@ -446,6 +448,8 @@ static int sam_adc_interrupt(int irq, void *context);
|
||||
/* ADC methods */
|
||||
|
||||
#ifdef SAMA5_ADC_HAVE_CHANNELS
|
||||
static int sam_adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback);
|
||||
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);
|
||||
@ -477,6 +481,7 @@ static void sam_adc_channels(struct sam_adc_s *priv);
|
||||
|
||||
static const struct adc_ops_s g_adcops =
|
||||
{
|
||||
.ao_bind = sam_adc_bind,
|
||||
.ao_reset = sam_adc_reset,
|
||||
.ao_setup = sam_adc_setup,
|
||||
.ao_shutdown = sam_adc_shutdown,
|
||||
@ -664,9 +669,15 @@ static void sam_adc_dmadone(void *arg)
|
||||
chan = (int)((*buffer & ADC_LCDR_CHANB_MASK) >> ADC_LCDR_CHANB_SHIFT);
|
||||
sample = ((*buffer & ADC_LCDR_DATA_MASK) >> ADC_LCDR_DATA_SHIFT);
|
||||
|
||||
/* And give the sample data to the ADC upper half */
|
||||
/* Verify that the upper-half driver has bound its callback functions */
|
||||
|
||||
(void)adc_receive(priv->dev, chan, sample);
|
||||
if (priv->cb != NULL)
|
||||
{
|
||||
/* Give the sample data to the ADC upper half */
|
||||
|
||||
DEBUGASSERT(priv->cb->au_receive != NULL);
|
||||
priv->cb->au_receive(priv->dev, chan, sample);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -858,7 +869,17 @@ static void sam_adc_endconversion(void *arg)
|
||||
/* Read the ADC sample and pass it to the upper half */
|
||||
|
||||
regval = sam_adc_getreg(priv, SAM_ADC_CDR(chan));
|
||||
(void)adc_receive(priv->dev, chan, regval & ADC_CDR_DATA_MASK);
|
||||
|
||||
/* Verify that the upper-half driver has bound its callback functions */
|
||||
|
||||
if (priv->cb != NULL)
|
||||
{
|
||||
/* Perform the data received callback */
|
||||
|
||||
DEBUGASSERT(priv->cb->au_receive != NULL);
|
||||
priv->cb->au_receive(priv->dev, chan, regval & ADC_CDR_DATA_MASK);
|
||||
}
|
||||
|
||||
pending &= ~bit;
|
||||
}
|
||||
}
|
||||
@ -954,6 +975,26 @@ static int sam_adc_interrupt(int irq, void *context)
|
||||
/****************************************************************************
|
||||
* ADC methods
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_adc_bind
|
||||
*
|
||||
* Description:
|
||||
* Bind the upper-half driver callbacks to the lower-half implementation. This
|
||||
* must be called early in order to receive ADC event notifications.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int sam_adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback)
|
||||
{
|
||||
struct sam_adc_s *priv = (struct sam_adc_s *)dev->ad_priv;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
priv->cb = callback;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_adc_reset
|
||||
*
|
||||
@ -1980,6 +2021,7 @@ struct adc_dev_s *sam_adc_initialize(void)
|
||||
/* Initialize the private ADC device data structure */
|
||||
|
||||
sem_init(&priv->exclsem, 0, 1);
|
||||
priv->cb = NULL;
|
||||
priv->dev = &g_adcdev;
|
||||
|
||||
#ifdef CONFIG_SAMA5_ADC_DMA
|
||||
|
@ -272,6 +272,7 @@
|
||||
|
||||
struct stm32_dev_s
|
||||
{
|
||||
FAR const struct adc_callback_s *cb;
|
||||
uint8_t irq; /* Interrupt generated by this ADC block */
|
||||
uint8_t nchannels; /* Number of channels */
|
||||
uint8_t cchannels; /* Number of configured channels */
|
||||
@ -364,6 +365,8 @@ static int adc123_interrupt(int irq, FAR void *context);
|
||||
|
||||
/* ADC Driver Methods */
|
||||
|
||||
static int adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback);
|
||||
static void adc_reset(FAR struct adc_dev_s *dev);
|
||||
static int adc_setup(FAR struct adc_dev_s *dev);
|
||||
static void adc_shutdown(FAR struct adc_dev_s *dev);
|
||||
@ -412,6 +415,7 @@ static void adc_startconv(FAR struct stm32_dev_s *priv, bool enable);
|
||||
|
||||
static const struct adc_ops_s g_adcops =
|
||||
{
|
||||
.ao_bind = adc_bind,
|
||||
#if defined(CONFIG_STM32_STM32L15XX) && \
|
||||
(STM32_CFGR_PLLSRC != 0 || STM32_SYSCLK_SW != RCC_CFGR_SW_HSI)
|
||||
.ao_reset = adc_reset_hsi_disable,
|
||||
@ -1660,6 +1664,25 @@ static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg)
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_bind
|
||||
*
|
||||
* Description:
|
||||
* Bind the upper-half driver callbacks to the lower-half implementation. This
|
||||
* must be called early in order to receive ADC event notifications.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback)
|
||||
{
|
||||
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
priv->cb = callback;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_reset
|
||||
*
|
||||
@ -2702,15 +2725,21 @@ static int adc_interrupt(FAR struct adc_dev_s *dev)
|
||||
|
||||
data = adc_getreg(priv, STM32_ADC_DR_OFFSET) & ADC_DR_RDATA_MASK;
|
||||
|
||||
/* Give the ADC data to the ADC driver. adc_receive() accepts 3
|
||||
* parameters:
|
||||
*
|
||||
* 1) The first is the ADC device instance for this ADC block.
|
||||
* 2) The second is the channel number for the data, and
|
||||
* 3) The third is the converted data for the channel.
|
||||
*/
|
||||
/* Verify that the upper-half driver has bound its callback functions */
|
||||
|
||||
adc_receive(dev, priv->chanlist[priv->current], data);
|
||||
if (priv->cb != NULL)
|
||||
{
|
||||
/* Give the ADC data to the ADC driver. The ADC receive() method
|
||||
* accepts 3 parameters:
|
||||
*
|
||||
* 1) The first is the ADC device instance for this ADC block.
|
||||
* 2) The second is the channel number for the data, and
|
||||
* 3) The third is the converted data for the channel.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(priv->cb->au_receive != NULL);
|
||||
priv->cb->au_receive(dev, priv->chanlist[priv->current], data);
|
||||
}
|
||||
|
||||
/* Set the channel number of the next channel that will complete
|
||||
* conversion.
|
||||
@ -2995,6 +3024,7 @@ struct adc_dev_s *stm32_adcinitialize(int intf, FAR const uint8_t *chanlist,
|
||||
|
||||
DEBUGASSERT(cchannels <= ADC_MAX_SAMPLES);
|
||||
|
||||
priv->cb = NULL;
|
||||
priv->cchannels = cchannels;
|
||||
|
||||
memcpy(priv->chanlist, chanlist, cchannels);
|
||||
|
@ -125,32 +125,32 @@
|
||||
|
||||
struct tiva_adc_step_cfg_s
|
||||
{
|
||||
uint8_t adc; /* Parent peripheral */
|
||||
uint8_t sse; /* Parent sample sequencer (SSE) */
|
||||
uint8_t step; /* Which step in the sequencer */
|
||||
uint8_t shold; /* Sample and hold time */
|
||||
uint8_t flags; /* Last step? Interrupt enabled?
|
||||
* Internal temperature sensor? */
|
||||
uint8_t ain; /* Which analog input */
|
||||
uint8_t adc; /* Parent peripheral */
|
||||
uint8_t sse; /* Parent sample sequencer (SSE) */
|
||||
uint8_t step; /* Which step in the sequencer */
|
||||
uint8_t shold; /* Sample and hold time */
|
||||
uint8_t flags; /* Last step? Interrupt enabled?
|
||||
* Internal temperature sensor? */
|
||||
uint8_t ain; /* Which analog input */
|
||||
};
|
||||
|
||||
/* Sample Sequencer configuration options */
|
||||
|
||||
struct tiva_adc_sse_cfg_s
|
||||
{
|
||||
uint8_t priority; /* Conversion priority, 0-3 no duplicates */
|
||||
uint8_t trigger; /* Trigger source */
|
||||
uint8_t priority; /* Conversion priority, 0-3 no duplicates */
|
||||
uint8_t trigger; /* Trigger source */
|
||||
};
|
||||
|
||||
/* ADC peripheral configuration options */
|
||||
|
||||
struct tiva_adc_cfg_s
|
||||
{
|
||||
uint8_t adc; /* ADC peripheral number */
|
||||
bool sse[4]; /* active SSEs in a bitmask */
|
||||
struct tiva_adc_sse_cfg_s ssecfg[4]; /* SSE configuration */
|
||||
uint8_t steps; /* Size of the stepcfg array */
|
||||
struct tiva_adc_step_cfg_s *stepcfg; /* Step configuration array */
|
||||
uint8_t adc; /* ADC peripheral number */
|
||||
bool sse[4]; /* active SSEs in a bitmask */
|
||||
struct tiva_adc_sse_cfg_s ssecfg[4]; /* SSE configuration */
|
||||
uint8_t steps; /* Size of the stepcfg array */
|
||||
struct tiva_adc_step_cfg_s *stepcfg; /* Step configuration array */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1,8 +1,10 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/tiva/tiva_adclow.c
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2015 TRD2 Inc. All rights reserved.
|
||||
* Author: Calvin Maguranis <calvin.maguranis@trd2inc.com>
|
||||
* Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References:
|
||||
*
|
||||
@ -67,8 +69,8 @@
|
||||
#include <stdbool.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
@ -135,6 +137,8 @@
|
||||
|
||||
/* Upper level ADC driver ***************************************************/
|
||||
|
||||
static int tiva_adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback);
|
||||
static void tiva_adc_reset(struct adc_dev_s *dev);
|
||||
static int tiva_adc_setup(struct adc_dev_s *dev);
|
||||
static void tiva_adc_shutdown(struct adc_dev_s *dev);
|
||||
@ -149,6 +153,7 @@ static int tiva_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg);
|
||||
|
||||
static const struct adc_ops_s g_adcops =
|
||||
{
|
||||
.ao_bind = tiva_adc_bind,
|
||||
.ao_reset = tiva_adc_reset,
|
||||
.ao_setup = tiva_adc_setup,
|
||||
.ao_shutdown = tiva_adc_shutdown,
|
||||
@ -163,6 +168,7 @@ static const struct adc_ops_s g_adcops =
|
||||
struct tiva_adc_s
|
||||
{
|
||||
struct adc_dev_s *dev;
|
||||
const struct adc_callback_s *cb;
|
||||
bool cfg; /* Configuration state */
|
||||
bool ena; /* Operation state */
|
||||
uint8_t devno; /* ADC device number */
|
||||
@ -373,6 +379,25 @@ static void tiva_adc_irqinitialize(struct tiva_adc_cfg_s *cfg)
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tiva_adc_bind
|
||||
*
|
||||
* Description:
|
||||
* Bind the upper-half driver callbacks to the lower-half implementation. This
|
||||
* must be called early in order to receive ADC event notifications.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int tiva_adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback)
|
||||
{
|
||||
struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
priv->cb = callback;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tiva_adc_reset
|
||||
*
|
||||
@ -559,11 +584,20 @@ static int tiva_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg)
|
||||
|
||||
fifo_count = tiva_adc_sse_data(priv->devno, sse, buf);
|
||||
|
||||
for (i = 0; i < fifo_count; ++i)
|
||||
/* Verify that the upper-half driver has bound its callback functions */
|
||||
|
||||
if (priv->cb != NULL)
|
||||
{
|
||||
(void)adc_receive(dev,
|
||||
tiva_adc_get_ain(priv->devno, sse, i),
|
||||
buf[i]);
|
||||
DEBUGASSERT(priv->cb->au_receive != NULL);
|
||||
|
||||
for (i = 0; i < fifo_count; ++i)
|
||||
{
|
||||
/* Perform the data received callback */
|
||||
|
||||
priv->cb->au_receive(dev,
|
||||
tiva_adc_get_ain(priv->devno, sse, i),
|
||||
buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Release our lock on the ADC structure */
|
||||
@ -651,18 +685,28 @@ static void tiva_adc_read(void *arg)
|
||||
/* This is a serious error: indicates invalid pointer indirection
|
||||
* and should cause a full system stop.
|
||||
*/
|
||||
|
||||
alldbg("PANIC!!! Invalid ADC device number given %d\n", sse->adc);
|
||||
PANIC();
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < fifo_count; ++i)
|
||||
/* Verify that the upper-half driver has bound its callback functions */
|
||||
|
||||
if (priv->cb != NULL)
|
||||
{
|
||||
(void)adc_receive(dev,
|
||||
tiva_adc_get_ain(sse->adc, sse->num, i),
|
||||
buf[i]);
|
||||
avdbg("AIN%d=0x%04x\n",
|
||||
tiva_adc_get_ain(sse->adc, sse->num, i), buf[i]);
|
||||
DEBUGASSERT(priv->cb->au_receive != NULL);
|
||||
|
||||
for (i = 0; i < fifo_count; ++i)
|
||||
{
|
||||
/* Perform the data received callback */
|
||||
|
||||
priv->cb->au_receive(dev,
|
||||
tiva_adc_get_ain(sse->adc, sse->num, i),
|
||||
buf[i]);
|
||||
avdbg("AIN%d = 0x%04x\n",
|
||||
tiva_adc_get_ain(sse->adc, sse->num, i), buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Exit, re-enabling ADC interrupts */
|
||||
@ -858,6 +902,7 @@ int tiva_adc_initialize(const char *devpath, struct tiva_adc_cfg_s *cfg,
|
||||
/* Now we are initialized */
|
||||
|
||||
adc->ena = true;
|
||||
adc->cb = NULL;
|
||||
|
||||
#ifdef CONFIG_DEBUG_ANALOG
|
||||
tiva_adc_runtimeobj_vals();
|
||||
|
@ -1,9 +1,10 @@
|
||||
/****************************************************************************
|
||||
* drivers/analog/adc.c
|
||||
*
|
||||
* Copyright (C) 2008-2009, 2016 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2011 Li Zhuoyi. All rights reserved.
|
||||
* Author: Li Zhuoyi <lzyy.cn@gmail.com>
|
||||
* History: 0.1 2011-08-04 initial version
|
||||
* Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Derived from drivers/can.c
|
||||
*
|
||||
@ -70,12 +71,14 @@ static int adc_close(FAR struct file *filep);
|
||||
static ssize_t adc_read(FAR struct file *fielp, FAR char *buffer,
|
||||
size_t buflen);
|
||||
static int adc_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||
static int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch,
|
||||
int32_t data);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct file_operations adc_fops =
|
||||
static const struct file_operations g_adc_fops =
|
||||
{
|
||||
adc_open, /* open */
|
||||
adc_close, /* close */
|
||||
@ -88,6 +91,11 @@ static const struct file_operations adc_fops =
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct adc_callback_s g_adc_callback =
|
||||
{
|
||||
adc_receive /* au_receive */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@ -361,15 +369,11 @@ static int adc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_receive
|
||||
****************************************************************************/
|
||||
|
||||
int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch, int32_t data)
|
||||
static int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch, int32_t data)
|
||||
{
|
||||
FAR struct adc_fifo_s *fifo = &dev->ad_recv;
|
||||
int nexttail;
|
||||
@ -408,12 +412,30 @@ int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch, int32_t data)
|
||||
return err;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_register
|
||||
****************************************************************************/
|
||||
|
||||
int adc_register(FAR const char *path, FAR struct adc_dev_s *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(path != NULL && dev != NULL);
|
||||
|
||||
/* Bind the upper-half callbacks to the lower half ADC driver */
|
||||
|
||||
DEBUGASSERT(dev->ad_ops != NULL && dev->ad_ops->ao_bind != NULL);
|
||||
ret = dev->ad_ops->ao_bind(dev, &g_adc_callback);
|
||||
if (ret < 0)
|
||||
{
|
||||
adbg("ERROR: Failed to bind callbacks: %d\n", ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initialize the ADC device structure */
|
||||
|
||||
dev->ad_ocount = 0;
|
||||
@ -421,7 +443,19 @@ int adc_register(FAR const char *path, FAR struct adc_dev_s *dev)
|
||||
sem_init(&dev->ad_recv.af_sem, 0, 0);
|
||||
sem_init(&dev->ad_closesem, 0, 1);
|
||||
|
||||
/* Reset the ADC hardware */
|
||||
|
||||
DEBUGASSERT(dev->ad_ops->ao_reset != NULL);
|
||||
dev->ad_ops->ao_reset(dev);
|
||||
|
||||
return register_driver(path, &adc_fops, 0444, dev);
|
||||
/* Register the ADC character driver */
|
||||
|
||||
ret = register_driver(path, &g_adc_fops, 0444, dev);
|
||||
if (ret < 0)
|
||||
{
|
||||
sem_destroy(&dev->ad_recv.af_sem);
|
||||
sem_destroy(&dev->ad_closesem);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
/************************************************************************************
|
||||
* arch/drivers/analog/ads1255.c
|
||||
*
|
||||
* Copyright (C) 2010, 2016 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2011 Li Zhuoyi. All rights reserved.
|
||||
* Author: Li Zhuoyi <lzyy.cn@gmail.com>
|
||||
* History: 0.1 2011-08-05 initial version
|
||||
* 0.2 2011-08-25 fix bug in g_adcdev (cd_ops -> ad_ops,cd_priv -> ad_priv)
|
||||
* Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
@ -47,6 +47,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
@ -105,8 +106,9 @@
|
||||
* ad_private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct up_dev_s
|
||||
struct ads1255_dev_s
|
||||
{
|
||||
FAR const struct adc_callback_s *cb;
|
||||
uint8_t channel;
|
||||
uint32_t sps;
|
||||
uint8_t pga;
|
||||
@ -123,6 +125,8 @@ struct up_dev_s
|
||||
|
||||
/* ADC methods */
|
||||
|
||||
static int adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback);
|
||||
static void adc_reset(FAR struct adc_dev_s *dev);
|
||||
static int adc_setup(FAR struct adc_dev_s *dev);
|
||||
static void adc_shutdown(FAR struct adc_dev_s *dev);
|
||||
@ -136,14 +140,15 @@ static int adc_interrupt(int irq, void *context);
|
||||
|
||||
static const struct adc_ops_s g_adcops =
|
||||
{
|
||||
.ao_reset = adc_reset, /* ao_reset */
|
||||
.ao_setup = adc_setup, /* ao_setup */
|
||||
.ao_bind = adc_bind, /* ao_bind */
|
||||
.ao_reset = adc_reset, /* ao_reset */
|
||||
.ao_setup = adc_setup, /* ao_setup */
|
||||
.ao_shutdown = adc_shutdown, /* ao_shutdown */
|
||||
.ao_rxint = adc_rxint, /* ao_rxint */
|
||||
.ao_ioctl = adc_ioctl /* ao_read */
|
||||
.ao_rxint = adc_rxint, /* ao_rxint */
|
||||
.ao_ioctl = adc_ioctl /* ao_read */
|
||||
};
|
||||
|
||||
static struct up_dev_s g_adcpriv =
|
||||
static struct ads1255_dev_s g_adcpriv =
|
||||
{
|
||||
.mux = (const uint8_t [])
|
||||
{
|
||||
@ -190,16 +195,44 @@ static uint8_t getspsreg(uint16_t sps)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* ad_private Functions
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_bind
|
||||
*
|
||||
* Description:
|
||||
* Bind the upper-half driver callbacks to the lower-half implementation. This
|
||||
* must be called early in order to receive ADC event notifications.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int adc_bind(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback)
|
||||
{
|
||||
FAR struct ads1255_dev_s *priv = (FAR struct ads1255_dev_s *)dev->ad_priv;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
priv->cb = callback;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_reset
|
||||
*
|
||||
* Description:
|
||||
* Reset the ADC device. Called early to initialize the hardware. This
|
||||
* is called, before ao_setup() and on error conditions.
|
||||
*
|
||||
****************************************************************************/
|
||||
/* Reset the ADC device. Called early to initialize the hardware. This
|
||||
* is called, before ao_setup() and on error conditions.
|
||||
*/
|
||||
|
||||
static void adc_reset(FAR struct adc_dev_s *dev)
|
||||
{
|
||||
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
|
||||
FAR struct spi_dev_s *spi = priv->spi;
|
||||
FAR struct ads1255_dev_s *priv = (FAR struct ads1255_dev_s *)dev->ad_priv;
|
||||
FAR struct spi_dev_s *spi;
|
||||
|
||||
DEBUGASSERT(priv != NULL && priv->spi != NULL);
|
||||
spi = priv->spi;
|
||||
|
||||
SPI_SETMODE(spi, SPIDEV_MODE1);
|
||||
SPI_SETBITS(spi, 8);
|
||||
@ -213,18 +246,27 @@ static void adc_reset(FAR struct adc_dev_s *dev)
|
||||
SPI_SELECT(spi, priv->devno, false);
|
||||
}
|
||||
|
||||
/* Configure the ADC. This method is called the first time that the ADC
|
||||
* device is opened. This will occur when the port is first opened.
|
||||
* This setup includes configuring and attaching ADC interrupts. Interrupts
|
||||
* are all disabled upon return.
|
||||
*/
|
||||
/****************************************************************************
|
||||
* Name: adc_setup
|
||||
*
|
||||
* Description:
|
||||
* Configure the ADC. This method is called the first time that the ADC
|
||||
* device is opened. This will occur when the port is first opened.
|
||||
* This setup includes configuring and attaching ADC interrupts. Interrupts
|
||||
* are all disabled upon return.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int adc_setup(FAR struct adc_dev_s *dev)
|
||||
static int adc_setup(FAR struct adc_dev_s *dev)
|
||||
{
|
||||
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
|
||||
FAR struct spi_dev_s *spi = priv->spi;
|
||||
int ret = irq_attach(priv->irq, adc_interrupt);
|
||||
FAR struct ads1255_dev_s *priv = (FAR struct ads1255_dev_s *)dev->ad_priv;
|
||||
FAR struct spi_dev_s *spi;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(priv != NULL && priv->spi != NULL);
|
||||
spi = priv->spi;
|
||||
|
||||
ret = irq_attach(priv->irq, adc_interrupt);
|
||||
if (ret == OK)
|
||||
{
|
||||
SPI_SELECT(spi, priv->devno, true);
|
||||
@ -251,22 +293,39 @@ static int adc_setup(FAR struct adc_dev_s *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Disable the ADC. This method is called when the ADC device is closed.
|
||||
* This method reverses the operation the setup method.
|
||||
*/
|
||||
/****************************************************************************
|
||||
* Name: adc_shutdown
|
||||
*
|
||||
* Description:
|
||||
* Disable the ADC. This method is called when the ADC device is closed.
|
||||
* This method reverses the operation the setup method.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void adc_shutdown(FAR struct adc_dev_s *dev)
|
||||
{
|
||||
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
|
||||
FAR struct ads1255_dev_s *priv = (FAR struct ads1255_dev_s *)dev->ad_priv;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
up_disable_irq(priv->irq);
|
||||
irq_detach(priv->irq);
|
||||
}
|
||||
|
||||
/* Call to enable or disable RX interrupts */
|
||||
/****************************************************************************
|
||||
* Name: adc_rxint
|
||||
*
|
||||
* Description:
|
||||
* Call to enable or disable RX interrupts
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void adc_rxint(FAR struct adc_dev_s *dev, bool enable)
|
||||
{
|
||||
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
|
||||
FAR struct ads1255_dev_s *priv = (FAR struct ads1255_dev_s *)dev->ad_priv;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
up_enable_irq(priv->irq);
|
||||
@ -277,21 +336,42 @@ static void adc_rxint(FAR struct adc_dev_s *dev, bool enable)
|
||||
}
|
||||
}
|
||||
|
||||
/* All ioctl calls will be routed through this method */
|
||||
/****************************************************************************
|
||||
* Name: adc_ioctl
|
||||
*
|
||||
* Description:
|
||||
* All ioctl calls will be routed through this method
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg)
|
||||
static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg)
|
||||
{
|
||||
dbg("Fix me:Not Implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_interrupt
|
||||
*
|
||||
* Description:
|
||||
* ADC interrupt handler
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int adc_interrupt(int irq, void *context)
|
||||
{
|
||||
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv;
|
||||
FAR struct spi_dev_s *spi = priv->spi;
|
||||
FAR struct ads1255_dev_s *priv = (FAR struct ads1255_dev_s *)g_adcdev.ad_priv;
|
||||
FAR struct spi_dev_s *spi;
|
||||
unsigned char buf[4];
|
||||
unsigned char ch;
|
||||
|
||||
DEBUGASSERT(priv != NULL && priv->spi != NULL);
|
||||
spi = priv->spi;
|
||||
|
||||
/* REVISIT: Cannot perform SPI operations from an interrupt handler!
|
||||
* Need to use the high priority work queue.
|
||||
*/
|
||||
|
||||
SPI_SELECT(spi, priv->devno, true);
|
||||
SPI_SEND(spi, ADS125X_RDATA);
|
||||
up_udelay(10);
|
||||
@ -316,7 +396,16 @@ static int adc_interrupt(int irq, void *context)
|
||||
SPI_SEND(spi, ADS125X_WAKEUP);
|
||||
SPI_SELECT(spi, priv->devno, false);
|
||||
|
||||
adc_receive(&g_adcdev, priv->channel, *(int32_t *)buf);
|
||||
/* Verify that the upper-half driver has bound its callback functions */
|
||||
|
||||
if (priv->cb != NULL)
|
||||
{
|
||||
/* Perform the data received callback */
|
||||
|
||||
DEBUGASSERT(priv->cb->au_receive != NULL);
|
||||
priv->cb->au_receive(&g_adcdev, priv->channel, *(int32_t *)buf);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -341,10 +430,13 @@ static int adc_interrupt(int irq, void *context)
|
||||
FAR struct adc_dev_s *up_ads1255initialize(FAR struct spi_dev_s *spi,
|
||||
unsigned int devno)
|
||||
{
|
||||
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv;
|
||||
FAR struct ads1255_dev_s *priv = (FAR struct ads1255_dev_s *)g_adcdev.ad_priv;
|
||||
|
||||
DEBUGASSERT(spi != NULL);
|
||||
|
||||
/* Driver state data */
|
||||
|
||||
priv->cb = NULL;
|
||||
priv->spi = spi;
|
||||
priv->devno = devno;
|
||||
return &g_adcdev;
|
||||
|
@ -75,6 +75,27 @@
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
************************************************************************************/
|
||||
/* These are callbacks to notify the upper-half driver of ADC events */
|
||||
|
||||
struct adc_dev_s;
|
||||
struct adc_callback_s
|
||||
{
|
||||
/* This method is called from the lower half, platform-specific ADC logic when
|
||||
* new ADC sample data is available.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The ADC device structure that was previously registered by adc_register()
|
||||
* ch - And ID for the ADC channel number that generated the data
|
||||
* data - The actual converted data from the channel.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*/
|
||||
|
||||
CODE int (*au_receive)(FAR struct adc_dev_s *dev, uint8_t ch, int32_t data);
|
||||
};
|
||||
|
||||
/* This describes on ADC message */
|
||||
|
||||
struct adc_msg_s
|
||||
{
|
||||
@ -82,6 +103,8 @@ struct adc_msg_s
|
||||
int32_t am_data; /* ADC convert result (4 bytes) */
|
||||
} packed_struct;
|
||||
|
||||
/* This describes a FIFO of ADC messages */
|
||||
|
||||
struct adc_fifo_s
|
||||
{
|
||||
sem_t af_sem; /* Counting semaphore */
|
||||
@ -99,6 +122,13 @@ struct adc_fifo_s
|
||||
struct adc_dev_s;
|
||||
struct adc_ops_s
|
||||
{
|
||||
/* Bind the upper-half driver callbacks to the lower-half implementation. This
|
||||
* must be called early in order to receive ADC event notifications.
|
||||
*/
|
||||
|
||||
CODE int (*ao_bind)(FAR struct adc_dev_s *dev,
|
||||
FAR const struct adc_callback_s *callback);
|
||||
|
||||
/* Reset the ADC device. Called early to initialize the hardware. This
|
||||
* is called, before ao_setup() and on error conditions.
|
||||
*/
|
||||
@ -188,25 +218,6 @@ extern "C"
|
||||
|
||||
int adc_register(FAR const char *path, FAR struct adc_dev_s *dev);
|
||||
|
||||
/************************************************************************************
|
||||
* Name: adc_receive
|
||||
*
|
||||
* Description:
|
||||
* This function is called from the lower half, platform-specific ADC logic when
|
||||
* new ADC sample data is available.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The ADC device structure that was previously registered by adc_register()
|
||||
* ch - And ID for the ADC channel number that generated the data
|
||||
* data - The actualy converted data from the channel.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch, int32_t data);
|
||||
|
||||
/************************************************************************************
|
||||
* Platform-Independent "Lower Half" ADC Driver Interfaces
|
||||
************************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user