Skip to main content
Explorer
August 8, 2024
Solved

Vrefint reads as 0 on some boards

  • August 8, 2024
  • 2 replies
  • 2123 views

I have got 3 identical boards with STM32u5a5. For improving ADC accuracy I want to calibrate Vref using Vrefint. This is working fine on one board, but on the other two boards Vrefint reads as 0 using the same software. Other ADC channels seem to work on all boards.

Vrefint has been enabled and a delay has been added giving Vrefint time to settle.

On the working device I get ADC values around 24600 for Vrefint (left aligned), on the non-working devices exactly 0.

Since everything is working fine on one device, I wonder what could be the issue on the other two devices.

    This topic has been closed for replies.
    Best answer by Amel NASRI

    Hi @Meixner ,

    In the current driver implementation, we have following sequence of code in HAL_ADCEx_Calibration_Start():

     /* Use a Data Memory Barrier instruction to avoid synchronization issues when accessing ADC registers */
     MODIFY_REG(hadc->Instance->CR, ADC_CR_CALINDEX, 0x9UL << ADC_CR_CALINDEX_Pos);
     __DMB();
     MODIFY_REG(hadc->Instance->CALFACT2, 0xFFFFFF00UL, 0x03021100UL);
     __DMB();
     SET_BIT(hadc->Instance->CALFACT, ADC_CALFACT_LATCH_COEF);
    

    Are you using an older version than 1.6.0for STM32CubeU5 firmware package?

    -Amel

    2 replies

    MeixnerAuthor
    Explorer
    August 9, 2024

    I have found a difference: On the working devices code was compiled with optimizations turned off, on the failing devices, the code was compiled with optimizations turned on in gcc.

    I have tracked down the failing code to the ADC calibration. The calibration code is essentially the same as in HAL_ADCEx_Calibration_Start(). Enabling gcc optimizations makes the code fail.

    MeixnerAuthor
    Explorer
    August 9, 2024

    Replacing

    MODIFY_REG(hadc->Instance->CR, ADC_CR_CALINDEX, 0x9UL << ADC_CR_CALINDEX_Pos);
    MODIFY_REG(hadc->Instance->CALFACT2, 0x00FF0000UL, 0x00020000UL);
    SET_BIT(hadc->Instance->CALFACT, ADC_CALFACT_LATCH_COEF);

    in HAL_ADCEx_Calibration_Start() by

    MODIFY_REG(hadc->Instance->CR, ADC_CR_CALINDEX, 0x9UL << ADC_CR_CALINDEX_Pos);
    __NOP();
    __NOP();
    MODIFY_REG(hadc->Instance->CALFACT2, 0x00FF0000UL, 0x00020000UL);
    SET_BIT(hadc->Instance->CALFACT, ADC_CALFACT_LATCH_COEF);

    fixed the issue.

    Technical Moderator
    August 9, 2024

    Hi @Meixner ,

    In the current driver implementation, we have following sequence of code in HAL_ADCEx_Calibration_Start():

     /* Use a Data Memory Barrier instruction to avoid synchronization issues when accessing ADC registers */
     MODIFY_REG(hadc->Instance->CR, ADC_CR_CALINDEX, 0x9UL << ADC_CR_CALINDEX_Pos);
     __DMB();
     MODIFY_REG(hadc->Instance->CALFACT2, 0xFFFFFF00UL, 0x03021100UL);
     __DMB();
     SET_BIT(hadc->Instance->CALFACT, ADC_CALFACT_LATCH_COEF);
    

    Are you using an older version than 1.6.0for STM32CubeU5 firmware package?

    -Amel

    Super User
    August 12, 2024

    Hi @Amel NASRI ,

    e.g.

    https://community.st.com/t5/stm32-mcus-products/adc-calibration-doesn-t-complete-on-stm32g0c1re/td-p/590459

    https://community.st.com/t5/stm32-mcus-products/adc-register-adrdy-never-sets-when-i-enable-the-adc-so-it-keeps/m-p/106159/highlight/true#M17007

    Maybe they are moot: I don't have the time/resources/abilities, nor access to the internal design, to judge and bring definitive conclusions about them.

    Maybe there are more which went below my radar. I tend to ignore ADC-related threads, as I usually can't help, because ADC is very complicated (in a usually underappreciated way) and the details differ significantly between the individual families (ADC is perhaps the most varying module of them all).

    JW