STM32H745 ADC Oversample bug in HAL
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();
}
