diff --git a/arch/arm/src/stm32/stm32_adc.c b/arch/arm/src/stm32/stm32_adc.c index 70fd1071cd..3b541dde8a 100644 --- a/arch/arm/src/stm32/stm32_adc.c +++ b/arch/arm/src/stm32/stm32_adc.c @@ -1666,6 +1666,7 @@ static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg) priv->current = 0; } } + } /* Restart DMA for the next conversion series */ diff --git a/arch/arm/src/stm32f7/stm32_adc.c b/arch/arm/src/stm32f7/stm32_adc.c index e4a885790d..82f7c43782 100644 --- a/arch/arm/src/stm32f7/stm32_adc.c +++ b/arch/arm/src/stm32f7/stm32_adc.c @@ -165,6 +165,26 @@ (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP8_SHIFT) | \ (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP9_SHIFT)) +/* The last external channel on ADC 1 to enable Reading Vref or Vbat / Vsence */ + +#define ADC_LAST_EXTERNAL_CHAN 15 + +/* Assuming VDC 2.4 - 3.6 */ + +#define ADC_MAX_FADC 36000000 + +#if STM32_PCLK2_FREQUENCY/2 <= ADC_MAX_FADC +# define ADC_CCR_ADCPRE_DIV ADC_CCR_ADCPRE_DIV2 +#elif STM32_PCLK2_FREQUENCY/4 <= ADC_MAX_FADC +# define ADC_CCR_ADCPRE_DIV ADC_CCR_ADCPRE_DIV4 +#elif STM32_PCLK2_FREQUENCY/6 <= ADC_MAX_FADC +# define ADC_CCR_ADCPRE_DIV ADC_CCR_ADCPRE_DIV6 +#elif STM32_PCLK2_FREQUENCY/8 <= ADC_MAX_FADC +# define ADC_CCR_ADCPRE_DIV ADC_CCR_ADCPRE_DIV8 +#else +# error "PCLK2 too high - no divisor found " +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -253,6 +273,7 @@ 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, int offset); static int adc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch); +static bool adc_internal(FAR struct stm32_dev_s * priv); #ifdef ADC_HAVE_TIMER static void adc_timstart(FAR struct stm32_dev_s *priv, bool enable); @@ -1066,19 +1087,14 @@ static void adc_rccreset(FAR struct stm32_dev_s *priv, bool reset) static void adc_enable(FAR struct stm32_dev_s *priv, bool enable) { -#ifdef ADC_SR_ADONS - bool enabled = (adc_getreg(priv, STM32_ADC_SR_OFFSET) & ADC_SR_ADONS) != 0; -#else - bool enabled = false; -#endif ainfo("enable: %d\n", enable ? 1 : 0); - if (!enabled && enable) + if (enable) { adc_modifyreg(priv, STM32_ADC_CR2_OFFSET, 0, ADC_CR2_ADON); } - else if (enabled && !enable) + else { adc_modifyreg(priv, STM32_ADC_CR2_OFFSET, ADC_CR2_ADON, 0); } @@ -1255,7 +1271,12 @@ static void adc_reset(FAR struct adc_dev_s *dev) /* ADC CCR configuration */ clrbits = ADC_CCR_ADCPRE_MASK | ADC_CCR_TSVREFE; - setbits = ADC_CCR_ADCPRE_DIV2; + setbits = ADC_CCR_ADCPRE_DIV; + + if (adc_internal(priv)) + { + setbits = ADC_CCR_TSVREFE; + } clrbits |= ADC_CCR_MULTI_MASK | ADC_CCR_DELAY_MASK | ADC_CCR_DDS | ADC_CCR_DMA_MASK | ADC_CCR_VBATE; @@ -1451,6 +1472,29 @@ static uint32_t adc_sqrbits(FAR struct stm32_dev_s *priv, int first, int last, return bits; } +/**************************************************************************** + * Name: adc_internal + ****************************************************************************/ + +static bool adc_internal(FAR struct stm32_dev_s * priv) +{ + int i; + + if (priv->intf == 1) + { + for (i = 0; i < priv->nchannels; i++) + { + if (priv->chanlist[i] > ADC_LAST_EXTERNAL_CHAN) + { + return true; + } + + } + } + + return false; +} + /**************************************************************************** * Name: adc_set_ch * @@ -1490,16 +1534,6 @@ static int adc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch) priv->nchannels = 1; } -#ifdef STM32_ADC_SQR5_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); -#endif - -#ifdef STM32_ADC_SQR4_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); -#endif - 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); @@ -1725,15 +1759,15 @@ struct adc_dev_s *stm32_adc_initialize(int intf, FAR const uint8_t *chanlist, /* Configure the selected ADC */ - priv = (FAR struct stm32_dev_s *)dev->ad_priv; - - priv->cb = NULL; + priv = (FAR struct stm32_dev_s *)dev->ad_priv; + priv->cb = NULL; DEBUGASSERT(cchannels <= ADC_MAX_SAMPLES); - if (cchannels > ADC_MAX_SAMPLES) - { - cchannels = ADC_MAX_SAMPLES; - } + if (cchannels > ADC_MAX_SAMPLES) + { + cchannels = ADC_MAX_SAMPLES; + } + priv->cchannels = cchannels; memcpy(priv->chanlist, chanlist, cchannels); diff --git a/configs/nucleo-144/src/stm32_adc.c b/configs/nucleo-144/src/stm32_adc.c index b079ebc738..f185335a7a 100644 --- a/configs/nucleo-144/src/stm32_adc.c +++ b/configs/nucleo-144/src/stm32_adc.c @@ -84,9 +84,6 @@ /************************************************************************************ * Private Data ************************************************************************************/ -/* The Olimex STM32-P405 has a 10 Kohm potentiometer AN_TR connected to PC0 - * ADC123_IN10 - */ /* Identifying number of each ADC channel: Variable Resistor. * @@ -94,7 +91,7 @@ */ #ifdef CONFIG_STM32F7_ADC1 -static const uint8_t g_chanlist[ADC1_NCHANNELS] = {1}; +static const uint8_t g_chanlist[ADC1_NCHANNELS] = {3}; /* Configurations of pins used byte each ADC channels * @@ -103,7 +100,7 @@ static const uint8_t g_chanlist[ADC1_NCHANNELS] = {1}; * GPIO_ADC1_IN11, GPIO_ADC1_IN12, GPIO_ADC1_IN13, GPIO_ADC1_IN15}; */ -static const uint32_t g_pinlist[ADC1_NCHANNELS] = {GPIO_ADC1_IN0}; +static const uint32_t g_pinlist[ADC1_NCHANNELS] = {GPIO_ADC1_IN3}; #endif /************************************************************************************ @@ -152,7 +149,10 @@ int board_adc_initialize(void) for (i = 0; i < ADC1_NCHANNELS; i++) { - stm32_configgpio(g_pinlist[i]); + if (g_pinlist[i] != 0) + { + stm32_configgpio(g_pinlist[i]); + } } /* Call stm32_adcinitialize() to get an instance of the ADC interface */