Skip to main content
Visitor II
August 18, 2023
Solved

STM32H745 ADC Oversample bug in HAL

  • August 18, 2023
  • 3 replies
  • 1707 views

Hello, I wanted to share an issue I found with enabling the oversampler for ADC using HAL. I was having issues result not being bit shifted. Further investigation I found that the HAL driver version 1.11 did not write the OVSS bits correctly. Here is the original code found in the stm32h7xx_hal_adc.c lines 760-765

MODIFY_REG(hadc->Instance->CFGR2, ADC_CFGR2_FIELDS,
ADC_CFGR2_ROVSE |
((hadc->Init.Oversampling.Ratio - 1UL) << ADC_CFGR2_OVSR_Pos) |
hadc->Init.Oversampling.RightBitShift |
hadc->Init.Oversampling.TriggeredMode |
hadc->Init.Oversampling.OversamplingStopReset);

 I modified the code to this

MODIFY_REG(hadc->Instance->CFGR2, ADC_CFGR2_FIELDS,
ADC_CFGR2_ROVSE |
((hadc->Init.Oversampling.Ratio - 1UL) << ADC_CFGR2_OVSR_Pos) |
hadc->Init.Oversampling.RightBitShift << ADC_CFGR2_OVSS_Pos |
hadc->Init.Oversampling.TriggeredMode << ADC_CFGR2_TROVS_Pos |
hadc->Init.Oversampling.OversamplingStopReset

With this modification I verified that the CFGR2 register was written correctly and my conversion results were valid.
For reference this is the code to setup the ADC

hadc3.Instance = ADC3;
hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
hadc3.Init.Resolution = ADC_RESOLUTION_16B;
hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc3.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc3.Init.LowPowerAutoWait = DISABLE;
hadc3.Init.ContinuousConvMode = DISABLE;
hadc3.Init.NbrOfConversion = 1;
hadc3.Init.DiscontinuousConvMode = DISABLE;
hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;//ADC_CONVERSIONDATA_DMA_CIRCULAR;
hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED;//ADC_OVR_DATA_OVERWRITTEN;
hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
hadc3.Init.Oversampling.Ratio = 16;
hadc3.Init.Oversampling.RightBitShift = 4;
hadc3.Init.OversamplingMode = ENABLE;
hadc3.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;

if (HAL_ADC_Init(&hadc3) != HAL_OK)
{
main_error_handler();
}

 

    This topic has been closed for replies.
    Best answer by KDJEM.1

    Hello @KVan .2 ,

     

    The issue is fixed in STM32CubeIDE1.16.0 and STM32Cube MX 6.12.0 versions.

     

    Thank you.

    Kaouthar

    3 replies

    Super User
    August 18, 2023

    I think there's a misunderstanding of the RightBitShift field. The valid values for that are already adjusted for the offset of the OFSS field.

     uint32_t RightBitShift; /*!< Configures the division coefficient for the Oversampler.
     This parameter can be a value of @ref ADC_HAL_EC_OVS_SHIFT */
    /** @defgroup ADC_HAL_EC_OVS_SHIFT Oversampling - Data shift
     * @{
     */
    #define ADC_RIGHTBITSHIFT_NONE (LL_ADC_OVS_SHIFT_NONE) /*!< ADC oversampling no shift (sum of the ADC conversions data is not divided to result as the ADC oversampling conversion data) */
    #define ADC_RIGHTBITSHIFT_1 (LL_ADC_OVS_SHIFT_RIGHT_1) /*!< ADC oversampling shift of 1 (sum of the ADC conversions data is divided by 2 to result as the ADC oversampling conversion data) */
    #define ADC_RIGHTBITSHIFT_2 (LL_ADC_OVS_SHIFT_RIGHT_2) /*!< ADC oversampling shift of 2 (sum of the ADC conversions data is divided by 4 to result as the ADC oversampling conversion data) */
    ...
    /** @defgroup ADC_LL_EC_OVS_SHIFT Oversampling - Data shift
     * @{
     */
    #define LL_ADC_OVS_SHIFT_NONE (0x00000000UL) /*!< ADC oversampling no shift (sum of the ADC conversions data is not divided to result as the ADC oversampling conversion data) */
    #define LL_ADC_OVS_SHIFT_RIGHT_1 ( ADC_CFGR2_OVSS_0) /*!< ADC oversampling shift of 1 (sum of the ADC conversions data is divided by 2 to result as the ADC oversampling conversion data) */
    #define LL_ADC_OVS_SHIFT_RIGHT_2 ( ADC_CFGR2_OVSS_1 ) /*!< ADC oversampling shift of 2 (sum of the ADC conversions data is divided by 4 to result as the ADC oversampling conversion data) */
    ...

    The value "4" isn't a valid value. It won't pass the check in IS_ADC_RIGHT_BIT_SHIFT.

    /**
     * @brief Verify the ADC oversampling shift.
     * @PAram __SHIFT__ programmed ADC oversampling shift.
     * @retval SET (__SHIFT__ is a valid value) or RESET (__SHIFT__ is invalid)
     */
    #define IS_ADC_RIGHT_BIT_SHIFT(__SHIFT__) (((__SHIFT__) == ADC_RIGHTBITSHIFT_NONE) || \
     ((__SHIFT__) == ADC_RIGHTBITSHIFT_1 ) || \
     ((__SHIFT__) == ADC_RIGHTBITSHIFT_2 ) || \
     ((__SHIFT__) == ADC_RIGHTBITSHIFT_3 ) || \
     ((__SHIFT__) == ADC_RIGHTBITSHIFT_4 ) || \
     ((__SHIFT__) == ADC_RIGHTBITSHIFT_5 ) || \
     ((__SHIFT__) == ADC_RIGHTBITSHIFT_6 ) || \
     ((__SHIFT__) == ADC_RIGHTBITSHIFT_7 ) || \
     ((__SHIFT__) == ADC_RIGHTBITSHIFT_8 ) || \
     ((__SHIFT__) == ADC_RIGHTBITSHIFT_9 ) || \
     ((__SHIFT__) == ADC_RIGHTBITSHIFT_10 ) || \
     ((__SHIFT__) == ADC_RIGHTBITSHIFT_11 ))

     

    Technical Moderator
    October 12, 2023

    Hello @KVan .2 ,

    I reported the issue internally.

    Internal ticket number: 176763 (This is an internal tracking number and is not accessible or usable by customers).

    Thank you.

    Kaouthar

    KDJEM.1Answer
    Technical Moderator
    July 12, 2024

    Hello @KVan .2 ,

     

    The issue is fixed in STM32CubeIDE1.16.0 and STM32Cube MX 6.12.0 versions.

     

    Thank you.

    Kaouthar