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

11 REPLIES 11
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)); 

 

Hi @Imen.D ,

We surely can agree on that "fixing" this issue in Cube is irrelevant, and it outght to be properly documented, as an erratum together with a correctly and completely described workaround.

Since you've posted above, several 'G0 Errata have been published, e.g. ES0418 for 'G071, and I can't see mentioned issue in those.

So naturally, several questions arise:

- is this issue related to all 'G0 or only to 'G0B0/'G0B1/'G0C1?

- is this issue related to any other STM32 family, or is it 'G0-specific only?

- in the workaround you write "maximum 256 processor cycles worst case" yet 2 ADC cycles with 256 prescaler that would be 512 processor cycles (also see next item), wouldn't it?

- given flexibility of ADC source, talking about "processor cycles" in workaround is IMO entirely incorrect. ADC clock may be asynchronous to processor/system clock (btw. the description of what PCLK is in context of ADC, is a real mess at various points of RM and would really need thorough revision).

- is any workaround available which would be based entirely on ADC registers reads/writes and would ensure the required delay? This would make the clocking discussion above less important.

- @DAlbe.3 above mentions a need for delay *not* between ADC enable and disable, as you've said, but between ADC disable and calibration. So, does the problem pertain to this combination of operations, too? And also to any other combination of operations?

Can you please comment on these?

Thanks,

JW

Imen.D
ST Employee

Hello @DAlbe.3 , @waclawek.jan ,

Thank you for sharing your feedback. Please find below more clarification:

So naturally, several questions arise:
      - is this issue related to all 'G0 or only to 'G0B0/'G0B1/'G0C1?
      - is this issue related to any other STM32 family, or is it 'G0-specific only?
This issue is related to a specific ADC peripheral version present on STM32G0, STM32WL, STM32C0 (all products within these series).

      - in the workaround you write "maximum 256 processor cycles worst case" yet 2 ADC cycles with 256 prescaler that would be 512 processor cycles (also see next item), wouldn't it?
You're right, it's a typo error with number 256 in my previous post, which should be 512.

      - given flexibility of ADC source, talking about "processor cycles" in workaround is IMO entirely incorrect. ADC clock may be asynchronous to processor/system clock (btw. the description of what PCLK is in context of ADC, is a real mess at various points of RM and would really need thorough revision).
This is correct, the delay unit is ADC kernel clock cycles (2 cycles).

- The delay implemented in HAL driver is based on code execution loop, therefore count in CPU cycles.
- An alternate solution could be a delay based on a timer (SysTick, timer peripheral, …)
About PLCK: this is clock of bus APB (The reference manual mentions:

" The HCLK clock and PCLK clock are used for clocking the AHB and the APB domains, respectively.
The peripherals are clocked with the clocks from the bus they are attached to (HCLK for AHB, PCLK for APB) except:"
So, ADC kernel clock can be derived from PCLK or other clock source, with frequency divided through a prescaler.

      - is any workaround available which would be based entirely on ADC registers reads/writes and would ensure the required delay? This would make the clocking discussion above less important.
The timing constraint comes from interface between bus clock (APB) and ADC peripheral (synchronization constraint). Since upstream of ADC, status based on ADC registers is not possible.
      - @DAlbe.3 above mentions a need for delay *not* between ADC enable and disable, as you've said, but between ADC disable and calibration. So, does the problem pertain to this combination of operations, too? And also to any other combination of operations?
In fact, the delay is required for ADC disable to be effective (therefore, applicable between ADC disable and calibration start, or between ADC disable and calibration factor set).

Based on your feedback, a request is ongoing to update the impacted Reference manuals with the missing information about delay.

@waclawek.jan Thank you again for the continued feedback; it is much appreciated!

Hope I answered your questions.

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

Hi @Imen.D ,

Thanks for the extensive reply.

I need some time to digest this... 🙂

JW