STM32CubeWB icon indicating copy to clipboard operation
STM32CubeWB copied to clipboard

HAL_ADCEx_Calibration_Start does not wait for the ADC to be ready before setting calibration factor

Open motla opened this issue 2 years ago • 4 comments

Hello,

Describe the set-up Custom board with STM32WB15CCU6E STM32CubeIDE v1.10.1 STM32Cube_FW_WB_V1.14.0

Describe the bug Under certain configurations, calling HAL_ADCEx_Calibration_Start() stalls the ADC. My code works perfectly if I don't call this function. If I call it as expected after MX_ADC1_Init(), it returns no error, but it lefts the ADC with ADDIS at 1, and the ADC never disables itself as it should. Then if I try to start measures with DMA it fills the buffer with zeroes. Without calling this function it filled the buffer properly.

How To Reproduce In main():

  // Calibrate ADC
  if(HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK) {
    Error_Handler();
  }
  while(LL_ADC_IsEnabled(hadc1.Instance));
  // the while() loops indefinitely, it shouldn't because HAL_ADCEx_Calibration_Start ends with LL_ADC_Disable

Additional context I believe the calibration factor is set although the ADC is not ready yet. I found a patch that works. In this function: https://github.com/STMicroelectronics/STM32CubeWB/blob/83aacadecbd5136ad3194f39e002ff50a5439ad9/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_adc_ex.c#L198-L201

Just add lines that waits for the ADC to be ready:

  /* Apply calibration factor */
  LL_ADC_Enable(hadc->Instance);
  while(!LL_ADC_IsActiveFlag_ADRDY(hadc->Instance));
  LL_ADC_SetCalibrationFactor(hadc->Instance, calibration_factor_accumulated);
  LL_ADC_Disable(hadc->Instance);
  while(LL_ADC_IsEnabled(hadc->Instance));

Or even better, replace LL functions by their HAL equivalents that do the job of waiting. I believe this is what should have been written instead:

  /* Apply calibration factor */
  ADC_Enable(hadc);
  LL_ADC_SetCalibrationFactor(hadc->Instance, calibration_factor_accumulated);
  ADC_Disable(hadc);

I can provide you other details of the clock configurations etc if you can't reproduce the bug.

motla avatar Jul 25 '22 18:07 motla

Small addition if you can't reproduce the bug, try to initialize the ADC with the highest prescaler value.

motla avatar Jul 26 '22 17:07 motla

Hi @motla,

We have tried to reproduce the issue without success. Would you please give us more details about the configuration and if possible share the whole project.

Actually, the ADC_SingleConversion_TriggerTimer_DMA project delivered within the STM32CubeWB seems to be accurate with your use case and it is working properly. Would you please try to test it and check if you are having the same behavior or not ?

With regards,

ASELSTM avatar Aug 09 '22 11:08 ASELSTM

I reliably see on this STM32WLE5 LoRaWAN firmware - do you still need a test-case?

danak6jq avatar Sep 11 '22 20:09 danak6jq

@ASELSTM sorry for the late reply, I've been quite busy.

Actually, the ADC_SingleConversion_TriggerTimer_DMA project delivered within the STM32CubeWB seems to be accurate with your use case and it is working properly.

You probably didn't see my second message Small addition if you can't reproduce the bug, try to initialize the ADC with the highest prescaler value..

It should not be my job to do that, but anyways I'll have to give you the exact baby steps in order for you to reproduce the bug, so you can correct it:

  • I got a NUCLEO-WB15CC, I guess it works for every board
  • Open the ADC_SingleConversion_TriggerTimer_DMA example you mentioned
  • In the main.c, in the main() function add while(LL_ADC_IsEnabled(hadc1.Instance)); just after ADC Calibration, on line 158.
  • Run the program in debug, the program should run fine as expected (the LED should blink quickly).
  • Now with the same code go to the .ioc file, go to the ADC settings, and change the prescaler to the highest value:

conf

  • Save the .ioc / regenerate the STM32Cube initialization code
  • Now run the same program in debug, it should get stuck at the line you added (if you remove the line, the program seems to run fine but actually the ADC is stalled and doesn't capture any data, as explained in the OP. however if you remove the calibration, it runs fine uncalibrated).
  • You can find the correcting patch and explanation in the OP, I already did the job

I noticed the issue has also been reported by someone else for STM32CubeWL, 3 months ago in Community Forums: https://community.st.com/s/question/0D53W00001aJM92SAG/stm32cubewlv120-haladcexcalibrationstart-does-not-work

So please fix it for any other potential faulty libraries as well.

Thank you!

motla avatar Sep 17 '22 16:09 motla

Hi @motla,

This issue has been fixed in the frame of version v1.15.0 of the STM32CubeWB. Please allow me then to close this thread.

With regards,

ASELSTM avatar Jul 03 '23 13:07 ASELSTM