cancel
Showing results for 
Search instead for 
Did you mean: 

ADC Calibration doesn't complete on STM32G0C1RE.

BrianB
Associate II

Using HAL_ADCEx_Calibration_Start() to calibrate the ADC. This function always returns HAL_ERROR.

Debugging shows its failing after it collects the 8 samples and attempting to disable the ADC is timing out.  (ie.  if ((HAL_GetTick() - tickstart) > ADC_DISABLE_TIMEOUT) is TRUE.)

Using CubeMX to generate drivers. CubeMX version 6.8.1

Note: ADC conversion are working IF I don't calibrate.

 

Thanks for your help.

 

1 ACCEPTED SOLUTION

Accepted Solutions
Imen.D
ST Employee

Hello @BrianB,

There is an issue on STM32G0 ADC during calibration due to delay needed between ADC enable and disable.

As a work-around: A minimum delay must be implemented between ADC enable and ADC disable.

  • ADC clock presc div64: 75 CPU clock cycles <=> between 1 and 2 ADC clock cycles
  • ADC clock presc div128: 155 CPU clock cycles <=> between 1 and 2 ADC clock cycles
  • ADC clock presc div256: 315 CPU clock cycles <=> between 1 and 2 ADC clock cycles

The Fix proposal is to wait for 2 ADC clock cycles between ADC enable and disable (worst case: 256 CPU cycles) .

Our development team is very aware of this issue and working to resolve this, and the fix will be available in the next release of STM32CubeG0 firmware package.

 

Thank you for your understanding while we work on this.

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

View solution in original post

6 REPLIES 6
Imen.D
ST Employee

Hello @BrianB  and welcome to the Community,

Thank you for having reported this issue.

I check this and come back to you soon with update.

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
Issamos
Lead II

Hello @BrianB 

Have you ensured that the ADC is off because as you can see in the user manual of the STM32CUBEG0:

  • Perform an ADC automatic self-calibration Calibration prerequisite: ADC must be disabled (execute this function before HAL_ADC_Start() or after HAL_ADC_Stop() ).Screenshot_2023-09-14-13-11-47-51.jpg

Also, in other boards, if the ADC work in a low frequency that can be a cause of error for HAL_ADCEx_Calibration_Start().

Best regards.

II

Imen.D
ST Employee

Hello @BrianB,

There is an issue on STM32G0 ADC during calibration due to delay needed between ADC enable and disable.

As a work-around: A minimum delay must be implemented between ADC enable and ADC disable.

  • ADC clock presc div64: 75 CPU clock cycles <=> between 1 and 2 ADC clock cycles
  • ADC clock presc div128: 155 CPU clock cycles <=> between 1 and 2 ADC clock cycles
  • ADC clock presc div256: 315 CPU clock cycles <=> between 1 and 2 ADC clock cycles

The Fix proposal is to wait for 2 ADC clock cycles between ADC enable and disable (worst case: 256 CPU cycles) .

Our development team is very aware of this issue and working to resolve this, and the fix will be available in the next release of STM32CubeG0 firmware package.

 

Thank you for your understanding while we work on this.

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

Hi,

The problem was low ADC frequency. It was 2 Mhz. I increased the ADC frequency to 8 MHz and the ADC calibration is working correctly.

Thanks for your help.

Imen.D
ST Employee

Really glad to know you overcame this problem.

Thank you once more for your understanding and contribution.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

Thanks @Imen.D 

This really needs to be in the errata; not everyone uses the Cube firmware packages or even HAL.

I spent hours chasing this: ADC calibration often hung after hw reset without this magic delay. Inserting a small (10uS or less) delay after disabling the ADC and before starting calibration reliably cures the problem.

    // Disable ADC prior to calibration
    ADC1->CR = ADC_CR_ADDIS;
    // Wait for ADC disabled
    while (ADC1->CR & (ADC_CR_ADCAL | ADC_CR_ADSTART | 
                       ADC_CR_ADSTP | ADC_CR_ADDIS | 
                       ADC_CR_ADEN));
    // A minimum delay is required after enabling or disabling the ADC
    delay_us(10);
    // Begin calibration process
    ADC1->CR = ADC_CR_ADCAL;
    // Wait for calibration to finish
    while ((ADC1->CR & ADC_CR_ADCAL)) ;
    // Clear end-of-calibration and ready flags
    ADC1->ISR |= (ADC_ISR_EOCAL | ADC_ISR_ADRDY);
    // Enable ADC
    ADC1->CR = ADC_CR_ADEN;               
    // Wait for ADC ready
    while (!(ADC1->ISR & ADC_ISR_ADRDY));