cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H745 ADC Oversample bug in HAL

KVan .2
Associate II

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();
}

 

2 REPLIES 2
TDK
Guru

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  ))

 

If you feel a post has answered your question, please click "Accept as Solution".
KDJEM.1
ST Employee

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

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.