void HAL_ADC_IRQHandler()

in Drivers/STM32U5xx_HAL/Src/stm32u5xx_hal_adc.c [2417:2778]


void HAL_ADC_IRQHandler(ADC_HandleTypeDef *hadc)
{
  uint32_t overrun_error = 0UL; /* flag set if overrun occurrence has to be considered as an error */
  uint32_t tmp_isr = hadc->Instance->ISR;
  uint32_t tmp_ier = hadc->Instance->IER;
  uint32_t tmp_adc_inj_is_trigger_source_sw_start;
  uint32_t tmp_adc_reg_is_trigger_source_sw_start;
  uint32_t tmp_cfgr;

  /* Check the parameters */
  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
  assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection));

  /* ========== Check End of Sampling flag for ADC group regular ========== */
  if (((tmp_isr & ADC_FLAG_EOSMP) == ADC_FLAG_EOSMP) && ((tmp_ier & ADC_IT_EOSMP) == ADC_IT_EOSMP))
  {
    /* Update state machine on end of sampling status if not in error state */
    if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL)
    {
      /* Set ADC state */
      SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOSMP);
    }

    /* End Of Sampling callback */
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
    hadc->EndOfSamplingCallback(hadc);
#else
    HAL_ADCEx_EndOfSamplingCallback(hadc);
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */

    /* Clear regular group conversion flag */
    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOSMP);
  }

  /* ====== Check ADC group regular end of unitary conversion sequence conversions ===== */
  if ((((tmp_isr & ADC_FLAG_EOC) == ADC_FLAG_EOC) && ((tmp_ier & ADC_IT_EOC) == ADC_IT_EOC)) ||
      (((tmp_isr & ADC_FLAG_EOS) == ADC_FLAG_EOS) && ((tmp_ier & ADC_IT_EOS) == ADC_IT_EOS)))
  {
    /* Update state machine on conversion status if not in error state */
    if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL)
    {
      /* Set ADC state */
      SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
    }

    /* Determine whether any further conversion upcoming on group regular     */
    /* by external trigger, continuous mode or scan sequence on going         */
    /* to disable interruption.                                               */
    if (hadc->Instance != ADC4)  /* ADC1 or ADC2 */
    {
      if (LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL)
      {
        /* Get relevant register CFGR in ADC instance of ADC master or slave    */
        /* in function of multimode state (for devices with multimode           */
        /* available).                                                          */
        tmp_cfgr = READ_REG(hadc->Instance->CFGR1);

        /* Carry on if continuous mode is disabled */
        if (READ_BIT(tmp_cfgr, ADC_CFGR1_CONT) != ADC_CFGR1_CONT)
        {
          /* If End of Sequence is reached, disable interrupts */
          if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS))
          {
            /* Allowed to modify bits ADC_IT_EOC/ADC_IT_EOS only if bit         */
            /* ADSTART==0 (no conversion on going)                              */
            if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
            {
              /* Disable ADC end of sequence conversion interrupt */
              /* Note: Overrun interrupt was enabled with EOC interrupt in      */
              /* HAL_Start_IT(), but is not disabled here because can be used   */
              /* by overrun IRQ process below.                                  */
              __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC | ADC_IT_EOS);

              /* Set ADC state */
              CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);

              if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL)
              {
                SET_BIT(hadc->State, HAL_ADC_STATE_READY);
              }
            }
            else
            {
              /* Change ADC state to error state */
              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);
            }
          }
        }
      }
    }
    else
    {
      /* Determine whether any further conversion upcoming on group regular     */
      /* by external trigger, continuous mode or scan sequence on going         */
      /* to disable interruption.                                               */
      if ((LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL)
          && (hadc->Init.ContinuousConvMode == DISABLE)
         )
      {
        /* If End of Sequence is reached, disable interrupts */
        if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS))
        {
          /* Allowed to modify bits ADC_IT_EOC/ADC_IT_EOS only if bit           */
          /* ADSTART==0 (no conversion on going)                                */
          if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
          {
            /* Disable ADC end of single conversion interrupt on group regular */
            /* Note: Overrun interrupt was enabled with EOC interrupt in        */
            /* HAL_Start_IT(), but is not disabled here because can be used     */
            /* by overrun IRQ process below.                                    */
            __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC | ADC_IT_EOS);

            /* Set ADC state */
            ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_REG_BUSY, HAL_ADC_STATE_READY);
          }
          else
          {
            /* Change ADC state to error state */
            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);
          }
        }
      }
    }

    /* Conversion complete callback */
    /* Note: Into callback function "HAL_ADC_ConvCpltCallback()",             */
    /*       to determine if conversion has been triggered from EOC or EOS,   */
    /*       possibility to use:                                              */
    /*        " if( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_EOS)) "                */
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
    hadc->ConvCpltCallback(hadc);
#else
    HAL_ADC_ConvCpltCallback(hadc);
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */

    /* Clear regular group conversion flag */
    /* Note: in case of overrun set to ADC_OVR_DATA_PRESERVED, end of         */
    /*       conversion flags clear induces the release of the preserved data.*/
    /*       Therefore, if the preserved data value is needed, it must be     */
    /*       read preliminarily into HAL_ADC_ConvCpltCallback().              */
    __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS));
  }

  if (hadc->Instance != ADC4)  /* ADC1 or ADC2 */
  {
    /* ====== Check ADC group injected end of unitary conversion sequence conversions ===== */
    if ((((tmp_isr & ADC_FLAG_JEOC) == ADC_FLAG_JEOC) && ((tmp_ier & ADC_IT_JEOC) == ADC_IT_JEOC)) ||
        (((tmp_isr & ADC_FLAG_JEOS) == ADC_FLAG_JEOS) && ((tmp_ier & ADC_IT_JEOS) == ADC_IT_JEOS)))
    {
      /* Update state machine on conversion status if not in error state */
      if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL)
      {
        /* Set ADC state */
        SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
      }

      /* Retrieve ADC configuration */
      tmp_adc_inj_is_trigger_source_sw_start = LL_ADC_INJ_IsTriggerSourceSWStart(hadc->Instance);
      tmp_adc_reg_is_trigger_source_sw_start = LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance);
      /* Get relevant register CFGR in ADC instance of ADC master or slave  */
      /* in function of multimode state (for devices with multimode         */
      /* available).                                                        */

      tmp_cfgr = READ_REG(hadc->Instance->CFGR1);

      /* Disable interruption if no further conversion upcoming by injected     */
      /* external trigger or by automatic injected conversion with regular      */
      /* group having no further conversion upcoming (same conditions as        */
      /* regular group interruption disabling above),                           */
      /* and if injected scan sequence is completed.                            */
      if (tmp_adc_inj_is_trigger_source_sw_start != 0UL)
      {
        if ((READ_BIT(tmp_cfgr, ADC_CFGR1_JAUTO) == 0UL) ||
            ((tmp_adc_reg_is_trigger_source_sw_start != 0UL) &&
             (READ_BIT(tmp_cfgr, ADC_CFGR1_CONT) == 0UL)))
        {
          /* If End of Sequence is reached, disable interrupts */
          if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS))
          {
            /* Particular case if injected contexts queue is enabled:             */
            /* when the last context has been fully processed, JSQR is reset      */
            /* by the hardware. Even if no injected conversion is planned to come */
            /* (queue empty, triggers are ignored), it can start again            */
            /* immediately after setting a new context (JADSTART is still set).   */
            /* Therefore, state of HAL ADC injected group is kept to busy.        */
            /* No ADC_CFGR1_JQM for STM32U5                                       */

            /* Allowed to modify bits ADC_IT_JEOC/ADC_IT_JEOS only if bit       */
            /* JADSTART==0 (no conversion on going)                             */
            if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
            {
              /* Disable ADC end of sequence conversion interrupt  */
              __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC | ADC_IT_JEOS);

              /* Set ADC state */
              CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);

              if ((hadc->State & HAL_ADC_STATE_REG_BUSY) == 0UL)
              {
                SET_BIT(hadc->State, HAL_ADC_STATE_READY);
              }
            }
          }
        }
      }

      /* Injected Conversion complete callback */
      /* Note:  HAL_ADCEx_InjectedConvCpltCallback can resort to
                if( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_JEOS)) or
                if( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_JEOC)) to determine whether
                interruption has been triggered by end of conversion or end of
                sequence.    */
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
      hadc->InjectedConvCpltCallback(hadc);
#else
      HAL_ADCEx_InjectedConvCpltCallback(hadc);
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */

      /* Clear injected group conversion flag */
      __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC | ADC_FLAG_JEOS);
    }
  } /* Specific ADC1 only */

  /* ========== Check Analog watchdog 1 flag ========== */
  if (((tmp_isr & ADC_FLAG_AWD1) == ADC_FLAG_AWD1) && ((tmp_ier & ADC_IT_AWD1) == ADC_IT_AWD1))
  {
    /* Set ADC state */
    SET_BIT(hadc->State, HAL_ADC_STATE_AWD1);

    /* Level out of window 1 callback */
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
    hadc->LevelOutOfWindowCallback(hadc);
#else
    HAL_ADC_LevelOutOfWindowCallback(hadc);
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */

    /* Clear ADC analog watchdog flag */
    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD1);
  }

  /* ========== Check analog watchdog 2 flag ========== */
  if (((tmp_isr & ADC_FLAG_AWD2) == ADC_FLAG_AWD2) && ((tmp_ier & ADC_IT_AWD2) == ADC_IT_AWD2))
  {
    /* Set ADC state */
    SET_BIT(hadc->State, HAL_ADC_STATE_AWD2);

    /* Level out of window 2 callback */
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
    hadc->LevelOutOfWindow2Callback(hadc);
#else
    HAL_ADCEx_LevelOutOfWindow2Callback(hadc);
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */

    /* Clear ADC analog watchdog flag */
    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD2);
  }

  /* ========== Check analog watchdog 3 flag ========== */
  if (((tmp_isr & ADC_FLAG_AWD3) == ADC_FLAG_AWD3) && ((tmp_ier & ADC_IT_AWD3) == ADC_IT_AWD3))
  {
    /* Set ADC state */
    SET_BIT(hadc->State, HAL_ADC_STATE_AWD3);

    /* Level out of window 3 callback */
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
    hadc->LevelOutOfWindow3Callback(hadc);
#else
    HAL_ADCEx_LevelOutOfWindow3Callback(hadc);
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */

    /* Clear ADC analog watchdog flag */
    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD3);
  }

  /* ========== Check Overrun flag ========== */
  if (((tmp_isr & ADC_FLAG_OVR) == ADC_FLAG_OVR) && ((tmp_ier & ADC_IT_OVR) == ADC_IT_OVR))
  {
    /* If overrun is set to overwrite previous data (default setting),        */
    /* overrun event is not considered as an error.                           */
    /* (cf ref manual "Managing conversions without using the DMA and without */
    /* overrun ")                                                             */
    /* Exception for usage with DMA overrun event always considered as an     */
    /* error.                                                                 */
    if (hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED)
    {
      overrun_error = 1UL;
    }
    else
    {
      /* Check DMA configuration */
      if (hadc->Instance != ADC4)  /* ADC1 or ADC2 */
      {
        /* Multimode not set or feature not available or ADC independent */
        if ((hadc->Instance->CFGR1 & ADC_CFGR1_DMNGT) != 0UL)
        {
          overrun_error = 1UL;
        }
      }
      else
      {
        /* Check DMA configuration */
        if (LL_ADC_REG_GetDMATransfer(hadc->Instance) != LL_ADC_REG_DMA_TRANSFER_NONE_ADC4)
        {
          overrun_error = 1UL;
        }
      }
    }

    if (overrun_error == 1UL)
    {
      /* Change ADC state to error state */
      SET_BIT(hadc->State, HAL_ADC_STATE_REG_OVR);

      /* Set ADC error code to overrun */
      SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR);

      /* Error callback */
      /* Note: In case of overrun, ADC conversion data is preserved until     */
      /*       flag OVR is reset.                                             */
      /*       Therefore, old ADC conversion data can be retrieved in         */
      /*       function "HAL_ADC_ErrorCallback()".                            */
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
      hadc->ErrorCallback(hadc);
#else
      HAL_ADC_ErrorCallback(hadc);
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
    }

    /* Clear ADC overrun flag */
    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
  }

  if (hadc->Instance != ADC4)  /* ADC1 or ADC2 */
  {
    /* ========== Check Injected context queue overflow flag ========== */
    if (((tmp_isr & ADC_FLAG_JQOVF) == ADC_FLAG_JQOVF) && ((tmp_ier & ADC_IT_JQOVF) == ADC_IT_JQOVF))
    {
      /* Change ADC state to overrun state */
      SET_BIT(hadc->State, HAL_ADC_STATE_INJ_JQOVF);

      /* Set ADC error code to Injected context queue overflow */
      SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF);

      /* Clear the Injected context queue overflow flag */
      __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JQOVF);

      /* Injected context queue overflow callback */
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
      hadc->InjectedQueueOverflowCallback(hadc);
#else
      HAL_ADCEx_InjectedQueueOverflowCallback(hadc);
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
    }
  } /* Speceific ADC1 only */

}