1
0
Fork 0
forked from nuttx/nuttx-update

Add ADC bind method to the EFM32 and LPC17xx ADC drivers

This commit is contained in:
Gregory Nutt 2016-05-26 11:57:18 -06:00
parent b630d48175
commit 9d6845b7ec
3 changed files with 86 additions and 15 deletions

View file

@ -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;

View file

@ -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:
*
@ -87,6 +88,7 @@
struct up_dev_s
{
FAR const struct adc_callback_s *cb;
uint8_t mask;
uint32_t sps;
int irq;
@ -100,6 +102,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);
@ -113,6 +117,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 +142,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
*
@ -384,7 +408,19 @@ static int adc_interrupt(int irq, void *context)
{
value = priv->buf[ch] / priv->count[ch];
value <<= 15;
adc_receive(&g_adcdev, ch, value);
/* 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, value);
}
priv->buf[ch] = 0;
priv->count[ch] = 0;
}
@ -596,6 +632,7 @@ static int adc_interrupt(int irq, void *context)
FAR struct adc_dev_s *lpc17_adcinitialize(void)
{
g_adcdev.cb = NULL;
return &g_adcdev;
}

View file

@ -140,11 +140,12 @@ 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 ads1255_dev_s g_adcpriv =