cancel
Showing results for 
Search instead for 
Did you mean: 

stm32cubewl_v1-2-0 HAL_ADCEx_Calibration_Start does not work

John1960
Associate II

In the middle of function returns HAL_ERROR.

stm32cubewl_v1-1-0 - the function works well.

1 ACCEPTED SOLUTION

Accepted Solutions
Philippe Cherbonnel
ST Employee

Hello,

A regression has been introduced in release v1.2.0.

Issue:

In case of high frequency ratio between CPU and ADC (CPU high frequency, ADC low frequency), function HAL_ADCEx_Calibration_Start() returns an error.

Root cause:

A delay must be fullfilled between ADC enable and ADC disable.

Fix:

In function HAL_ADCEx_Calibration_Start(), a delay must be added:

  LL_ADC_Enable(hadc->Instance);

<delay here>

  LL_ADC_SetCalibrationFactor(hadc->Instance, calibration_factor_accumulated);

  LL_ADC_Disable(hadc->Instance);

The fix will be available in next STM32WL FW package release.

Documentation is being updated to mention this constraint.

Best regards

Philippe

View solution in original post

12 REPLIES 12
John1960
Associate II

Sorry, MCU STM32WLE5

Louis AUDOLY
ST Employee

Hello and welcome @John1960​ ,

You can have a look at the example ADC_AnalogWatchdog that you can find here :

STM32Cube_FW_WL_V1.2.0\Projects\NUCLEO-WL55JC\Examples\ADC\ADC_AnalogWatchdog

In the main function there is a calibration that don't return an error.

Which code are you running ?

Best regards

John1960
Associate II

I use my own code, which use ADC. First I want to calibrate it, so I call HAL_ADCEx_Calibration_Start. 

I began from stm32cubewl_v1-1-0, and it worked well.

Then I upgaded library to stm32cubewl_v1-2-0, and the function began to return HAL_ERROR.

Functions HAL_ADCEx_Calibration_Start  from version 1.1 and from version 1.2 are extreemly different.

Part of my code - Green LED is ON:

void ADC_Init ()

{

 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;

 PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_HSI;

 if ( HAL_RCCEx_PeriphCLKConfig ( &PeriphClkInitStruct ) != HAL_OK )

  {

   Error_Handler();

  }

 /* Peripheral clock enable */

 __HAL_RCC_ADC_CLK_ENABLE();

 hadc.Instance = ADC;

 hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV64;

 hadc.Init.Resolution = ADC_RESOLUTION_12B;

 hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;

 hadc.Init.ScanConvMode = ADC_SCAN_DISABLE;

 hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

 hadc.Init.LowPowerAutoWait = DISABLE;

 hadc.Init.LowPowerAutoPowerOff = DISABLE;

 hadc.Init.ContinuousConvMode = DISABLE;

 hadc.Init.NbrOfConversion = 1;

 hadc.Init.DiscontinuousConvMode = DISABLE;

 hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;

 hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

 hadc.Init.DMAContinuousRequests = DISABLE;

 hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;

 hadc.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_160CYCLES_5;

 hadc.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;

 hadc.Init.OversamplingMode = DISABLE;

 hadc.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;

 if (HAL_ADC_Init(&hadc) != HAL_OK)

 {

  Error_Handler();

 }

 /* ADC interrupt Init */

 HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);

 HAL_NVIC_EnableIRQ(ADC_IRQn);

// return;

 if (HAL_ADCEx_Calibration_Start(&hadc) != HAL_OK)

 {

  /* Calibration Error */

 GreenLED_On ();

  Error_Handler();

 }

 } // ADC_Init

Philippe Cherbonnel
ST Employee

Hello,

A regression has been introduced in release v1.2.0.

Issue:

In case of high frequency ratio between CPU and ADC (CPU high frequency, ADC low frequency), function HAL_ADCEx_Calibration_Start() returns an error.

Root cause:

A delay must be fullfilled between ADC enable and ADC disable.

Fix:

In function HAL_ADCEx_Calibration_Start(), a delay must be added:

  LL_ADC_Enable(hadc->Instance);

<delay here>

  LL_ADC_SetCalibrationFactor(hadc->Instance, calibration_factor_accumulated);

  LL_ADC_Disable(hadc->Instance);

The fix will be available in next STM32WL FW package release.

Documentation is being updated to mention this constraint.

Best regards

Philippe

John1960
Associate II

OK

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

As above, I spin on ADRDY, no need for a timer

I reported the issue for STM32CubeWB as well.

The library already have some macros that wait for ADRDY the flag, just remove the LL_ prefix:

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

https://github.com/STMicroelectronics/STM32CubeWB/issues/59

Any notion of when the next STM32WL FW release will be available?

Holy crap - Same problem on STM32G030 chips.

The solution was posted two month ago.

Why you dont make a rollout about that?

I had searched a while to find that...

After calling the calibration function, the ADC_IT is stopped working.

No Hal_Error comes out.

@Dana Myers​ 

Your spin cycle is running really great.

Thank you for posting that!