HAL_StatusTypeDef HAL_ADC_Init()

in Drivers/STM32U5xx_HAL/Src/stm32u5xx_hal_adc.c [406:945]


HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc)
{
  HAL_StatusTypeDef tmp_hal_status = HAL_OK;
  uint32_t tmpCFGR1 = 0UL;
  uint32_t tmpCFGR2 = 0UL;
  uint32_t tmp_adc_reg_is_conversion_on_going;
  __IO uint32_t wait_loop_index;
  uint32_t tmp_adc_is_conversion_on_going_regular;
  uint32_t tmp_adc_is_conversion_on_going_injected;

  /* Check ADC handle */
  if (hadc == NULL)
  {
    return HAL_ERROR;
  }

  /* Check the parameters */
  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
  assert_param(IS_ADC_CLOCKPRESCALER(hadc->Init.ClockPrescaler));
  assert_param(IS_ADC_RESOLUTION(hadc->Init.Resolution));
  assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
  assert_param(IS_ADC_EXTTRIG_EDGE(hadc->Init.ExternalTrigConvEdge));

  if (hadc->Instance != ADC4) /* ADC1 or ADC2 */
  {
    assert_param(IS_ADC_SCAN_MODE(hadc->Init.ScanConvMode));
    assert_param(IS_ADC_GAIN_COMPENSATION(hadc->Init.GainCompensation));
    assert_param(IS_ADC_CONVERSIONDATAMGT(hadc->Init.ConversionDataManagement));
    assert_param(IS_ADC_EXTTRIG(hadc->Init.ExternalTrigConv));
  }
  else
  {
    assert_param(IS_ADC4_SCAN_MODE(hadc->Init.ScanConvMode));
    assert_param(IS_ADC_DATA_ALIGN(hadc->Init.DataAlign));
    assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests));
    assert_param(IS_ADC4_LOW_POWER(hadc->Init.LowPowerAutoPowerOff));
    assert_param(IS_ADC4_VREF_PROT(hadc->Init.VrefProtection));
    assert_param(IS_ADC4_EXTTRIG(hadc->Init.ExternalTrigConv));
    assert_param(IS_ADC_TRIGGER_FREQ(hadc->Init.TriggerFrequencyMode));
  }
  assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection));
  assert_param(IS_ADC_OVERRUN(hadc->Init.Overrun));
  assert_param(IS_FUNCTIONAL_STATE(hadc->Init.LowPowerAutoWait));
  assert_param(IS_FUNCTIONAL_STATE(hadc->Init.OversamplingMode));

  if (hadc->Init.ScanConvMode != ADC_SCAN_DISABLE)
  {
    assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode));
    if (hadc->Instance != ADC4) /* ADC1 or ADC2 */
    {
      assert_param(IS_ADC_REGULAR_NB_CONV(hadc->Init.NbrOfConversion));
      if (hadc->Init.DiscontinuousConvMode == ENABLE)
      {
        assert_param(IS_ADC_REGULAR_DISCONT_NUMBER(hadc->Init.NbrOfDiscConversion));
      }
    }
    else
    {
      if (hadc->Init.ScanConvMode == ADC_SCAN_ENABLE)
      {
        assert_param(IS_ADC_REGULAR_NB_CONV(hadc->Init.NbrOfConversion));
      }
    }
  }

  /* DISCEN and CONT bits cannot be set at the same time */
  assert_param(!((hadc->Init.DiscontinuousConvMode == ENABLE) && (hadc->Init.ContinuousConvMode == ENABLE)));

  /* Actions performed only if ADC is coming from state reset:                */
  /* - Initialization of ADC MSP                                              */
  if (hadc->State == HAL_ADC_STATE_RESET)
  {
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
    /* Init the ADC Callback settings */
    hadc->ConvCpltCallback              = HAL_ADC_ConvCpltCallback;                 /* Legacy weak callback */
    hadc->ConvHalfCpltCallback          = HAL_ADC_ConvHalfCpltCallback;             /* Legacy weak callback */
    hadc->LevelOutOfWindowCallback      = HAL_ADC_LevelOutOfWindowCallback;         /* Legacy weak callback */
    hadc->ErrorCallback                 = HAL_ADC_ErrorCallback;                    /* Legacy weak callback */
    if (hadc->Instance != ADC4) /* ADC1 or ADC2 */
    {
      hadc->InjectedConvCpltCallback      = HAL_ADCEx_InjectedConvCpltCallback;       /* Legacy weak callback */
      hadc->InjectedQueueOverflowCallback = HAL_ADCEx_InjectedQueueOverflowCallback;  /* Legacy weak callback */
    }
    hadc->LevelOutOfWindow2Callback     = HAL_ADCEx_LevelOutOfWindow2Callback;      /* Legacy weak callback */
    hadc->LevelOutOfWindow3Callback     = HAL_ADCEx_LevelOutOfWindow3Callback;      /* Legacy weak callback */
    hadc->EndOfSamplingCallback         = HAL_ADCEx_EndOfSamplingCallback;          /* Legacy weak callback */

    if (hadc->MspInitCallback == NULL)
    {
      hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit  */
    }

    /* Init the low level hardware */
    hadc->MspInitCallback(hadc);
#else
    /* Init the low level hardware */
    HAL_ADC_MspInit(hadc);
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */

    /* Set ADC error code to none */
    ADC_CLEAR_ERRORCODE(hadc);

    /* Initialize Lock */
    hadc->Lock = HAL_UNLOCKED;
  }

  /* - Exit from deep-power-down mode and ADC voltage regulator enable        */
  if (LL_ADC_IsDeepPowerDownEnabled(hadc->Instance) != 0UL)
  {
    /* Disable ADC deep power down mode */
    LL_ADC_DisableDeepPowerDown(hadc->Instance);

    /* System was in deep power down mode, calibration must
     be relaunched or a previously saved calibration factor
     re-applied once the ADC voltage regulator is enabled */
  }

  if (LL_ADC_IsInternalRegulatorEnabled(hadc->Instance) == 0UL)
  {
    /* Enable ADC internal voltage regulator */
    LL_ADC_EnableInternalRegulator(hadc->Instance);

    /* Note: Variable divided by 2 to compensate partially              */
    /*       CPU processing cycles, scaling in us split to not          */
    /*       exceed 32 bits register capacity and handle low frequency. */
    wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
    while (wait_loop_index != 0UL)
    {
      wait_loop_index--;
    }
  }

  /* Verification that ADC voltage regulator is correctly enabled, whether    */
  /* or not ADC is coming from state reset (if any potential problem of       */
  /* clocking, voltage regulator would not be enabled).                       */
  if (LL_ADC_IsInternalRegulatorEnabled(hadc->Instance) == 0UL)
  {
    /* Update ADC state machine to error */
    SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);

    /* Set ADC error code to ADC peripheral internal error */
    SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);

    tmp_hal_status = HAL_ERROR;
  }

  /* Configuration of ADC parameters if previous preliminary actions are      */
  /* correctly completed and if there is no conversion on going on regular    */
  /* group (ADC may already be enabled at this point if HAL_ADC_Init() is     */
  /* called to update a parameter on the fly).                                */
  tmp_adc_reg_is_conversion_on_going = LL_ADC_REG_IsConversionOngoing(hadc->Instance);

  if (((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL)
      && (tmp_adc_reg_is_conversion_on_going == 0UL)
     )
  {
    /* Set ADC state */
    ADC_STATE_CLR_SET(hadc->State,
                      HAL_ADC_STATE_REG_BUSY,
                      HAL_ADC_STATE_BUSY_INTERNAL);

    /* Configuration of common ADC parameters                                 */

    /* Parameters update conditioned to ADC state:                            */
    /* Parameters that can be updated only when ADC is disabled:              */
    /*  - clock configuration                                                 */
    if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
    {
      if (hadc->Instance != ADC4) /* ADC1 or ADC2 */
      {
        if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
        {
          /* Reset configuration of ADC common register CCR:                      */
          /*                                                                      */
          /*   - ADC clock mode and ACC prescaler (CKMODE and PRESC bits)are set  */
          /*     according to adc->Init.ClockPrescaler. It selects the clock      */
          /*    source and sets the clock division factor.                        */
          /*                                                                      */
          /* Some parameters of this register are not reset, since they are set   */
          /* by other functions and must be kept in case of usage of this         */
          /* function on the fly (update of a parameter of ADC_InitTypeDef        */
          /* without needing to reconfigure all other ADC groups/channels         */
          /* parameters):                                                         */
          /*   - when multimode feature is available, multimode-related           */
          /*     parameters: MDMA, DMACFG, DELAY, DUAL (set by API                */
          /*     HAL_ADCEx_MultiModeConfigChannel() )                             */
          /*   - internal measurement paths: Vbat, temperature sensor, Vref       */
          /*     (set into HAL_ADC_ConfigChannel() or                             */
          /*     HAL_ADCEx_InjectedConfigChannel() )                              */
          LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(hadc->Instance), hadc->Init.ClockPrescaler);
        }
      }
      else
      {
        /* Some parameters of this register are not reset, since they are set   */
        /* by other functions and must be kept in case of usage of this         */
        /* function on the fly (update of a parameter of ADC_InitTypeDef        */
        /* without needing to reconfigure all other ADC groups/channels         */
        /* parameters):                                                         */
        /*   - internal measurement paths: Vbat, temperature sensor, Vref       */
        /*     (set into HAL_ADC_ConfigChannel() )                              */

        /* Configuration of ADC resolution                                      */
        MODIFY_REG(hadc->Instance->CFGR1,
                   ADC_CFGR1_RES,
                   __LL_ADC_RESOLUTION_ADC1_TO_ADC4(hadc->Init.Resolution));   /* Convert resolution for the ADC4 */

        /* Configuration of ADC clock mode: clock source AHB or HSI with        */
        /* selectable prescaler.                                                */
        MODIFY_REG(ADC4_COMMON->CCR,
                   ADC_CCR_PRESC,
                   hadc->Init.ClockPrescaler & ADC_CCR_PRESC);
      }
    }
    if (hadc->Instance != ADC4) /* ADC1 or ADC2 */
    {
      /* Configuration of ADC:                                                  */
      /*  - resolution                               Init.Resolution            */
      /*  - external trigger to start conversion     Init.ExternalTrigConv      */
      /*  - external trigger polarity                Init.ExternalTrigConvEdge  */
      /*  - continuous conversion mode               Init.ContinuousConvMode    */
      /*  - overrun                                  Init.Overrun               */
      /*  - discontinuous mode                       Init.DiscontinuousConvMode */
      /*  - discontinuous mode channel count         Init.NbrOfDiscConversion   */

      tmpCFGR1  = (/*ADC_CFGR_AUTODELAY((uint32_t)hadc->Init.LowPowerAutoWait)             |*/
                    ADC_CFGR_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode)         |
                    hadc->Init.Overrun                                                    |
                    hadc->Init.Resolution                                                 |
                    ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode));
    }
    else
    {
      /* Configuration of ADC:                                                  */
      /*  - discontinuous mode                                                  */
      /*  - LowPowerAutoWait mode                                               */
      /*  - LowPowerAutoPowerOff mode                                           */
      /*  - continuous conversion mode                                          */
      /*  - overrun                                                             */
      /*  - external trigger to start conversion                                */
      /*  - external trigger polarity                                           */
      /*  - data alignment                                                      */
      /*  - resolution                                                          */
      /*  - scan direction                                                      */
      /*  - DMA continuous request                                              */
      tmpCFGR1 |= (ADC_CFGR_AUTOWAIT((uint32_t)hadc->Init.LowPowerAutoWait)        |
                   ADC_CFGR_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode)    |
                   ADC_CFGR_OVERRUN(hadc->Init.Overrun)                            |
                   hadc->Init.DataAlign                                            |
                   ADC_SCAN_SEQ_MODE(hadc->Init.ScanConvMode)                      |
                   ADC_CFGR_DMACONTREQ(hadc, (uint32_t)hadc->Init.DMAContinuousRequests));
    }

    if (hadc->Init.DiscontinuousConvMode == ENABLE)
    {
      if (hadc->Instance != ADC4) /* ADC1 or ADC2 */
      {
        tmpCFGR1 |= ADC_CFGR_DISCONTINUOUS_NUM(hadc->Init.NbrOfDiscConversion);
      }
      else
      {
        if (hadc->Init.ContinuousConvMode == DISABLE)
        {
          /* Enable the selected ADC group regular discontinuous mode */
          tmpCFGR1 |= ADC_CFGR1_DISCEN;
        }
        else
        {
          /* ADC regular group discontinuous was intended to be enabled,        */
          /* but ADC regular group modes continuous and sequencer discontinuous */
          /* cannot be enabled simultaneously.                                  */

          /* Update ADC state machine to error */
          SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);

          /* Set ADC error code to ADC IP internal error */
          SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
        }
      }
    }

    if (hadc->Instance != ADC4) /* ADC1 or ADC2 */
    {
      /* Enable external trigger if trigger selection is different of software  */
      /* start.                                                                 */
      /* Note: This configuration keeps the hardware feature of parameter       */
      /*       ExternalTrigConvEdge "trigger edge none" equivalent to           */
      /*       software start.                                                  */
      if (hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START)
      {
        tmpCFGR1 |= ((hadc->Init.ExternalTrigConv & ADC_CFGR1_EXTSEL) | hadc->Init.ExternalTrigConvEdge);
      }
      /* Update Configuration Register CFGR */
      MODIFY_REG(hadc->Instance->CFGR1, ADC_CFGR_FIELDS_1, tmpCFGR1);
    }
    else
    {
      /* Enable external trigger if trigger selection is different of software  */
      /* start.                                                                 */
      /* Note: This configuration keeps the hardware feature of parameter       */
      /*       ExternalTrigConvEdge "trigger edge none" equivalent to           */
      /*       software start.                                                  */
      if (hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START)
      {
        tmpCFGR1 |= ((hadc->Init.ExternalTrigConv & ADC4_CFGR1_EXTSEL) | hadc->Init.ExternalTrigConvEdge);
      }
      /* Update ADC configuration register with previous settings */
      MODIFY_REG(hadc->Instance->CFGR1,
                 ADC_CFGR1_DISCEN  |
                 ADC4_CFGR1_WAIT    |
                 ADC_CFGR1_CONT    |
                 ADC_CFGR1_OVRMOD  |
                 ADC_CFGR1_EXTSEL  |
                 ADC_CFGR1_EXTEN   |
                 ADC4_CFGR1_ALIGN   |
                 ADC4_CFGR1_SCANDIR |
                 ADC4_CFGR1_DMACFG,
                 tmpCFGR1);

      if (hadc->Init.LowPowerAutoPowerOff != ADC_LOW_POWER_NONE)
      {
        SET_BIT(hadc->Instance->PW, hadc->Init.LowPowerAutoPowerOff);
      }

      if (hadc->Init.VrefProtection != ADC_VREF_PPROT_NONE)
      {
        SET_BIT(hadc->Instance->PW, hadc->Init.VrefProtection);
      }

    }

    if (hadc->Instance != ADC4) /* ADC1 or ADC2 */
    {
      /* Parameters update conditioned to ADC state:                            */
      /* Parameters that can be updated when ADC is disabled or enabled without */
      /* conversion on going on regular and injected groups:                    */
      /*  - Conversion data management      Init.ConversionDataManagement       */
      /*  - LowPowerAutoWait feature        Init.LowPowerAutoWait               */
      /*  - Oversampling parameters         Init.Oversampling                   */
      tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
      tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
      if ((tmp_adc_is_conversion_on_going_regular == 0UL)
          && (tmp_adc_is_conversion_on_going_injected == 0UL)
         )
      {
        tmpCFGR1 = (ADC_CFGR_AUTODELAY((uint32_t)hadc->Init.LowPowerAutoWait)        |
                    ADC_CFGR_DMACONTREQ(hadc, (uint32_t)hadc->Init.ConversionDataManagement));

        MODIFY_REG(hadc->Instance->CFGR1, ADC4_CFGR_FIELDS_2, tmpCFGR1);
        if (hadc->Init.GainCompensation != 0UL)
        {
          LL_ADC_SetGainCompensation(hadc->Instance, hadc->Init.GainCompensation);
        }

        if (hadc->Init.OversamplingMode == ENABLE)
        {
          assert_param(IS_ADC_OVERSAMPLING_RATIO(hadc->Init.Oversampling.Ratio));
          assert_param(IS_ADC_RIGHT_BIT_SHIFT(hadc->Init.Oversampling.RightBitShift));
          assert_param(IS_ADC_TRIGGERED_OVERSAMPLING_MODE(hadc->Init.Oversampling.TriggeredMode));
          assert_param(IS_ADC_REGOVERSAMPLING_MODE(hadc->Init.Oversampling.OversamplingStopReset));

          if ((hadc->Init.ExternalTrigConv == ADC_SOFTWARE_START)
              || (hadc->Init.ExternalTrigConvEdge == ADC_EXTERNALTRIGCONVEDGE_NONE))
          {
            /* Multi trigger is not applicable to software-triggered conversions */
            assert_param((hadc->Init.Oversampling.TriggeredMode == ADC_TRIGGEREDMODE_SINGLE_TRIGGER));
          }

          /* Configuration of Oversampler:                                       */
          /*  - Oversampling Ratio                                               */
          /*  - Right bit shift                                                  */
          /*  - Left bit shift                                                   */
          /*  - Triggered mode                                                   */
          /*  - Oversampling mode (continued/resumed)                            */
          /*  - trigger frequency mode                                           */
          MODIFY_REG(hadc->Instance->CFGR2, ADC_CFGR2_FIELDS,
                     ADC_CFGR2_ROVSE                                       |
                     (hadc->Init.Oversampling.Ratio << ADC_CFGR2_OVSR_Pos) |
                     hadc->Init.Oversampling.RightBitShift                 |
                     hadc->Init.Oversampling.TriggeredMode                 |
                     hadc->Init.Oversampling.OversamplingStopReset         |
                     (hadc->Init.TriggerFrequencyMode >> 2UL));
        }
        else
        {
          /* Disable ADC oversampling scope on ADC group regular */
          CLEAR_BIT(hadc->Instance->CFGR2, ADC_CFGR2_ROVSE);
        }

        /* Set the LeftShift parameter: it is applied to the final result with or without oversampling */
        MODIFY_REG(hadc->Instance->CFGR2, ADC_CFGR2_LSHIFT, hadc->Init.LeftBitShift);
      }
      /* Configuration of regular group sequencer:                              */
      /* - if scan mode is disabled, regular channels sequence length is set to */
      /*   0x00: 1 channel converted (channel on regular rank 1)                */
      /*   Parameter "NbrOfConversion" is discarded.                            */
      /*   Note: Scan mode is not present by hardware on this device, but       */
      /*   emulated by software for alignment over all STM32 devices.           */
      /* - if scan mode is enabled, regular channels sequence length is set to  */
      /*   parameter "NbrOfConversion".                                         */
      if (hadc->Init.ScanConvMode == ADC_SCAN_ENABLE)
      {
        /* Set number of ranks in regular group sequencer */
        MODIFY_REG(hadc->Instance->SQR1, ADC_SQR1_L, (hadc->Init.NbrOfConversion - (uint8_t)1));
      }
      else
      {
        CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_L);
      }

      /* Initialize the ADC state */
      /* Clear HAL_ADC_STATE_BUSY_INTERNAL bit, set HAL_ADC_STATE_READY bit */
      ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL, HAL_ADC_STATE_READY);

    }
    else
    {
      /* Configuration of ADC:                                                  */
      /*  - oversampling enable                                                 */
      /*  - oversampling ratio                                                  */
      /*  - oversampling shift                                                  */
      /*  - oversampling discontinuous mode (triggered mode)                    */
      /*  - trigger frequency mode                                              */
      tmpCFGR2 |= (hadc->Init.Oversampling.Ratio         |
                   hadc->Init.Oversampling.RightBitShift |
                   hadc->Init.Oversampling.TriggeredMode |
                   hadc->Init.TriggerFrequencyMode
                  );

      if (hadc->Init.OversamplingMode == ENABLE)
      {
        SET_BIT(tmpCFGR2, ADC_CFGR2_ROVSE);
      }
      MODIFY_REG(hadc->Instance->CFGR2,
                 ADC_CFGR2_LFTRIG | ADC_CFGR2_ROVSE | ADC4_CFGR2_OVSR | ADC_CFGR2_OVSS | ADC_CFGR2_TROVS,
                 tmpCFGR2);


      /* Channel sampling time configuration */
      LL_ADC_SetSamplingTimeCommonChannels(hadc->Instance, LL_ADC_SAMPLINGTIME_COMMON_1,                   \
                                           hadc->Init.SamplingTimeCommon1);
      LL_ADC_SetSamplingTimeCommonChannels(hadc->Instance, LL_ADC_SAMPLINGTIME_COMMON_2,                   \
                                           hadc->Init.SamplingTimeCommon2);

      /* Configuration of regular group sequencer:                              */
      /* - if scan mode is disabled, regular channels sequence length is set to */
      /*   0x00: 1 channel converted (channel on regular rank 1)                */
      /*   Parameter "NbrOfConversion" is discarded.                            */
      /*   Note: Scan mode is not present by hardware on this device, but       */
      /*   emulated by software for alignment over all STM32 devices.           */
      /* - if scan mode is enabled, regular channels sequence length is set to  */
      /*   parameter "NbrOfConversion".                                         */
      /*   Channels must be configured into each rank using function            */
      /*   "HAL_ADC_ConfigChannel()".                                           */
      if (hadc->Init.ScanConvMode == ADC4_SCAN_DISABLE)
      {
        /* Set sequencer scan length by clearing ranks above rank 1             */
        /* and do not modify rank 1 value.                                      */
        SET_BIT(hadc->Instance->CHSELR, ADC_CHSELR_SQ2_TO_SQ8);

      }
      else if (hadc->Init.ScanConvMode == ADC4_SCAN_ENABLE)
      {
        /* Count number of ranks available in HAL ADC handle variable */
        uint32_t ADCGroupRegularSequencerRanksCount;

        /* Parse all ranks from 1 to 8 */
        for (ADCGroupRegularSequencerRanksCount = 0UL; ADCGroupRegularSequencerRanksCount < (8UL);                    \
             ADCGroupRegularSequencerRanksCount++)
        {
          /* Check each sequencer rank until value of end of sequence */
          if (((hadc->ADCGroupRegularSequencerRanks >> (ADCGroupRegularSequencerRanksCount * 4UL)) & ADC_CHSELR_SQ1) ==
              ADC_CHSELR_SQ1)
          {
            break;
          }
        }

        if (ADCGroupRegularSequencerRanksCount == 1UL)
        {
          /* Set ADC group regular sequencer:                                   */
          /* Set sequencer scan length by clearing ranks above rank 1           */
          /* and do not modify rank 1 value.                                    */
          SET_BIT(hadc->Instance->CHSELR, ADC_CHSELR_SQ2_TO_SQ8);
        }
        else
        {
          /* Set ADC group regular sequencer:                                   */
          /*  - Set ADC group regular sequencer to value memorized              */
          /*    in HAL ADC handle                                               */
          /*    Note: This value maybe be initialized at a unknown value,       */
          /*          therefore after the first call of "HAL_ADC_Init()",        */
          /*          each rank corresponding to parameter "NbrOfConversion"    */
          /*          must be set using "HAL_ADC_ConfigChannel()".              */
          /*  - Set sequencer scan length by clearing ranks above maximum rank  */
          /*    and do not modify other ranks value.                            */
          MODIFY_REG(hadc->Instance->CHSELR,
                     ADC_CHSELR_SQ_ALL,
                     (ADC_CHSELR_SQ2_TO_SQ8 << (((hadc->Init.NbrOfConversion - 1UL) * ADC4_REGULAR_RANK_2) & 0x1FUL)) \
                     | (hadc->ADCGroupRegularSequencerRanks)
                    );
        }
      }

      /* Check back that ADC registers have effectively been configured to      */
      /* ensure of no potential problem of ADC core IP clocking.                */
      /* Check through register CFGR1 (excluding analog watchdog configuration: */
      /* set into separate dedicated function, and bits of ADC resolution set   */
      /* out of temporary variable 'tmpCFGR1').                                 */
      if ((hadc->Instance->CFGR1 & ~(ADC_CFGR1_AWD1CH | ADC_CFGR1_AWD1EN | ADC_CFGR1_AWD1SGL | ADC_CFGR1_RES))
          == tmpCFGR1)
      {
        /* Set ADC error code to none */
        ADC_CLEAR_ERRORCODE(hadc);

        /* Set the ADC state */
        ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL, HAL_ADC_STATE_READY);
      }
      else
      {
        /* Update ADC state machine to error */
        ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL, HAL_ADC_STATE_ERROR_INTERNAL);

        /* Set ADC error code to ADC IP internal error */
        SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);

        tmp_hal_status = HAL_ERROR;
      }
    }
  }
  else
  {
    /* Update ADC state machine to error */
    SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);

    tmp_hal_status = HAL_ERROR;
  }

  return tmp_hal_status;
}