Skip to content

Commit d877047

Browse files
committed
[ADC] Harden adc_read_value()
Signed-off-by: Frederic.Pillon <[email protected]>
1 parent d7c6b8b commit d877047

File tree

1 file changed

+91
-44
lines changed

1 file changed

+91
-44
lines changed

cores/arduino/stm32/analog.c

+91-44
Original file line numberDiff line numberDiff line change
@@ -518,53 +518,87 @@ uint16_t adc_read_value(PinName pin)
518518
return 0;
519519
}
520520

521-
#ifndef STM32F1xx
522-
AdcHandle.Init.ClockPrescaler = ADC_CLOCK_DIV; /* Asynchronous clock mode, input ADC clock divided */
521+
#ifdef ADC_CLOCK_DIV
522+
AdcHandle.Init.ClockPrescaler = ADC_CLOCK_DIV; /* (A)synchronous clock mode, input ADC clock divided */
523+
#endif
524+
#ifdef ADC_RESOLUTION_12B
523525
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* 12-bit resolution for converted data */
524-
AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC flag picked-up to indicate conversion end */
525-
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
526-
#ifdef STM32H7xx
527-
AdcHandle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; /* Regular Conversion data stored in DR register only */
528-
#else
529-
AdcHandle.Init.DMAContinuousRequests = DISABLE; /* DMA one-shot mode selected (not applied to this example) */
530-
#endif /* STM32H7xx */
531-
#endif /* STM32F1xx */
532-
#ifndef STM32H7xx
526+
#endif
527+
#ifdef ADC_DATAALIGN_RIGHT
533528
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */
534-
#endif /* !STM32H7xx */
529+
#endif
535530
AdcHandle.Init.ScanConvMode = DISABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
531+
#ifdef ADC_EOC_SINGLE_CONV
532+
AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC flag picked-up to indicate conversion end */
533+
#endif
534+
#if !defined(STM32F1xx) && !defined(STM32F2xx) && !defined(STM32F4xx) && \
535+
!defined(STM32F7xx) && !defined(STM32F373xC) && !defined(STM32F378xx)
536+
AdcHandle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */
537+
#endif
538+
#if !defined(STM32F1xx) && !defined(STM32F2xx) && !defined(STM32F3xx) && \
539+
!defined(STM32F4xx) && !defined(STM32F7xx) && !defined(STM32H7xx) && \
540+
!defined(STM32L4xx) && !defined(STM32WBxx)
541+
AdcHandle.Init.LowPowerAutoPowerOff = DISABLE; /* ADC automatically powers-off after a conversion and automatically wakes-up when a new conversion is triggered */
542+
#endif
543+
#ifdef ADC_CHANNELS_BANK_A
544+
AdcHandle.Init.ChannelsBank = ADC_CHANNELS_BANK_A;
545+
#endif
536546
AdcHandle.Init.ContinuousConvMode = DISABLE; /* Continuous mode disabled to have only 1 conversion at each conversion trig */
547+
#if !defined(STM32F0xx) && !defined(STM32L0xx)
548+
AdcHandle.Init.NbrOfConversion = 1; /* Specifies the number of ranks that will be converted within the regular group sequencer. */
549+
#endif
537550
AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */
551+
#if !defined(STM32F0xx) && !defined(STM32G0xx) && !defined(STM32L0xx)
552+
AdcHandle.Init.NbrOfDiscConversion = 0; /* Parameter discarded because sequencer is disabled */
553+
#endif
538554
AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* Software start to trig the 1st conversion manually, without external event */
539-
AdcHandle.State = HAL_ADC_STATE_RESET;
540-
#if defined (STM32F0xx) || defined(STM32G0xx) || defined (STM32L0xx)
541-
AdcHandle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */
542-
AdcHandle.Init.LowPowerAutoPowerOff = DISABLE; /* ADC automatically powers-off after a conversion and automatically wakes-up when a new conversion is triggered */
555+
#if !defined(STM32F1xx)
556+
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
557+
#endif
558+
#if !defined(STM32F1xx) && !defined(STM32H7xx) && \
559+
!defined(STM32F373xC) && !defined(STM32F378xx)
560+
AdcHandle.Init.DMAContinuousRequests = DISABLE; /* DMA one-shot mode selected (not applied to this example) */
561+
#endif
562+
#ifdef ADC_CONVERSIONDATA_DR
563+
AdcHandle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; /* Regular Conversion data stored in DR register only */
564+
#endif
565+
#ifdef ADC_OVR_DATA_OVERWRITTEN
543566
AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* DR register is overwritten with the last conversion result in case of overrun */
544-
#ifdef STM32F0xx
567+
#endif
568+
#ifdef ADC_LEFTBITSHIFT_NONE
569+
AdcHandle.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; /* No bit shift left applied on the final ADC convesion data */
570+
#endif
571+
572+
#if defined(STM32F0xx)
545573
AdcHandle.Init.SamplingTimeCommon = SAMPLINGTIME;
546-
#elif STM32G0xx
574+
#endif
575+
#if defined(STM32G0xx)
547576
AdcHandle.Init.SamplingTimeCommon1 = SAMPLINGTIME; /* Set sampling time common to a group of channels. */
548577
AdcHandle.Init.SamplingTimeCommon2 = SAMPLINGTIME; /* Set sampling time common to a group of channels, second common setting possible.*/
549-
AdcHandle.Init.OversamplingMode = DISABLE;
550578
AdcHandle.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
551-
#else
552-
//LowPowerFrequencyMode to enable if clk freq < 2.8Mhz
579+
#endif
580+
#if defined(STM32L0xx)
581+
AdcHandle.Init.LowPowerFrequencyMode = DISABLE; /* To be enabled only if ADC clock < 2.8 MHz */
553582
AdcHandle.Init.SamplingTime = SAMPLINGTIME;
554-
#endif /* STM32F0xx */
555-
#else
556-
#if defined (STM32F3xx) || defined (STM32H7xx)
557-
AdcHandle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */
558-
#ifndef STM32H7xx
559-
AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* DR register is overwritten with the last conversion result in case of overrun */
560-
#endif /* !STM32H7xx */
561-
#endif /* STM32F3xx || STM32H7xx */
562-
AdcHandle.Init.NbrOfDiscConversion = 0; /* Parameter discarded because sequencer is disabled */
563-
#endif /* STM32F0xx || STM32G0xx || STM32L0xx */
564-
565-
#if !defined (STM32F0xx) && !defined (STM32L0xx)
566-
AdcHandle.Init.NbrOfConversion = 1; /* Specifies the number of ranks that will be converted within the regular group sequencer. */
567583
#endif
584+
#if !defined(STM32F0xx) && !defined(STM32F1xx) && !defined(STM32F2xx) && \
585+
!defined(STM32F3xx) && !defined(STM32F4xx) && !defined(STM32F7xx) && \
586+
!defined(STM32L1xx)
587+
AdcHandle.Init.OversamplingMode = DISABLE;
588+
/* AdcHandle.Init.Oversample ignore for STM32L0xx as oversampling disabled */
589+
/* AdcHandle.Init.Oversampling ignored for other as oversampling disabled */
590+
#endif
591+
#if defined(ADC_CFGR_DFSDMCFG) && defined(DFSDM1_Channel0)
592+
AdcHandle.Init.DFSDMConfig = ADC_DFSDM_MODE_DISABLE; /* ADC conversions are not transferred by DFSDM. */
593+
#endif
594+
#ifdef ADC_TRIGGER_FREQ_HIGH
595+
AdcHandle.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
596+
#endif
597+
598+
AdcHandle.State = HAL_ADC_STATE_RESET;
599+
AdcHandle.DMA_Handle = NULL;
600+
AdcHandle.Lock = HAL_UNLOCKED;
601+
/* Some other ADC_HandleTypeDef fields exists but not required */
568602

569603
g_current_pin = pin; /* Needed for HAL_ADC_MspInit*/
570604

@@ -581,31 +615,44 @@ uint16_t adc_read_value(PinName pin)
581615
if (!IS_ADC_CHANNEL(AdcChannelConf.Channel)) {
582616
return 0;
583617
}
584-
#endif /* STM32L4xx */
618+
#endif /* STM32L4xx || STM32WBxx */
585619
AdcChannelConf.Rank = ADC_REGULAR_RANK_1; /* Specifies the rank in the regular group sequencer */
586-
#ifndef STM32L0xx
587-
#if defined (STM32G0xx)
588-
AdcChannelConf.SamplingTime = ADC_SAMPLINGTIME_COMMON_1; /* Sampling time value to be set for the selected channel */
589-
#else
620+
#if !defined(STM32L0xx)
621+
#if !defined(STM32G0xx)
590622
AdcChannelConf.SamplingTime = SAMPLINGTIME; /* Sampling time value to be set for the selected channel */
623+
#else
624+
AdcChannelConf.SamplingTime = ADC_SAMPLINGTIME_COMMON_1; /* Sampling time value to be set for the selected channel */
591625
#endif
592626
#endif
593-
#if defined (STM32F3xx) || defined (STM32L4xx) || defined (STM32H7xx) || defined(STM32WBxx)
627+
#if !defined(STM32F0xx) && !defined(STM32F1xx) && !defined(STM32F2xx) && \
628+
!defined(STM32F4xx) && !defined(STM32F7xx) && !defined(STM32G0xx) && \
629+
!defined(STM32L0xx) && !defined(STM32L1xx) && \
630+
!defined(STM32F373xC) && !defined(STM32F378xx)
594631
AdcChannelConf.SingleDiff = ADC_SINGLE_ENDED; /* Single-ended input channel */
595632
AdcChannelConf.OffsetNumber = ADC_OFFSET_NONE; /* No offset subtraction */
633+
#endif
634+
#if !defined(STM32F0xx) && !defined(STM32F1xx) && !defined(STM32F2xx) && \
635+
!defined(STM32G0xx) && !defined(STM32L0xx) && !defined(STM32L1xx) && \
636+
!defined(STM32WBxx) && !defined(STM32F373xC) && !defined(STM32F378xx)
596637
AdcChannelConf.Offset = 0; /* Parameter discarded because offset correction is disabled */
597638
#endif
639+
#if defined (STM32H7xx)
640+
AdcChannelConf.OffsetRightShift = DISABLE; /* No Right Offset Shift */
641+
AdcChannelConf.OffsetSignedSaturation = DISABLE; /* Signed saturation feature is not used */
642+
#endif
643+
598644
/*##-2- Configure ADC regular channel ######################################*/
599645
if (HAL_ADC_ConfigChannel(&AdcHandle, &AdcChannelConf) != HAL_OK) {
600646
/* Channel Configuration Error */
601647
return 0;
602648
}
603649

604-
#if defined (STM32F0xx) || defined (STM32F1xx) || defined (STM32F3xx) ||\
605-
defined (STM32H7xx) || defined (STM32G0xx) || defined (STM32L0xx) ||\
606-
defined (STM32L4xx) || defined(STM32WBxx)
650+
#if defined(STM32F0xx) || defined(STM32F1xx) || defined(STM32F3xx) || \
651+
defined(STM32G0xx) || defined(STM32H7xx) || defined(STM32L0xx) || \
652+
defined(STM32L4xx) || defined(STM32WBxx)
607653
/*##-2.1- Calibrate ADC then Start the conversion process ####################*/
608-
#if defined (STM32F0xx) || defined (STM32G0xx) || defined (STM32F1xx)
654+
#if defined(STM32F0xx) || defined(STM32G0xx) || defined(STM32F1xx) || \
655+
defined(STM32F373xC) || defined(STM32F378xx)
609656
if (HAL_ADCEx_Calibration_Start(&AdcHandle) != HAL_OK)
610657
#elif defined (STM32H7xx)
611658
if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK)

0 commit comments

Comments
 (0)