AnsweredAssumed Answered

STM32L4 ADC Initialization Problem

Question asked by Doug Kehn on Jul 15, 2016
Latest reply on Jan 13, 2017 by Jeanne Joly
Hi All,

I'm using STM32L475, STM32CubeMX 4.15.1, STM32L4 firmware library 1.5.1 and the code generated by STM32CubeMX. When initializing ADC1 and ADC2 the ADC2 initialization, MX_ADC2_Init(), sometimes calls ErrorHandler() because HAL_ADCEx_MultiModeConfigChannel() is returning and error.

HAL_ADCEx_MultiModeConfigChannel(), stm32l4xx_hal_adc_ex.c, is called with hadc->Instance = ADC2; therefore, ADC_MULTI_SLAVE(hadc, &tmphadcSlave) sets tmphadcSlave->Instance = NULL. When ADC_IS_CONVERSION_ONGOING_REGULAR(&tmphadcSlave) is called a NULL pointer, tmphadcSlave->Instance->CR, is dereferenced and leads to unexpected results.

The NULL pointer deference can be fixed by changing macro ADC_IS_CONVERSION_ONGOING_REGULAR, stm32l4xx_hal_adc.h, to

#define ADC_IS_CONVERSION_ONGOING_REGULAR(__HANDLE__)                                         \
       (( !(__HANDLE__)->Instance || (((__HANDLE__)->Instance->CR) & ADC_CR_ADSTART) == RESET \
        ) ? RESET : SET)

With this change ADC_IS_CONVERSION_ONGOING_REGULAR will return RESET when Instance is NULL.

HAL_ADCEx_MultiModeConfigChannel() also calls macro ADC_IS_ENABLE(&tmphadcSlave). ADC_IS_ENABLE should also check for NULL before using tmphadcSlave->Instance.

#define ADC_IS_ENABLE(__HANDLE__)                                                           \
       (( (__HANDLE__)->Instance                                                         && \
          ((((__HANDLE__)->Instance->CR) & (ADC_CR_ADEN | ADC_CR_ADDIS)) == ADC_CR_ADEN) && \
          ((((__HANDLE__)->Instance->ISR) & ADC_FLAG_RDY) == ADC_FLAG_RDY)                  \
        ) ? SET : RESET)

Is this analysis and resolution correct? I believe returning RESET is appropriate when Instance = NULL. Also, updating the macros seemed cleaner than adding NULL checks to the source; but this is debatable.

Thanks and Regards,