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 */
}