Skip to main content
Kilian Nötzold
Associate III
August 18, 2018
Question

Bug in STM32H7 HAL for ADC Injected Channel 18

  • August 18, 2018
  • 6 replies
  • 1438 views

When for ADC2 Channel 18 is selected as Injected Channel and initialized via “HAL_ADCEx_InjectedConfigChannel�? it will return HAL_ERROR.

When no other ADC it will fail in line 2288 2286*. When another ADC is enabled it will fail in line 2277 2275*.

HAL File: stm32h7xx_hal_adc_ex.c

HAL Version: V1.2.0 V1.3.0

I think the block from line 2229 2227* to 2290 2288* should be included in the else in line 2223 2221*.

Btw the comment in line 2245 2243* is wrong the Temp. sensor it is channel 18

It can easily reproduce by code generation of STM32CubeMX.

1.     Enable ADC2 -> In18

2.     Config ADC2 In18 as Injected Channel

Or use the attached CubeMX project.

*edit for Version V1.3.0

Thanks

    This topic has been closed for replies.

    6 replies

    Tesla DeLorean
    Guru
    August 18, 2018

    >>HAL Version: V1.2.0

    Not current, check if it was addressed in V1.3.0

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Kilian Nötzold
    Associate III
    August 19, 2018

    Hello Clive,

    tanks for the info. Unfortunately V1.3.0 it shows the same behavior.

    I have edited the line numbers in the previous post to match the new version.

    Tesla DeLorean
    Guru
    August 19, 2018

    @STOne-32​ @Imen DAHMEN​ ​ 

    STM32Cube_FW_H7_V1.3.0\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_adc.c

    Quarter Battery is CH17, and not on ADC1

             /* If Channel 18 is selected, enable VBAT measurement path.          */

             /* Note: VBAT internal internal channels available on ADC1 and ADC3  */

             else if ((sConfig->Channel == ADC_CHANNEL_VBAT_DIV4) && ((hadc->Instance == ADC3)))

             {

               SET_BIT(tmpADC_Common->CCR, ADC_CCR_VBATEN);

             }

    STM32Cube_FW_H7_V1.3.0\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_adc_ex.c

    All channels wrongly commented

           /* If Channel 17 is selected, enable Temp. sensor measurement path   */

           /* Note: Temp. sensor internal channels available only on ADC3       */

           if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) &&

               (hadc->Instance == ADC3))

           {

             SET_BIT(tmpADC_Common->CCR, ADC_CCR_TSEN);

             /* Delay for temperature sensor stabilization time */

             while(WaitLoopIndex < ADC_TEMPSENSOR_DELAY_US)

             {

               WaitLoopIndex++;

             }

           }

           /* If Channel 18 is selected, enable VBAT measurement path           */

           /* Note: VBAT internal internal channels available only on ADC3      */

           else if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT_DIV4) &&

                    (hadc->Instance == ADC3))

           {

             SET_BIT(tmpADC_Common->CCR, ADC_CCR_VBATEN);

           }

           /* If Channel 0 is selected, enable VREFINT measurement path         */

           /* Note: VREFINT internal channels available only on ADC3            */

           else if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) &&

                    (hadc->Instance == ADC3))

           {

             SET_BIT(tmpADC_Common->CCR, ADC_CCR_VREFEN);

           }

           else

           {

             /* Discrepancy found out between ADC instance and internal

                channel request */

             SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);

             tmp_hal_status = HAL_ERROR;

           }

    The error reported above occurs because the top level test doesn't qualify for ADC3 and it causes a drop through to a HAL_ERROR

       /* If the requested internal measurement path has already been enabled,  */

       /* bypass the configuration processing.                                  */

       if (( (sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) &&

             (HAL_IS_BIT_CLR(tmpADC_Common->CCR, ADC_CCR_TSEN))           ) ||

           ( (sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT_DIV4)      &&

             (HAL_IS_BIT_CLR(tmpADC_Common->CCR, ADC_CCR_VBATEN))         ) ||

           ( (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT)   &&

             (HAL_IS_BIT_CLR(tmpADC_Common->CCR, ADC_CCR_VREFEN)))

          )

       {

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Tesla DeLorean
    Guru
    August 19, 2018

       /* If the requested internal measurement path has already been enabled,  */

       /* bypass the configuration processing.                                  */

       if (( (sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) &&

             (HAL_IS_BIT_CLR(tmpADC_Common->CCR, ADC_CCR_TSEN))           ) ||

           ( (sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT_DIV4)      &&

             (HAL_IS_BIT_CLR(tmpADC_Common->CCR, ADC_CCR_VBATEN))         ) ||

           ( (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT)   &&

             (HAL_IS_BIT_CLR(tmpADC_Common->CCR, ADC_CCR_VREFEN)))

          )

       {

         /* Configuration of common ADC parameters (continuation)               */

         /* Software is allowed to change common parameters only when all ADCs  */

         /* of the common group are disabled.                                   */

         if ((ADC_IS_ENABLE(hadc) == RESET)  &&

             (ADC_ANY_OTHER_ENABLED(hadc) == RESET) )

         {

           /* If Channel 17 is selected, enable Temp. sensor measurement path   */

           /* Note: Temp. sensor internal channels available only on ADC3       */

           if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) &&

               (hadc->Instance == ADC3))

           {

             SET_BIT(tmpADC_Common->CCR, ADC_CCR_TSEN);

             /* Delay for temperature sensor stabilization time */

             while(WaitLoopIndex < ADC_TEMPSENSOR_DELAY_US)

             {

               WaitLoopIndex++;

             }

           }

           /* If Channel 18 is selected, enable VBAT measurement path           */

           /* Note: VBAT internal internal channels available only on ADC3      */

           else if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT_DIV4) &&

                    (hadc->Instance == ADC3))

           {

             SET_BIT(tmpADC_Common->CCR, ADC_CCR_VBATEN);

           }

           /* If Channel 0 is selected, enable VREFINT measurement path         */

           /* Note: VREFINT internal channels available only on ADC3            */

           else if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) &&

                    (hadc->Instance == ADC3))

           {

             SET_BIT(tmpADC_Common->CCR, ADC_CCR_VREFEN);

           }

           else

           {

             /* Discrepancy found out between ADC instance and internal

                channel request */

             SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);

             tmp_hal_status = HAL_ERROR;

           }

         }

         /* If the requested internal measurement path has already been enabled */

         /* and other ADC of the common group are enabled, internal             */

         /* measurement paths cannot be enabled.                                */

         else

         {

           /* Update ADC state machine to error */

           SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);

           tmp_hal_status = HAL_ERROR;

         }

       }

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Tesla DeLorean
    Guru
    August 19, 2018

    @Kilian Nötzold​ definitely a complete mess, flagged to staff.

       /* Configuration of common ADC parameters                                */

       if((hadc->Instance == ADC1) || (hadc->Instance == ADC2))

       {

         /* Pointer to the common control register                                */

         tmpADC_Common = ADC12_COMMON_REGISTER(hadc);

       }

       else

       {

         /* Pointer to the common control register                                */

         tmpADC_Common = ADC3_COMMON_REGISTER(hadc);

       } // MOVE THIS BRACE OVER/AROUND THE OFFENDING CODE FOR ADC3 BELOW

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Kilian Nötzold
    Associate III
    August 19, 2018

    @Community member​ Thanks for informing ST.

    Whoever is taking care on this topic should also check if a similar issue exists in stm32h7xx_hal_adc.c staring in line 2548 as the code looks Identical. I haven’t looked deeper into but at least the comments are messed in the same way.

    Martin Franke
    Associate II
    January 19, 2019

    FYI The same issue exists for stm32h7xx_hal_adc.c