STMicroelectronics / stm32h7xx_hal_driver

Provides the STM32Cube MCU Component "hal_driver" of the STM32H7 series.
BSD 3-Clause "New" or "Revised" License
97 stars 41 forks source link

Incorrect assertion in HAL_ADC_ConfigChannel() for STM32H7 #33

Open wouter-palmsens opened 1 year ago

wouter-palmsens commented 1 year ago

Description of the set-up

Description of the bug

The function HAL_ADC_ConfigChannel() contains the following check:

  /* if ROVSE is set, the value of the OFFSETy_EN bit in ADCx_OFRy register is
     ignored (considered as reset) */
  assert_param(!((sConfig->OffsetNumber != ADC_OFFSET_NONE) && (hadc->Init.OversamplingMode == ENABLE)));

I guess the assertion is (incorrectly) copied from the STM32L4 (or other device) HAL code, for which this check is correct. The STM32L4+ reference manual (RM0432 Rev 9) states the following, which matches the description in the code comment:

Offset correction is not supported in oversampling mode. When ROVSE and/or JOVSE bit isset, the value of the OFFSETy_EN bit in ADC_OFRy register is ignored (considered as reset).

However, according to the reference manual (RM0433 Rev 7):

The offset correction is also supported in oversampling mode.

Since the offset correction is also supported in oversampling mode on the STM32H753, this assertion is incorrect and should be removed or modified (OffsetRightShift and OffsetSignedSaturation are not supported in oversampling mode, so probably those should be checked instead).

How To Reproduce

Call HAL_ADC_ConfigChannel() with sConfig->OffsetNumber defined to another value then ADC_OFFSET_NONE (e.g. ADC_OFFSET_1) and hadc->Init.OversamplingMode set to ENABLE and USE_FULL_ASSERT defined.

RJMSTM commented 1 year ago

Hello @wouter-palmsens

Thank you for your contribution. Would it be possible to share the project you have used to reproduce the issue in order to allow a better analysis of the problem.

With regards, Rania

wouter-palmsens commented 1 year ago

Hello @RJMSTM , For obvious reasons I cannot share my full project. However, I think it's relatively easy to reproduce the issue with the information provided in the description. Any example application using ADC with oversampling can easily be adjusted to reproduce this issue. For example, the ADC_OverSampler project from the STM32CubeH7 repository.

At line 133 of main.c, change the channel configuration to for example the following (any valid configuration with sConfig.OffsetNumber != ADC_OFFSET_NONE will trigger the assert):

sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_8CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_1;  // !!!
sConfig.Offset = 0x8000;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
  Error_Handler();
}

I hope this helps.