Check return from nxsem_wait_uninterruptible()

This commit is for all ADC/DAC drivers under arch/.
This commit is contained in:
Ouss4 2020-04-03 00:10:26 +01:00 committed by patacongo
parent 65739a38fb
commit 13b229a9eb
7 changed files with 273 additions and 137 deletions

View File

@ -109,8 +109,10 @@ struct lc823450_adc_inst_s
****************************************************************************/ ****************************************************************************/
static inline void lc823450_adc_clearirq(void); static inline void lc823450_adc_clearirq(void);
static inline void lc823450_adc_sem_wait(FAR struct lc823450_adc_inst_s *inst); static inline int lc823450_adc_sem_wait(
static inline void lc823450_adc_sem_post(FAR struct lc823450_adc_inst_s *inst); FAR struct lc823450_adc_inst_s *inst);
static inline void lc823450_adc_sem_post(
FAR struct lc823450_adc_inst_s *inst);
static int lc823450_adc_bind(FAR struct adc_dev_s *dev, static int lc823450_adc_bind(FAR struct adc_dev_s *dev,
FAR const struct adc_callback_s *callback); FAR const struct adc_callback_s *callback);
@ -118,7 +120,8 @@ static void lc823450_adc_reset(FAR struct adc_dev_s *dev);
static int lc823450_adc_setup(FAR struct adc_dev_s *dev); static int lc823450_adc_setup(FAR struct adc_dev_s *dev);
static void lc823450_adc_shutdown(FAR struct adc_dev_s *dev); static void lc823450_adc_shutdown(FAR struct adc_dev_s *dev);
static void lc823450_adc_rxint(FAR struct adc_dev_s *dev, bool enable); static void lc823450_adc_rxint(FAR struct adc_dev_s *dev, bool enable);
static int lc823450_adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg); static int lc823450_adc_ioctl(FAR struct adc_dev_s *dev, int cmd,
unsigned long arg);
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
@ -192,7 +195,6 @@ static void lc823450_adc_standby(int on)
/* disable clock */ /* disable clock */
modifyreg32(MCLKCNTAPB, MCLKCNTAPB_ADC_CLKEN, 0); modifyreg32(MCLKCNTAPB, MCLKCNTAPB_ADC_CLKEN, 0);
} }
else else
{ {
@ -225,6 +227,7 @@ static void lc823450_adc_start(FAR struct lc823450_adc_inst_s *inst)
uint32_t pclk; /* APB clock in Hz */ uint32_t pclk; /* APB clock in Hz */
uint8_t i; uint8_t i;
uint32_t div; uint32_t div;
int ret;
#ifdef CONFIG_ADC_POLLED #ifdef CONFIG_ADC_POLLED
irqstate_t flags; irqstate_t flags;
@ -261,7 +264,12 @@ static void lc823450_adc_start(FAR struct lc823450_adc_inst_s *inst)
while ((getreg32(rADCSTS) & rADCSTS_fADCMPL) == 0) while ((getreg32(rADCSTS) & rADCSTS_fADCMPL) == 0)
; ;
#else #else
nxsem_wait_uninterruptible(&inst->sem_isr); ret = nxsem_wait_uninterruptible(&inst->sem_isr);
if (ret < 0)
{
return;
}
#endif #endif
#ifdef CONFIG_ADC_POLLED #ifdef CONFIG_ADC_POLLED
@ -277,9 +285,9 @@ static void lc823450_adc_start(FAR struct lc823450_adc_inst_s *inst)
* *
****************************************************************************/ ****************************************************************************/
static inline void lc823450_adc_sem_wait(FAR struct lc823450_adc_inst_s *inst) static inline int lc823450_adc_sem_wait(FAR struct lc823450_adc_inst_s *inst)
{ {
nxsem_wait_uninterruptible(&inst->sem_excl); return nxsem_wait_uninterruptible(&inst->sem_excl);
} }
/**************************************************************************** /****************************************************************************
@ -290,7 +298,8 @@ static inline void lc823450_adc_sem_wait(FAR struct lc823450_adc_inst_s *inst)
* *
****************************************************************************/ ****************************************************************************/
static inline void lc823450_adc_sem_post(FAR struct lc823450_adc_inst_s *inst) static inline void lc823450_adc_sem_post(
FAR struct lc823450_adc_inst_s *inst)
{ {
nxsem_post(&inst->sem_excl); nxsem_post(&inst->sem_excl);
} }
@ -407,9 +416,15 @@ static void lc823450_adc_rxint(FAR struct adc_dev_s *dev, bool enable)
{ {
FAR struct lc823450_adc_inst_s *inst = FAR struct lc823450_adc_inst_s *inst =
(FAR struct lc823450_adc_inst_s *)dev->ad_priv; (FAR struct lc823450_adc_inst_s *)dev->ad_priv;
int ret;
ainfo("enable: %d\n", enable); ainfo("enable: %d\n", enable);
lc823450_adc_sem_wait(inst); ret = lc823450_adc_sem_wait(inst);
if (ret < 0)
{
return;
}
#ifndef CONFIG_ADC_POLLED #ifndef CONFIG_ADC_POLLED
if (enable) if (enable)
@ -448,7 +463,11 @@ static int lc823450_adc_ioctl(FAR struct adc_dev_s *dev, int cmd,
ainfo("cmd=%xh\n", cmd); ainfo("cmd=%xh\n", cmd);
lc823450_adc_sem_wait(priv); ret = lc823450_adc_sem_wait(priv);
if (ret < 0)
{
return ret;
}
switch (cmd) switch (cmd)
{ {
@ -534,7 +553,13 @@ FAR struct adc_dev_s *lc823450_adcinitialize(void)
nxsem_init(&inst->sem_isr, 0, 0); nxsem_init(&inst->sem_isr, 0, 0);
#endif #endif
lc823450_adc_sem_wait(inst); ret = lc823450_adc_sem_wait(inst);
if (ret < 0)
{
aerr("adc_register failed: %d\n", ret);
kmm_free(g_inst);
return NULL;
}
/* enable clock & unreset (include exitting standby mode) */ /* enable clock & unreset (include exitting standby mode) */
@ -586,9 +611,11 @@ FAR struct adc_dev_s *lc823450_adcinitialize(void)
* Name: lc823450_adc_receive * Name: lc823450_adc_receive
****************************************************************************/ ****************************************************************************/
int lc823450_adc_receive(FAR struct adc_dev_s *dev, FAR struct adc_msg_s *msg) int lc823450_adc_receive(FAR struct adc_dev_s *dev,
FAR struct adc_msg_s *msg)
{ {
uint8_t ch; uint8_t ch;
int ret;
FAR struct lc823450_adc_inst_s *inst = FAR struct lc823450_adc_inst_s *inst =
(FAR struct lc823450_adc_inst_s *)dev->ad_priv; (FAR struct lc823450_adc_inst_s *)dev->ad_priv;
@ -602,7 +629,12 @@ int lc823450_adc_receive(FAR struct adc_dev_s *dev, FAR struct adc_msg_s *msg)
return -EINVAL; return -EINVAL;
} }
lc823450_adc_sem_wait(inst); ret = lc823450_adc_sem_wait(inst);
if (ret < 0)
{
return ret;
}
lc823450_adc_standby(0); lc823450_adc_standby(0);
lc823450_adc_start(inst); lc823450_adc_start(inst);

View File

@ -1,4 +1,4 @@
/************************************************************************************ /****************************************************************************
* arch/arm/src/sama5/sam_adc.c * arch/arm/src/sama5/sam_adc.c
* *
* Copyright (C) 2013, 2014, 2017-2018 Gregory Nutt. All rights reserved. * Copyright (C) 2013, 2014, 2017-2018 Gregory Nutt. All rights reserved.
@ -41,7 +41,7 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
************************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Included Files * Included Files
@ -88,6 +88,7 @@
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/* Count the number of channels in use */ /* Count the number of channels in use */
#define SAMA5_CHAN0_INUSE 0 #define SAMA5_CHAN0_INUSE 0
@ -415,16 +416,17 @@ struct sam_adc_s
/* Debug stuff */ /* Debug stuff */
#ifdef CONFIG_SAMA5_ADC_REGDEBUG #ifdef CONFIG_SAMA5_ADC_REGDEBUG
bool wrlast; /* Last was a write */ bool wrlast; /* Last was a write */
uintptr_t addrlast; /* Last address */ uintptr_t addrlast; /* Last address */
uint32_t vallast; /* Last value */ uint32_t vallast; /* Last value */
int ntimes; /* Number of times */ int ntimes; /* Number of times */
#endif #endif
}; };
/**************************************************************************** /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
****************************************************************************/ ****************************************************************************/
/* Register operations ******************************************************/ /* Register operations ******************************************************/
#ifdef CONFIG_SAMA5_ADC_REGDEBUG #ifdef CONFIG_SAMA5_ADC_REGDEBUG
@ -511,6 +513,7 @@ static struct adc_dev_s g_adcdev;
/**************************************************************************** /****************************************************************************
* Register Operations * Register Operations
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: sam_adc_checkreg * Name: sam_adc_checkreg
* *
@ -611,8 +614,8 @@ static void sam_adc_dmadone(void *arg)
ainfo("ready=%d enabled=%d\n", priv->enabled, priv->ready); ainfo("ready=%d enabled=%d\n", priv->enabled, priv->ready);
DEBUGASSERT(priv != NULL && !priv->ready); DEBUGASSERT(priv != NULL && !priv->ready);
/* If the DMA transfer is not enabled, just ignore the data (and do not start /* If the DMA transfer is not enabled, just ignore the data (and do not
* the next DMA transfer). * start the next DMA transfer).
*/ */
if (priv->enabled) if (priv->enabled)
@ -656,13 +659,13 @@ static void sam_adc_dmadone(void *arg)
sam_adc_dmasetup(priv, (FAR uint8_t *)next, sam_adc_dmasetup(priv, (FAR uint8_t *)next,
SAMA5_ADC_SAMPLES * sizeof(uint16_t)); SAMA5_ADC_SAMPLES * sizeof(uint16_t));
/* Invalidate the DMA buffer so that we are guaranteed to reload the /* Invalidate the DMA buffer so that we are guaranteed to reload the
* newly DMAed data from RAM. * newly DMAed data from RAM.
*/ */
up_invalidate_dcache((uintptr_t)buffer, up_invalidate_dcache((uintptr_t)buffer,
(uintptr_t)buffer + SAMA5_ADC_SAMPLES * sizeof(uint16_t)); (uintptr_t)buffer +
SAMA5_ADC_SAMPLES * sizeof(uint16_t));
/* Process each sample */ /* Process each sample */
@ -670,7 +673,8 @@ static void sam_adc_dmadone(void *arg)
{ {
/* Get the sample and the channel number */ /* Get the sample and the channel number */
chan = (int)((*buffer & ADC_LCDR_CHANB_MASK) >> ADC_LCDR_CHANB_SHIFT); chan = (int)((*buffer & ADC_LCDR_CHANB_MASK) >>
ADC_LCDR_CHANB_SHIFT);
sample = ((*buffer & ADC_LCDR_DATA_MASK) >> ADC_LCDR_DATA_SHIFT); sample = ((*buffer & ADC_LCDR_DATA_MASK) >> ADC_LCDR_DATA_SHIFT);
/* Verify that the upper-half driver has bound its callback functions */ /* Verify that the upper-half driver has bound its callback functions */
@ -827,6 +831,7 @@ static int sam_adc_dmasetup(FAR struct sam_adc_s *priv, FAR uint8_t *buffer,
/**************************************************************************** /****************************************************************************
* ADC interrupt handling * ADC interrupt handling
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: sam_adc_endconversion * Name: sam_adc_endconversion
* *
@ -851,6 +856,7 @@ static void sam_adc_endconversion(void *arg)
uint32_t regval; uint32_t regval;
uint32_t pending; uint32_t pending;
int chan; int chan;
int ret;
DEBUGASSERT(priv != NULL); DEBUGASSERT(priv != NULL);
ainfo("pending=%08x\n", priv->pending); ainfo("pending=%08x\n", priv->pending);
@ -861,7 +867,11 @@ static void sam_adc_endconversion(void *arg)
/* Get exclusive access to the driver data structure */ /* Get exclusive access to the driver data structure */
sam_adc_lock(priv); ret = sam_adc_lock(priv);
if (ret < 0)
{
return;
}
/* Check for the end of conversion event on each channel */ /* Check for the end of conversion event on each channel */
@ -881,7 +891,8 @@ static void sam_adc_endconversion(void *arg)
/* Perform the data received callback */ /* Perform the data received callback */
DEBUGASSERT(priv->cb->au_receive != NULL); DEBUGASSERT(priv->cb->au_receive != NULL);
priv->cb->au_receive(priv->dev, chan, regval & ADC_CDR_DATA_MASK); priv->cb->au_receive(priv->dev, chan, regval &
ADC_CDR_DATA_MASK);
} }
pending &= ~bit; pending &= ~bit;
@ -984,8 +995,8 @@ static int sam_adc_interrupt(int irq, void *context, FAR void *arg)
* Name: sam_adc_bind * Name: sam_adc_bind
* *
* Description: * Description:
* Bind the upper-half driver callbacks to the lower-half implementation. This * Bind the upper-half driver callbacks to the lower-half implementation.
* must be called early in order to receive ADC event notifications. * This must be called early in order to receive ADC event notifications.
* *
****************************************************************************/ ****************************************************************************/
@ -1075,8 +1086,8 @@ static void sam_adc_reset(struct adc_dev_s *dev)
* Description: * Description:
* Configure the ADC. This method is called the first time that the ADC * 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. * device is opened. This will occur when the port is first opened.
* This setup includes configuring and attaching ADC interrupts. Interrupts * This setup includes configuring and attaching ADC interrupts.
* are all disabled upon return. * Interrupts are all disabled upon return.
* *
****************************************************************************/ ****************************************************************************/
@ -1087,8 +1098,8 @@ static int sam_adc_setup(struct adc_dev_s *dev)
ainfo("Setup\n"); ainfo("Setup\n");
/* Enable channel number tag. This bit will force the channel number (CHNB) /* Enable channel number tag. This bit will force the channel number
* to be included in the LDCR register content. * (CHNB) to be included in the LDCR register content.
*/ */
regval = sam_adc_getreg(priv, SAM_ADC_EMR); regval = sam_adc_getreg(priv, SAM_ADC_EMR);
@ -1308,7 +1319,8 @@ static int sam_adc_settimer(struct sam_adc_s *priv, uint32_t frequency,
priv->tc = sam_tc_allocate(channel, mode); priv->tc = sam_tc_allocate(channel, mode);
if (!priv->tc) if (!priv->tc)
{ {
aerr("ERROR: Failed to allocate channel %d mode %08x\n", channel, mode); aerr("ERROR: Failed to allocate channel %d mode %08x\n",
channel, mode);
return -EINVAL; return -EINVAL;
} }
@ -1327,8 +1339,8 @@ static int sam_adc_settimer(struct sam_adc_s *priv, uint32_t frequency,
regval = sam_tc_infreq() / fdiv; regval = sam_tc_infreq() / fdiv;
/* Set up TC_RA and TC_RC. The frequency is determined by RA and RC: TIOA is /* Set up TC_RA and TC_RC. The frequency is determined by RA and RC:
* cleared on RA match; TIOA is set on RC match. * TIOA is cleared on RA match; TIOA is set on RC match.
*/ */
sam_tc_setregister(priv->tc, TC_REGA, regval >> 1); sam_tc_setregister(priv->tc, TC_REGA, regval >> 1);
@ -1514,7 +1526,8 @@ static void sam_adc_autocalibrate(struct sam_adc_s *priv)
/* Wait for auto calibration to complete */ /* Wait for auto calibration to complete */
while (sam_adc_getreg(priv, SAM_ADC_ISR) & ADC_ISR_EOCAL) != ADC_ISR_EOCAL); while ((sam_adc_getreg(priv, SAM_ADC_ISR) &
ADC_ISR_EOCAL) != ADC_ISR_EOCAL);
#endif #endif
} }
@ -1535,8 +1548,8 @@ static void sam_adc_offset(struct sam_adc_s *priv)
#ifdef CONFIG_SAMA5_ADC_ANARCH #ifdef CONFIG_SAMA5_ADC_ANARCH
/* Set the offset for each enabled channel. This centers the analog signal /* Set the offset for each enabled channel. This centers the analog signal
* on Vrefin/2 before the gain scaling. The Offset applied is: (G-1)Vrefin/2 * on Vrefin/2 before the gain scaling. The Offset applied is:
* where G is the gain applied. The default is no offset. * (G-1)Vrefin/2 where G is the gain applied. The default is no offset.
*/ */
#if defined(CONFIG_SAMA5_ADC_CHAN0) && defined(CONFIG_SAMA5_ADC_OFFSET0) #if defined(CONFIG_SAMA5_ADC_CHAN0) && defined(CONFIG_SAMA5_ADC_OFFSET0)
@ -1747,7 +1760,8 @@ static void sam_adc_analogchange(struct sam_adc_s *priv)
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_SAMA5_ADC_SEQUENCER #ifdef CONFIG_SAMA5_ADC_SEQUENCER
static void sam_adc_setseqr(int chan, uint32_t *seqr1, uint32_t *seqr2, int seq) static void sam_adc_setseqr(int chan, uint32_t *seqr1, uint32_t *seqr2,
int seq)
{ {
if (seq > 8) if (seq > 8)
{ {
@ -2103,8 +2117,10 @@ struct adc_dev_s *sam_adc_initialize(void)
/* Set ADC timing */ /* Set ADC timing */
regval = sam_adc_getreg(priv, SAM_ADC_MR); regval = sam_adc_getreg(priv, SAM_ADC_MR);
regval &= ~(ADC_MR_STARTUP_MASK | ADC_MR_TRACKTIM_MASK | ADC_MR_SETTLING_MASK); regval &= ~(ADC_MR_STARTUP_MASK | ADC_MR_TRACKTIM_MASK |
regval |= (ADC_MR_STARTUP_512 | ADC_MR_TRACKTIM(0) | ADC_MR_SETTLING_17); ADC_MR_SETTLING_MASK);
regval |= (ADC_MR_STARTUP_512 | ADC_MR_TRACKTIM(0) |
ADC_MR_SETTLING_17);
sam_adc_putreg(priv, SAM_ADC_MR, regval); sam_adc_putreg(priv, SAM_ADC_MR, regval);
/* Attach the ADC interrupt */ /* Attach the ADC interrupt */
@ -2143,10 +2159,10 @@ struct adc_dev_s *sam_adc_initialize(void)
* *
****************************************************************************/ ****************************************************************************/
void sam_adc_lock(FAR struct sam_adc_s *priv) int sam_adc_lock(FAR struct sam_adc_s *priv)
{ {
ainfo("Locking\n"); ainfo("Locking\n");
nxsem_wait_uninterruptible(&priv->exclsem); return nxsem_wait_uninterruptible(&priv->exclsem);
} }
/**************************************************************************** /****************************************************************************
@ -2194,7 +2210,8 @@ uint32_t sam_adc_getreg(struct sam_adc_s *priv, uintptr_t address)
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_SAMA5_ADC_REGDEBUG #ifdef CONFIG_SAMA5_ADC_REGDEBUG
void sam_adc_putreg(struct sam_adc_s *priv, uintptr_t address, uint32_t regval) void sam_adc_putreg(struct sam_adc_s *priv, uintptr_t address,
uint32_t regval)
{ {
if (sam_adc_checkreg(priv, true, regval, address)) if (sam_adc_checkreg(priv, true, regval, address))
{ {

View File

@ -51,6 +51,7 @@
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/* Configuration ************************************************************/ /* Configuration ************************************************************/
#ifndef CONFIG_SCHED_WORKQUEUE #ifndef CONFIG_SCHED_WORKQUEUE
@ -109,7 +110,7 @@ extern "C"
#endif #endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions Prototypes
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
@ -138,7 +139,7 @@ FAR struct adc_dev_s *sam_adc_initialize(void);
****************************************************************************/ ****************************************************************************/
struct sam_adc_s; struct sam_adc_s;
void sam_adc_lock(FAR struct sam_adc_s *priv); int sam_adc_lock(FAR struct sam_adc_s *priv);
/**************************************************************************** /****************************************************************************
* Name: sam_adc_unlock * Name: sam_adc_unlock

View File

@ -72,12 +72,12 @@
/* The STM32 ADC lower-half driver functionality overview: /* The STM32 ADC lower-half driver functionality overview:
* - one lower-half driver for all STM32 ADC IP cores, * - one lower-half driver for all STM32 ADC IP cores,
* - general lower-half logic for the Nuttx upper-half ADC driver, * - general lower-half logic for the Nuttx upper-half ADC driver,
* - lower-half ADC driver can be used not only with the upper-half ADC driver, * - lower-half ADC driver can be used not only with the upper-half ADC
* but also in the lower-half logic for special-case custom drivers * driver, but also in the lower-half logic for special-case custom
* (eg. power-control, custom sensors), * drivers (eg. power-control, custom sensors),
* - ADC can be used in time-critical operations (eg. control loop for * - ADC can be used in time-critical operations (eg. control loop for
* converters or motor drivers) therefore it is necessary to support the high * converters or motor drivers) therefore it is necessary to support the
* performance, zero latency ADC interrupts, * high performance, zero latency ADC interrupts,
* - ADC triggering from different sources (EXTSEL and JEXTSEL), * - ADC triggering from different sources (EXTSEL and JEXTSEL),
* - regular sequence conversion (supported in upper-half ADC driver) * - regular sequence conversion (supported in upper-half ADC driver)
* - injected sequence conversion (not supported in upper-half ADC driver) * - injected sequence conversion (not supported in upper-half ADC driver)
@ -128,8 +128,8 @@
# warning "There is no proper implementation for TIMER TRIGGERS at the moment" # warning "There is no proper implementation for TIMER TRIGGERS at the moment"
#endif #endif
/* If ADC use HSI as clock-source and HSI is not used for PLL and system clock, /* If ADC use HSI as clock-source and HSI is not used for PLL and system
* then we can control it directly from ADC driver. * clock, then we can control it directly from ADC driver.
*/ */
#if defined(HAVE_ADC_CLOCK_HSI) && \ #if defined(HAVE_ADC_CLOCK_HSI) && \
@ -198,7 +198,7 @@
# define ADC_JEXTREG_JEXTEN_DEFAULT ADC_JSQR_JEXTEN_RISING # define ADC_JEXTREG_JEXTEN_DEFAULT ADC_JSQR_JEXTEN_RISING
#endif #endif
/* ADC Channels/DMA ********************************************************/ /* ADC Channels/DMA *********************************************************/
/* The maximum number of channels that can be sampled. If DMA support is /* The maximum number of channels that can be sampled. If DMA support is
* not enabled, then only a single channel can be sampled. Otherwise, * not enabled, then only a single channel can be sampled. Otherwise,
@ -354,7 +354,8 @@
* - H7 - 20 * - H7 - 20
* - L1 - 32 * - L1 - 32
* *
* NOTE: this value can be obtained from SMPRx register description (ST manual) * NOTE: this value can be obtained from SMPRx register description
* (ST manual)
*/ */
#if defined(CONFIG_STM32_STM32F10XX) #if defined(CONFIG_STM32_STM32F10XX)
@ -623,8 +624,8 @@ static void adc_rxint(FAR struct adc_dev_s *dev, bool enable);
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);
static void adc_enable(FAR struct stm32_dev_s *priv, bool enable); static void adc_enable(FAR struct stm32_dev_s *priv, bool enable);
static uint32_t adc_sqrbits(FAR struct stm32_dev_s *priv, int first, int last, static uint32_t adc_sqrbits(FAR struct stm32_dev_s *priv, int first,
int offset); int last, int offset);
static int adc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch); static int adc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch);
static int adc_ioc_change_ints(FAR struct adc_dev_s *dev, int cmd, static int adc_ioc_change_ints(FAR struct adc_dev_s *dev, int cmd,
@ -688,16 +689,18 @@ static void adc_inten(FAR struct stm32_adc_dev_s *dev, uint32_t source);
static void adc_intdis(FAR struct stm32_adc_dev_s *dev, uint32_t source); static void adc_intdis(FAR struct stm32_adc_dev_s *dev, uint32_t source);
static uint32_t adc_intget(FAR struct stm32_adc_dev_s *dev); static uint32_t adc_intget(FAR struct stm32_adc_dev_s *dev);
static uint32_t adc_regget(FAR struct stm32_adc_dev_s *dev); static uint32_t adc_regget(FAR struct stm32_adc_dev_s *dev);
static void adc_llops_reg_startconv(FAR struct stm32_adc_dev_s *dev, bool enable); static void adc_llops_reg_startconv(FAR struct stm32_adc_dev_s *dev,
static int adc_offset_set(FAR struct stm32_adc_dev_s *dev, uint8_t ch, uint8_t i, bool enable);
uint16_t offset); static int adc_offset_set(FAR struct stm32_adc_dev_s *dev, uint8_t ch,
uint8_t i, uint16_t offset);
# ifdef ADC_HAVE_DMA # ifdef ADC_HAVE_DMA
static int adc_regbufregister(FAR struct stm32_adc_dev_s *dev, uint16_t *buffer, static int adc_regbufregister(FAR struct stm32_adc_dev_s *dev,
uint8_t len); uint16_t *buffer, uint8_t len);
# endif # endif
# ifdef ADC_HAVE_INJECTED # ifdef ADC_HAVE_INJECTED
static uint32_t adc_injget(FAR struct stm32_adc_dev_s *dev, uint8_t chan); static uint32_t adc_injget(FAR struct stm32_adc_dev_s *dev, uint8_t chan);
static void adc_llops_inj_startconv(FAR struct stm32_adc_dev_s *dev, bool enable); static void adc_llops_inj_startconv(FAR struct stm32_adc_dev_s *dev,
bool enable);
# endif # endif
# ifdef CONFIG_STM32_ADC_CHANGE_SAMPLETIME # ifdef CONFIG_STM32_ADC_CHANGE_SAMPLETIME
static void adc_sampletime_set(FAR struct stm32_adc_dev_s *dev, static void adc_sampletime_set(FAR struct stm32_adc_dev_s *dev,
@ -1655,8 +1658,8 @@ static int adc_timinit(FAR struct stm32_dev_s *priv)
#else /* No ADV TIM */ #else /* No ADV TIM */
/* For the STM32L15XX family only these timers can be used: 2-4, 6, 7, 9, 10 /* For the STM32L15XX family only these timers can be used: 2-4, 6, 7, 9,
* Reset the output compare and output compare N IDLE State * 10. Reset the output compare and output compare N IDLE State
*/ */
if (priv->tbase >= STM32_TIM2_BASE && priv->tbase <= STM32_TIM4_BASE) if (priv->tbase >= STM32_TIM2_BASE && priv->tbase <= STM32_TIM4_BASE)
@ -1735,7 +1738,8 @@ static void adc_reg_startconv(FAR struct stm32_dev_s *priv, bool enable)
/* Wait for the conversion to stop */ /* Wait for the conversion to stop */
while ((adc_getreg(priv, STM32_ADC_CR_OFFSET) & ADC_CR_ADSTP) != 0); while ((adc_getreg(priv, STM32_ADC_CR_OFFSET) &
ADC_CR_ADSTP) != 0);
} }
} }
} }
@ -1822,7 +1826,8 @@ static void adc_inj_startconv(FAR struct stm32_dev_s *priv, bool enable)
/* Wait for the conversion to stop */ /* Wait for the conversion to stop */
while ((adc_getreg(priv, STM32_ADC_CR_OFFSET) & ADC_CR_JADSTP) != 0); while ((adc_getreg(priv, STM32_ADC_CR_OFFSET) &
ADC_CR_JADSTP) != 0);
} }
} }
} }
@ -1998,7 +2003,8 @@ static void adc_rccreset(FAR struct stm32_dev_s *priv, bool reset)
uint32_t adcbit; uint32_t adcbit;
/* Pick the appropriate bit in the RCC reset register. /* Pick the appropriate bit in the RCC reset register.
* For the STM32 ADC IPv2, there is an individual bit to reset each ADC block. * For the STM32 ADC IPv2, there is an individual bit to reset each
* ADC block.
*/ */
switch (priv->intf) switch (priv->intf)
@ -2160,7 +2166,7 @@ static void adc_dels_after_conversion(FAR struct stm32_dev_s *priv,
* *
* Description: * Description:
* Selects the bank of channels to be converted * Selects the bank of channels to be converted
* (! Must be modified only when no conversion is on going !) * (! Must be modified only when no conversion is on going !)
* *
* Input Parameters: * Input Parameters:
* *
@ -2279,7 +2285,8 @@ static void adc_enable(FAR struct stm32_dev_s *priv, bool enable)
****************************************************************************/ ****************************************************************************/
#if defined(ADC_HAVE_DMA) && !defined(CONFIG_STM32_ADC_NOIRQ) #if defined(ADC_HAVE_DMA) && !defined(CONFIG_STM32_ADC_NOIRQ)
static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg) static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr,
FAR void *arg)
{ {
FAR struct adc_dev_s *dev = (FAR struct adc_dev_s *)arg; FAR struct adc_dev_s *dev = (FAR struct adc_dev_s *)arg;
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
@ -2850,6 +2857,7 @@ static void adc_reset(FAR struct adc_dev_s *dev)
{ {
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
irqstate_t flags; irqstate_t flags;
int ret;
ainfo("intf: %d\n", priv->intf); ainfo("intf: %d\n", priv->intf);
flags = enter_critical_section(); flags = enter_critical_section();
@ -2871,7 +2879,11 @@ static void adc_reset(FAR struct adc_dev_s *dev)
/* Only if this is the first initialzied ADC instance in the ADC block */ /* Only if this is the first initialzied ADC instance in the ADC block */
#ifdef HAVE_ADC_CMN_DATA #ifdef HAVE_ADC_CMN_DATA
adccmn_lock(priv, true); ret = adccmn_lock(priv, true);
if (ret < 0)
{
return;
}
if (priv->cmn->initialized == 0) if (priv->cmn->initialized == 0)
#endif #endif
@ -3000,7 +3012,12 @@ static int adc_setup(FAR struct adc_dev_s *dev)
#ifdef HAVE_ADC_CMN_DATA #ifdef HAVE_ADC_CMN_DATA
/* Increase instances counter */ /* Increase instances counter */
adccmn_lock(priv, true); ret = adccmn_lock(priv, true);
if (ret < 0)
{
return ret;
}
priv->cmn->initialized += 1; priv->cmn->initialized += 1;
adccmn_lock(priv, false); adccmn_lock(priv, false);
#endif #endif
@ -3024,6 +3041,7 @@ static int adc_setup(FAR struct adc_dev_s *dev)
static void adc_shutdown(FAR struct adc_dev_s *dev) static void adc_shutdown(FAR struct adc_dev_s *dev)
{ {
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
int ret;
/* Disable ADC */ /* Disable ADC */
@ -3041,7 +3059,11 @@ static void adc_shutdown(FAR struct adc_dev_s *dev)
#endif #endif
#ifdef HAVE_ADC_CMN_DATA #ifdef HAVE_ADC_CMN_DATA
adccmn_lock(priv, true); ret = adccmn_lock(priv, true);
if (ret < 0)
{
return;
}
if (priv->cmn->initialized <= 1) if (priv->cmn->initialized <= 1)
#endif #endif
@ -3049,9 +3071,10 @@ static void adc_shutdown(FAR struct adc_dev_s *dev)
/* Disable and reset the ADC module. /* Disable and reset the ADC module.
* *
* NOTE: The ADC block will be reset to its reset state only if all * NOTE: The ADC block will be reset to its reset state only if all
* ADC block instances are closed. This means that the closed ADC * ADC block instances are closed. This means that the closed
* may not be reset which in turn may affect low-power applications. * ADC may not be reset which in turn may affect low-power
* (But ADC is turned off here, is not that enough?) * applications. (But ADC is turned off here, is not that
* enough?)
*/ */
adc_rccreset(priv, true); adc_rccreset(priv, true);
@ -3171,7 +3194,8 @@ static void adc_ioc_enable_tvref_register(FAR struct adc_dev_s *dev,
adccmn_modifyreg(priv, STM32_ADC_CCR_OFFSET, ADC_CCR_TSVREFE, 0); adccmn_modifyreg(priv, STM32_ADC_CCR_OFFSET, ADC_CCR_TSVREFE, 0);
} }
ainfo("STM32_ADC_CCR value: 0x%08x\n", adccmn_getreg(priv, STM32_ADC_CCR_OFFSET)); ainfo("STM32_ADC_CCR value: 0x%08x\n",
adccmn_getreg(priv, STM32_ADC_CCR_OFFSET));
#endif #endif
} }
#endif /* HAVE_IP_ADC_V1 */ #endif /* HAVE_IP_ADC_V1 */
@ -3372,7 +3396,8 @@ static void adc_enable_vbat_channel(FAR struct adc_dev_s *dev, bool enable)
adccmn_modifyreg(priv, STM32_ADC_CCR_OFFSET, ADC_CCR_VBATEN, 0); adccmn_modifyreg(priv, STM32_ADC_CCR_OFFSET, ADC_CCR_VBATEN, 0);
} }
ainfo("STM32_ADC_CCR value: 0x%08x\n", adccmn_getreg(priv, STM32_ADC_CCR_OFFSET)); ainfo("STM32_ADC_CCR value: 0x%08x\n",
adccmn_getreg(priv, STM32_ADC_CCR_OFFSET));
} }
#endif #endif
@ -3495,7 +3520,8 @@ static void adc_ioc_enable_eoc_int(FAR struct stm32_dev_s *priv, bool enable)
* *
****************************************************************************/ ****************************************************************************/
static void adc_ioc_enable_jeoc_int(FAR struct stm32_dev_s *priv, bool enable) static void adc_ioc_enable_jeoc_int(FAR struct stm32_dev_s *priv,
bool enable)
{ {
if (enable) if (enable)
{ {
@ -3655,8 +3681,8 @@ static void adc_enable_hsi(bool enable)
* Name: adc_sqrbits * Name: adc_sqrbits
****************************************************************************/ ****************************************************************************/
static uint32_t adc_sqrbits(FAR struct stm32_dev_s *priv, int first, int last, static uint32_t adc_sqrbits(FAR struct stm32_dev_s *priv, int first,
int offset) int last, int offset)
{ {
uint32_t bits = 0; uint32_t bits = 0;
int i; int i;
@ -3762,7 +3788,8 @@ static int adc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch)
} }
else else
{ {
for (i = 0; i < priv->cr_channels && priv->r_chanlist[i] != ch - 1; i++); for (i = 0; i < priv->cr_channels && priv->r_chanlist[i] != ch - 1;
i++);
if (i >= priv->cr_channels) if (i >= priv->cr_channels)
{ {
@ -3774,23 +3801,28 @@ static int adc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch)
} }
#ifdef STM32_ADC_SQR5_OFFSET #ifdef STM32_ADC_SQR5_OFFSET
bits = adc_sqrbits(priv, ADC_SQR5_FIRST, ADC_SQR5_LAST, ADC_SQR5_SQ_OFFSET); bits = adc_sqrbits(priv, ADC_SQR5_FIRST, ADC_SQR5_LAST,
ADC_SQR5_SQ_OFFSET);
adc_modifyreg(priv, STM32_ADC_SQR5_OFFSET, ~ADC_SQR5_RESERVED, bits); adc_modifyreg(priv, STM32_ADC_SQR5_OFFSET, ~ADC_SQR5_RESERVED, bits);
#endif #endif
#ifdef STM32_ADC_SQR4_OFFSET #ifdef STM32_ADC_SQR4_OFFSET
bits = adc_sqrbits(priv, ADC_SQR4_FIRST, ADC_SQR4_LAST, ADC_SQR4_SQ_OFFSET); bits = adc_sqrbits(priv, ADC_SQR4_FIRST, ADC_SQR4_LAST,
ADC_SQR4_SQ_OFFSET);
adc_modifyreg(priv, STM32_ADC_SQR4_OFFSET, ~ADC_SQR4_RESERVED, bits); adc_modifyreg(priv, STM32_ADC_SQR4_OFFSET, ~ADC_SQR4_RESERVED, bits);
#endif #endif
bits = adc_sqrbits(priv, ADC_SQR3_FIRST, ADC_SQR3_LAST, ADC_SQR3_SQ_OFFSET); bits = adc_sqrbits(priv, ADC_SQR3_FIRST, ADC_SQR3_LAST,
ADC_SQR3_SQ_OFFSET);
adc_modifyreg(priv, STM32_ADC_SQR3_OFFSET, ~ADC_SQR3_RESERVED, bits); adc_modifyreg(priv, STM32_ADC_SQR3_OFFSET, ~ADC_SQR3_RESERVED, bits);
bits = adc_sqrbits(priv, ADC_SQR2_FIRST, ADC_SQR2_LAST, ADC_SQR2_SQ_OFFSET); bits = adc_sqrbits(priv, ADC_SQR2_FIRST, ADC_SQR2_LAST,
ADC_SQR2_SQ_OFFSET);
adc_modifyreg(priv, STM32_ADC_SQR2_OFFSET, ~ADC_SQR2_RESERVED, bits); adc_modifyreg(priv, STM32_ADC_SQR2_OFFSET, ~ADC_SQR2_RESERVED, bits);
bits = ((uint32_t)priv->rnchannels - 1) << ADC_SQR1_L_SHIFT; bits = ((uint32_t)priv->rnchannels - 1) << ADC_SQR1_L_SHIFT;
bits |= adc_sqrbits(priv, ADC_SQR1_FIRST, ADC_SQR1_LAST, ADC_SQR1_SQ_OFFSET); bits |= adc_sqrbits(priv, ADC_SQR1_FIRST,
ADC_SQR1_LAST, ADC_SQR1_SQ_OFFSET);
adc_modifyreg(priv, STM32_ADC_SQR1_OFFSET, ~ADC_SQR1_RESERVED, bits); adc_modifyreg(priv, STM32_ADC_SQR1_OFFSET, ~ADC_SQR1_RESERVED, bits);
return OK; return OK;
@ -4288,7 +4320,8 @@ static uint32_t adc_regget(FAR struct stm32_adc_dev_s *dev)
* Name: adc_llops_reg_startconv * Name: adc_llops_reg_startconv
****************************************************************************/ ****************************************************************************/
static void adc_llops_reg_startconv(FAR struct stm32_adc_dev_s *dev, bool enable) static void adc_llops_reg_startconv(FAR struct stm32_adc_dev_s *dev,
bool enable)
{ {
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev;
@ -4300,8 +4333,8 @@ static void adc_llops_reg_startconv(FAR struct stm32_adc_dev_s *dev, bool enable
****************************************************************************/ ****************************************************************************/
#ifdef ADC_HAVE_DMA #ifdef ADC_HAVE_DMA
static int adc_regbufregister(FAR struct stm32_adc_dev_s *dev, uint16_t *buffer, static int adc_regbufregister(FAR struct stm32_adc_dev_s *dev,
uint8_t len) uint16_t *buffer, uint8_t len)
{ {
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev;
@ -4347,7 +4380,8 @@ errout:
* Name: adc_llops_inj_startconv * Name: adc_llops_inj_startconv
****************************************************************************/ ****************************************************************************/
static void adc_llops_inj_startconv(FAR struct stm32_adc_dev_s *dev, bool enable) static void adc_llops_inj_startconv(FAR struct stm32_adc_dev_s *dev,
bool enable)
{ {
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev;

View File

@ -88,12 +88,14 @@
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/* RCC reset ****************************************************************/ /* RCC reset ****************************************************************/
#define STM32_RCC_RSTR STM32_RCC_APB2RSTR #define STM32_RCC_RSTR STM32_RCC_APB2RSTR
#define RCC_RSTR_ADC1RST RCC_APB2RSTR_ADC1RST #define RCC_RSTR_ADC1RST RCC_APB2RSTR_ADC1RST
/* ADC Channels/DMA ********************************************************/ /* ADC Channels/DMA *********************************************************/
/* The maximum number of channels that can be sampled. If DMA support is /* The maximum number of channels that can be sampled. If DMA support is
* not enabled, then only a single channel can be sampled. Otherwise, * not enabled, then only a single channel can be sampled. Otherwise,
* data overruns would occur. * data overruns would occur.
@ -142,7 +144,8 @@
/* Number of channels per ADC: /* Number of channels per ADC:
* - F0, L0, G0 - 19, but single SMP for all channels * - F0, L0, G0 - 19, but single SMP for all channels
* *
* NOTE: this value can be obtained from SMPRx register description (ST manual) * NOTE: this value can be obtained from SMPRx register description
* (ST manual)
*/ */
#if defined(CONFIG_STM32F0L0G0_STM32F0) || defined(CONFIG_STM32F0L0G0_STM32L0) #if defined(CONFIG_STM32F0L0G0_STM32F0) || defined(CONFIG_STM32F0L0G0_STM32L0)
@ -350,12 +353,16 @@ static int adc_extcfg_set(FAR struct adc_dev_s *dev, uint32_t extcfg);
static void adc_dumpregs(FAR struct stm32_dev_s *priv); static void adc_dumpregs(FAR struct stm32_dev_s *priv);
#ifdef CONFIG_STM32F0L0G0_ADC_LL_OPS #ifdef CONFIG_STM32F0L0G0_ADC_LL_OPS
static void adc_llops_intack(FAR struct stm32_adc_dev_s *dev, uint32_t source); static void adc_llops_intack(FAR struct stm32_adc_dev_s *dev,
static void adc_llops_inten(FAR struct stm32_adc_dev_s *dev, uint32_t source); uint32_t source);
static void adc_llops_intdis(FAR struct stm32_adc_dev_s *dev, uint32_t source); static void adc_llops_inten(FAR struct stm32_adc_dev_s *dev,
uint32_t source);
static void adc_llops_intdis(FAR struct stm32_adc_dev_s *dev,
uint32_t source);
static uint32_t adc_llops_intget(FAR struct stm32_adc_dev_s *dev); static uint32_t adc_llops_intget(FAR struct stm32_adc_dev_s *dev);
static uint32_t adc_llops_regget(FAR struct stm32_adc_dev_s *dev); static uint32_t adc_llops_regget(FAR struct stm32_adc_dev_s *dev);
static void adc_llops_reg_startconv(FAR struct stm32_adc_dev_s *dev, bool enable); static void adc_llops_reg_startconv(FAR struct stm32_adc_dev_s *dev,
bool enable);
# ifdef ADC_HAVE_DMA # ifdef ADC_HAVE_DMA
static int adc_llops_regbufregister(FAR struct stm32_adc_dev_s *dev, static int adc_llops_regbufregister(FAR struct stm32_adc_dev_s *dev,
uint16_t *buffer, uint8_t len); uint16_t *buffer, uint8_t len);
@ -593,7 +600,7 @@ static uint32_t adccmn_getreg(FAR struct stm32_dev_s *priv, uint32_t offset)
/* Return register value */ /* Return register value */
return getreg32(base+offset); return getreg32(base + offset);
} }
# endif # endif
#endif /* HAVE_ADC_CMN_REGS */ #endif /* HAVE_ADC_CMN_REGS */
@ -821,7 +828,8 @@ static void adc_reg_startconv(FAR struct stm32_dev_s *priv, bool enable)
/* Wait for the conversion to stop */ /* Wait for the conversion to stop */
while ((adc_getreg(priv, STM32_ADC_CR_OFFSET) & ADC_CR_ADSTP) != 0); while ((adc_getreg(priv, STM32_ADC_CR_OFFSET) &
ADC_CR_ADSTP) != 0);
} }
} }
} }
@ -868,7 +876,8 @@ static void adc_rccreset(FAR struct stm32_dev_s *priv, bool reset)
uint32_t adcbit; uint32_t adcbit;
/* Pick the appropriate bit in the RCC reset register. /* Pick the appropriate bit in the RCC reset register.
* For the STM32 ADC IPv2, there is an individual bit to reset each ADC block. * For the STM32 ADC IPv2, there is an individual bit to reset each ADC
* block.
*/ */
switch (priv->intf) switch (priv->intf)
@ -879,6 +888,7 @@ static void adc_rccreset(FAR struct stm32_dev_s *priv, bool reset)
adcbit = RCC_RSTR_ADC1RST; adcbit = RCC_RSTR_ADC1RST;
break; break;
} }
#endif #endif
default: default:
{ {
@ -970,7 +980,8 @@ static void adc_enable(FAR struct stm32_dev_s *priv, bool enable)
****************************************************************************/ ****************************************************************************/
#if defined(ADC_HAVE_DMA) #if defined(ADC_HAVE_DMA)
static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg) static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr,
FAR void *arg)
{ {
FAR struct adc_dev_s *dev = (FAR struct adc_dev_s *)arg; FAR struct adc_dev_s *dev = (FAR struct adc_dev_s *)arg;
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
@ -1334,6 +1345,7 @@ static void adc_reset(FAR struct adc_dev_s *dev)
{ {
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
irqstate_t flags; irqstate_t flags;
int ret;
ainfo("intf: %d\n", priv->intf); ainfo("intf: %d\n", priv->intf);
flags = enter_critical_section(); flags = enter_critical_section();
@ -1347,7 +1359,11 @@ static void adc_reset(FAR struct adc_dev_s *dev)
/* Only if this is the first initialzied ADC instance in the ADC block */ /* Only if this is the first initialzied ADC instance in the ADC block */
#ifdef HAVE_ADC_CMN_DATA #ifdef HAVE_ADC_CMN_DATA
adccmn_lock(priv, true); ret = adccmn_lock(priv, true);
if (ret < 0)
{
return;
}
if (priv->cmn->initialized == 0) if (priv->cmn->initialized == 0)
#endif #endif
@ -1448,7 +1464,12 @@ static int adc_setup(FAR struct adc_dev_s *dev)
#ifdef HAVE_ADC_CMN_DATA #ifdef HAVE_ADC_CMN_DATA
/* Increase instances counter */ /* Increase instances counter */
adccmn_lock(priv, true); ret = adccmn_lock(priv, true);
if (ret < 0)
{
return;
}
priv->cmn->initialized += 1; priv->cmn->initialized += 1;
adccmn_lock(priv, false); adccmn_lock(priv, false);
#endif #endif
@ -1472,6 +1493,7 @@ static int adc_setup(FAR struct adc_dev_s *dev)
static void adc_shutdown(FAR struct adc_dev_s *dev) static void adc_shutdown(FAR struct adc_dev_s *dev)
{ {
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
int ret;
/* Disable ADC */ /* Disable ADC */
@ -1485,7 +1507,11 @@ static void adc_shutdown(FAR struct adc_dev_s *dev)
#endif #endif
#ifdef HAVE_ADC_CMN_DATA #ifdef HAVE_ADC_CMN_DATA
adccmn_lock(priv, true); ret = adccmn_lock(priv, true);
if (ret < 0)
{
return;
}
if (priv->cmn->initialized <= 1) if (priv->cmn->initialized <= 1)
#endif #endif
@ -1494,8 +1520,9 @@ static void adc_shutdown(FAR struct adc_dev_s *dev)
* *
* NOTE: The ADC block will be reset to its reset state only if all * NOTE: The ADC block will be reset to its reset state only if all
* ADC block instances are closed. This means that the closed ADC * ADC block instances are closed. This means that the closed ADC
* may not be reset which in turn may affect low-power applications. * may not be reset which in turn may affect low-power
* (But ADC is turned off here, is not that enough?) * applications. (But ADC is turned off here, is not that
* enough?)
*/ */
adc_rccreset(priv, true); adc_rccreset(priv, true);
@ -1683,7 +1710,8 @@ static void adc_enable_vbat_channel(FAR struct adc_dev_s *dev, bool enable)
adccmn_modifyreg(priv, STM32_ADC_CCR_OFFSET, ADC_CCR_VBATEN, 0); adccmn_modifyreg(priv, STM32_ADC_CCR_OFFSET, ADC_CCR_VBATEN, 0);
} }
ainfo("STM32_ADC_CCR value: 0x%08x\n", adccmn_getreg(priv, STM32_ADC_CCR_OFFSET)); ainfo("STM32_ADC_CCR value: 0x%08x\n",
adccmn_getreg(priv, STM32_ADC_CCR_OFFSET));
} }
#endif #endif
@ -1894,7 +1922,8 @@ static int adc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch)
} }
else else
{ {
for (i = 0; i < priv->cr_channels && priv->r_chanlist[i] != ch - 1; i++); for (i = 0; i < priv->cr_channels && priv->r_chanlist[i] != ch - 1;
i++);
if (i >= priv->cr_channels) if (i >= priv->cr_channels)
{ {
@ -1905,8 +1934,7 @@ static int adc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch)
priv->rnchannels = 1; priv->rnchannels = 1;
} }
for (i = 0; i < priv->rnchannels; i += 1)
for (i = 0; i < priv->rnchannels; i+=1)
{ {
bits |= ADC_CHSELR_CHSEL(priv->r_chanlist[i]); bits |= ADC_CHSELR_CHSEL(priv->r_chanlist[i]);
} }
@ -2153,7 +2181,8 @@ static int adc1_interrupt(int irq, FAR void *context, FAR void *arg)
* Name: adc_llops_intack * Name: adc_llops_intack
****************************************************************************/ ****************************************************************************/
static void adc_llops_intack(FAR struct stm32_adc_dev_s *dev, uint32_t source) static void adc_llops_intack(FAR struct stm32_adc_dev_s *dev,
uint32_t source)
{ {
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev;
@ -2187,7 +2216,8 @@ static void adc_llops_inten(FAR struct stm32_adc_dev_s *dev, uint32_t source)
* Name: adc_llops_intdis * Name: adc_llops_intdis
****************************************************************************/ ****************************************************************************/
static void adc_llops_intdis(FAR struct stm32_adc_dev_s *dev, uint32_t source) static void adc_llops_intdis(FAR struct stm32_adc_dev_s *dev,
uint32_t source)
{ {
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev;
@ -2227,7 +2257,8 @@ static uint32_t adc_llops_regget(FAR struct stm32_adc_dev_s *dev)
* Name: adc_llops_reg_startconv * Name: adc_llops_reg_startconv
****************************************************************************/ ****************************************************************************/
static void adc_llops_reg_startconv(FAR struct stm32_adc_dev_s *dev, bool enable) static void adc_llops_reg_startconv(FAR struct stm32_adc_dev_s *dev,
bool enable)
{ {
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev;
@ -2354,6 +2385,7 @@ struct adc_dev_s *stm32_adcinitialize(int intf, FAR const uint8_t *chanlist,
dev = &g_adcdev1; dev = &g_adcdev1;
break; break;
} }
#endif #endif
default: default:
{ {

View File

@ -14,7 +14,8 @@
* The Tivaware sample code has a BSD compatible license that requires this * The Tivaware sample code has a BSD compatible license that requires this
* copyright notice: * copyright notice:
* *
* Copyright (c) 2005-2014 Texas Instruments Incorporated. All rights reserved. * Copyright (c) 2005-2014 Texas Instruments Incorporated.
* All rights reserved.
* Software License Agreement * Software License Agreement
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -45,7 +46,8 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* This is part of revision 2.1.0.12573 of the Tiva Peripheral Driver Library. * This is part of revision 2.1.0.12573 of the Tiva Peripheral Driver
* Library.
****************************************************************************/ ****************************************************************************/
/* Keep in mind that for every step there should be another entry in the /* Keep in mind that for every step there should be another entry in the
@ -141,7 +143,8 @@ static void tiva_adc_reset(struct adc_dev_s *dev);
static int tiva_adc_setup(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); static void tiva_adc_shutdown(struct adc_dev_s *dev);
static void tiva_adc_rxint(struct adc_dev_s *dev, bool enable); static void tiva_adc_rxint(struct adc_dev_s *dev, bool enable);
static int tiva_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg); static int tiva_adc_ioctl(struct adc_dev_s *dev, int cmd,
unsigned long arg);
/**************************************************************************** /****************************************************************************
* Public Data * Public Data
@ -350,6 +353,7 @@ static void tiva_adc_irqinitialize(struct tiva_adc_cfg_s *cfg)
tiva_adc_irq_attach(0, 3, tiva_adc0_sse3_interrupt); tiva_adc_irq_attach(0, 3, tiva_adc0_sse3_interrupt);
} }
} }
#endif #endif
#ifdef CONFIG_TIVA_ADC1 #ifdef CONFIG_TIVA_ADC1
if (cfg->adc == 1) if (cfg->adc == 1)
@ -381,8 +385,8 @@ static void tiva_adc_irqinitialize(struct tiva_adc_cfg_s *cfg)
* Name: tiva_adc_bind * Name: tiva_adc_bind
* *
* Description: * Description:
* Bind the upper-half driver callbacks to the lower-half implementation. This * Bind the upper-half driver callbacks to the lower-half implementation.
* must be called early in order to receive ADC event notifications. * This must be called early in order to receive ADC event notifications.
* *
****************************************************************************/ ****************************************************************************/
@ -565,7 +569,11 @@ static int tiva_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg)
/* Get exclusive access to the driver data structure */ /* Get exclusive access to the driver data structure */
tiva_adc_lock(priv, sse); ret = tiva_adc_lock(priv, sse);
if (ret < 0)
{
return ret;
}
/* Start conversion and wait for end of conversion */ /* Start conversion and wait for end of conversion */
@ -622,7 +630,7 @@ static int tiva_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg)
(regval & TIVA_ADC_TRIG_PWM2) || (regval & TIVA_ADC_TRIG_PWM2) ||
(regval & TIVA_ADC_TRIG_PWM3)) (regval & TIVA_ADC_TRIG_PWM3))
{ {
tiva_adc_sse_pwm_trig(adc, sse, (uint32_t)(arg&0xFFFFFFFC)); tiva_adc_sse_pwm_trig(adc, sse, (uint32_t)(arg & 0xfffffffc));
} }
} }
break; break;
@ -666,10 +674,15 @@ static void tiva_adc_read(void *arg)
uint8_t i = 0; uint8_t i = 0;
uint8_t fifo_count = 0; uint8_t fifo_count = 0;
int32_t buf[8]; int32_t buf[8];
int ret;
/* Get exclusive access to the driver data structure */ /* Get exclusive access to the driver data structure */
tiva_adc_lock(g_adcs[sse->adc], sse->num); ret = tiva_adc_lock(g_adcs[sse->adc], sse->num);
if (ret < 0)
{
return ;
}
/* Get sampled data */ /* Get sampled data */
@ -789,7 +802,6 @@ static struct tiva_adc_s *tiva_adc_struct_init(struct tiva_adc_cfg_s *cfg)
for (s = 0; s < 4; s++) for (s = 0; s < 4; s++)
{ {
/* Only configure selected SSEs */ /* Only configure selected SSEs */
if (cfg->sse[s]) if (cfg->sse[s])
@ -823,6 +835,7 @@ static struct tiva_adc_s *tiva_adc_struct_init(struct tiva_adc_cfg_s *cfg)
{ {
goto tiva_adc_struct_init_error; goto tiva_adc_struct_init_error;
} }
goto tiva_adc_struct_init_ok; goto tiva_adc_struct_init_ok;
} }
else else
@ -941,12 +954,12 @@ int tiva_adc_initialize(const char *devpath, struct tiva_adc_cfg_s *cfg,
* *
****************************************************************************/ ****************************************************************************/
void tiva_adc_lock(FAR struct tiva_adc_s *priv, int sse) int tiva_adc_lock(FAR struct tiva_adc_s *priv, int sse)
{ {
struct tiva_adc_sse_s *s = g_sses[SSE_IDX(priv->devno, sse)]; struct tiva_adc_sse_s *s = g_sses[SSE_IDX(priv->devno, sse)];
ainfo("Locking...\n"); ainfo("Locking...\n");
nxsem_wait_uninterruptible(&s->exclsem); return nxsem_wait_uninterruptible(&s->exclsem);
} }
/**************************************************************************** /****************************************************************************
@ -1023,6 +1036,7 @@ static void tiva_adc_runtimeobj_vals(void)
ainfo("SSE%d [0x%08x] adc=%d cfg=%d ena=%d num=%d\n", ainfo("SSE%d [0x%08x] adc=%d cfg=%d ena=%d num=%d\n",
s, sse, sse->adc, sse->cfg, sse->ena, sse->num); s, sse, sse->adc, sse->cfg, sse->ena, sse->num);
} }
# endif # endif
# ifdef CONFIG_TIVA_ADC1 # ifdef CONFIG_TIVA_ADC1
ainfo("ADC1 [0x%08x] cfg=%d ena=%d devno=%d\n", ainfo("ADC1 [0x%08x] cfg=%d ena=%d devno=%d\n",

View File

@ -211,7 +211,7 @@ struct tiva_adc_s;
* *
****************************************************************************/ ****************************************************************************/
void tiva_adc_lock(FAR struct tiva_adc_s *priv, int sse); int tiva_adc_lock(FAR struct tiva_adc_s *priv, int sse);
/**************************************************************************** /****************************************************************************
* Name: tiva_adc_unlock * Name: tiva_adc_unlock
@ -356,9 +356,10 @@ int tiva_adc_enable(uint8_t adc, bool state);
* TM4C123 - Select either MOSC or PIOSC. Both result in 16 MHz operation, * TM4C123 - Select either MOSC or PIOSC. Both result in 16 MHz operation,
* however the PIOSC allows the ADC to operate in deep sleep mode. * however the PIOSC allows the ADC to operate in deep sleep mode.
* *
* TM4C129 - For the 129, there is still a selection between various internal * TM4C129 - For the 129, there is still a selection between various
* clocks, however the output frequency is variable (16 MHz - 32 MHz); so it * internal clocks, however the output frequency is variable (16 MHz -
* is much more intuitive to allow the clock variable be a frequency value. * 32 MHz); so it is much more intuitive to allow the clock variable be a
* frequency value.
* *
****************************************************************************/ ****************************************************************************/
@ -543,9 +544,10 @@ void tiva_adc_sse_clear_int(uint8_t adc, uint8_t sse);
* Name: tiva_adc_sse_data * Name: tiva_adc_sse_data
* *
* Description: * Description:
* Retrieves data from the FIFOs for all steps in the given sample sequencer. * Retrieves data from the FIFOs for all steps in the given sample
* The input data buffer MUST be as large or larger than the sample sequencer. * sequencer.
* otherwise * The input data buffer MUST be as large or larger than the sample
* sequencer. otherwise
* *
* Input Parameters: * Input Parameters:
* adc - peripheral state * adc - peripheral state
@ -593,7 +595,8 @@ void tiva_adc_sse_priority(uint8_t adc, uint8_t sse, uint8_t priority);
* *
****************************************************************************/ ****************************************************************************/
void tiva_adc_sse_register_chn(uint8_t adc, uint8_t sse, uint8_t chn, uint32_t ain); void tiva_adc_sse_register_chn(uint8_t adc, uint8_t sse, uint8_t chn,
uint32_t ain);
/**************************************************************************** /****************************************************************************
* Name: tiva_adc_sse_differential * Name: tiva_adc_sse_differential
@ -609,7 +612,8 @@ void tiva_adc_sse_register_chn(uint8_t adc, uint8_t sse, uint8_t chn, uint32_t a
* *
****************************************************************************/ ****************************************************************************/
void tiva_adc_sse_differential(uint8_t adc, uint8_t sse, uint8_t chn, uint32_t diff); void tiva_adc_sse_differential(uint8_t adc, uint8_t sse, uint8_t chn,
uint32_t diff);
/**************************************************************************** /****************************************************************************
* Name: tiva_adc_sse_sample_hold_time * Name: tiva_adc_sse_sample_hold_time
@ -629,7 +633,8 @@ void tiva_adc_sse_differential(uint8_t adc, uint8_t sse, uint8_t chn, uint32_t d
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_EXPERIMENTAL #ifdef CONFIG_EXPERIMENTAL
void tiva_adc_sse_sample_hold_time(uint8_t adc, uint8_t sse, uint8_t chn, uint32_t shold); void tiva_adc_sse_sample_hold_time(uint8_t adc, uint8_t sse, uint8_t chn,
uint32_t shold);
#endif #endif
/**************************************************************************** /****************************************************************************
@ -647,8 +652,8 @@ void tiva_adc_sse_sample_hold_time(uint8_t adc, uint8_t sse, uint8_t chn, uint32
* -*Comparator/Differential select: The analog input is differentially * -*Comparator/Differential select: The analog input is differentially
* sampled. The corresponding ADCSSMUXn nibble must be set to the pair * sampled. The corresponding ADCSSMUXn nibble must be set to the pair
* number "i", where the paired inputs are "2i and 2i+1". Because the * number "i", where the paired inputs are "2i and 2i+1". Because the
* temperature sensor does not have a differential option, this bit must * temperature sensor does not have a differential option, this bit
* not be set when the TS3 bit is set. * must not be set when the TS3 bit is set.
* *
* *Comparator/Differential functionality is unsupported and ignored. * *Comparator/Differential functionality is unsupported and ignored.
* *
@ -660,7 +665,8 @@ void tiva_adc_sse_sample_hold_time(uint8_t adc, uint8_t sse, uint8_t chn, uint32
* *
****************************************************************************/ ****************************************************************************/
void tiva_adc_sse_step_cfg(uint8_t adc, uint8_t sse, uint8_t chn, uint8_t cfg); void tiva_adc_sse_step_cfg(uint8_t adc, uint8_t sse, uint8_t chn,
uint8_t cfg);
/**************************************************************************** /****************************************************************************
* Name: tiva_adc_dump_reg_cfg * Name: tiva_adc_dump_reg_cfg