summaryrefslogtreecommitdiffstatshomepage
path: root/stmhal/hal/f7/src/stm32f7xx_hal_adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'stmhal/hal/f7/src/stm32f7xx_hal_adc.c')
-rw-r--r--stmhal/hal/f7/src/stm32f7xx_hal_adc.c758
1 files changed, 518 insertions, 240 deletions
diff --git a/stmhal/hal/f7/src/stm32f7xx_hal_adc.c b/stmhal/hal/f7/src/stm32f7xx_hal_adc.c
index 0c5f83b20c..b8da090f06 100644
--- a/stmhal/hal/f7/src/stm32f7xx_hal_adc.c
+++ b/stmhal/hal/f7/src/stm32f7xx_hal_adc.c
@@ -2,8 +2,8 @@
******************************************************************************
* @file stm32f7xx_hal_adc.c
* @author MCD Application Team
- * @version V1.0.1
- * @date 25-June-2015
+ * @version V1.1.2
+ * @date 23-September-2016
* @brief This file provides firmware functions to manage the following
* functionalities of the Analog to Digital Convertor (ADC) peripheral:
* + Initialization and de-initialization functions
@@ -164,7 +164,7 @@
******************************************************************************
* @attention
*
- * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@@ -258,10 +258,12 @@ static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma);
*/
HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc)
{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
/* Check ADC handle */
if(hadc == NULL)
{
- return HAL_ERROR;
+ return HAL_ERROR;
}
/* Check the parameters */
@@ -284,29 +286,45 @@ HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc)
if(hadc->State == HAL_ADC_STATE_RESET)
{
+ /* Initialize ADC error code */
+ ADC_CLEAR_ERRORCODE(hadc);
+
/* Allocate lock resource and initialize it */
hadc->Lock = HAL_UNLOCKED;
/* Init the low level hardware */
HAL_ADC_MspInit(hadc);
}
- /* Initialize the ADC state */
- hadc->State = HAL_ADC_STATE_BUSY;
+ /* Configuration of ADC parameters if previous preliminary actions are */
+ /* correctly completed. */
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL))
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_BUSY_INTERNAL);
- /* Set ADC parameters */
- ADC_Init(hadc);
+ /* Set ADC parameters */
+ ADC_Init(hadc);
- /* Set ADC error code to none */
- hadc->ErrorCode = HAL_ADC_ERROR_NONE;
+ /* Set ADC error code to none */
+ ADC_CLEAR_ERRORCODE(hadc);
- /* Initialize the ADC state */
- hadc->State = HAL_ADC_STATE_READY;
+ /* Set the ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_BUSY_INTERNAL,
+ HAL_ADC_STATE_READY);
+ }
+ else
+ {
+ tmp_hal_status = HAL_ERROR;
+ }
/* Release Lock */
__HAL_UNLOCK(hadc);
/* Return function status */
- return HAL_OK;
+ return tmp_hal_status;
}
/**
@@ -317,29 +335,43 @@ HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc)
*/
HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc)
{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
/* Check ADC handle */
if(hadc == NULL)
{
- return HAL_ERROR;
+ return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_BUSY;
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL);
+
+ /* Stop potential conversion on going, on regular and injected groups */
+ /* Disable ADC peripheral */
+ __HAL_ADC_DISABLE(hadc);
- /* DeInit the low level hardware */
- HAL_ADC_MspDeInit(hadc);
+ /* Configuration of ADC parameters if previous preliminary actions are */
+ /* correctly completed. */
+ if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON))
+ {
+ /* DeInit the low level hardware */
+ HAL_ADC_MspDeInit(hadc);
- /* Set ADC error code to none */
- hadc->ErrorCode = HAL_ADC_ERROR_NONE;
+ /* Set ADC error code to none */
+ ADC_CLEAR_ERRORCODE(hadc);
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_RESET;
+ /* Set ADC state */
+ hadc->State = HAL_ADC_STATE_RESET;
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
/* Return function status */
- return HAL_OK;
+ return tmp_hal_status;
}
/**
@@ -350,6 +382,8 @@ HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc)
*/
__weak void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_ADC_MspInit could be implemented in the user file
*/
@@ -363,6 +397,8 @@ __weak void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
*/
__weak void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_ADC_MspDeInit could be implemented in the user file
*/
@@ -409,18 +445,7 @@ HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
/* Process locked */
__HAL_LOCK(hadc);
- /* Check if an injected conversion is ongoing */
- if(hadc->State == HAL_ADC_STATE_BUSY_INJ)
- {
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_BUSY_INJ_REG;
- }
- else
- {
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_BUSY_REG;
- }
-
+ /* Enable the ADC peripheral */
/* Check if ADC peripheral is disabled in order to enable it and wait during
Tstab time the ADC's stabilization */
if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
@@ -437,26 +462,62 @@ HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
}
}
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- /* Check if Multimode enabled */
- if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
+ /* Start conversion if ADC is effectively enabled */
+ if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON))
{
- /* if no external trigger present enable software conversion of regular channels */
- if((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)
+ /* Set ADC state */
+ /* - Clear state bitfield related to regular group conversion results */
+ /* - Set state bitfield related to regular group operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR,
+ HAL_ADC_STATE_REG_BUSY);
+
+ /* If conversions on group regular are also triggering group injected, */
+ /* update ADC state. */
+ if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
{
- /* Enable the selected ADC software conversion for regular group */
- hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
}
- }
- else
- {
- /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */
- if((hadc->Instance == ADC1) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET))
+
+ /* State machine update: Check if an injected conversion is ongoing */
+ if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
+ {
+ /* Reset ADC error code fields related to conversions on group regular */
+ CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
+ }
+ else
+ {
+ /* Reset ADC all error code fields */
+ ADC_CLEAR_ERRORCODE(hadc);
+ }
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* Clear regular group conversion flag and overrun flag */
+ /* (To ensure of no unknown state from potential previous ADC operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC | ADC_FLAG_OVR);
+
+ /* Check if Multimode enabled */
+ if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
{
- /* Enable the selected ADC software conversion for regular group */
+ /* if no external trigger present enable software conversion of regular channels */
+ if((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)
+ {
+ /* Enable the selected ADC software conversion for regular group */
hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
+ }
+ }
+ else
+ {
+ /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */
+ if((hadc->Instance == ADC1) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET))
+ {
+ /* Enable the selected ADC software conversion for regular group */
+ hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
+ }
}
}
@@ -476,11 +537,27 @@ HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
*/
HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc)
{
- /* Disable the Peripheral */
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Stop potential conversion on going, on regular and injected groups */
+ /* Disable ADC peripheral */
__HAL_ADC_DISABLE(hadc);
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_READY;
+ /* Check if ADC is effectively disabled */
+ if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON))
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
/* Return function status */
return HAL_OK;
@@ -488,6 +565,14 @@ HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc)
/**
* @brief Poll for regular conversion complete
+ * @note ADC conversion flags EOS (end of sequence) and EOC (end of
+ * conversion) are cleared by this function.
+ * @note This function cannot be used in a particular setup: ADC configured
+ * in DMA mode and polling for end of each conversion (ADC init
+ * parameter "EOCSelection" set to ADC_EOC_SINGLE_CONV).
+ * In this case, DMA resets the flag EOC and polling cannot be
+ * performed on each conversion. Nevertheless, polling can still
+ * be performed on the complete sequence.
* @param hadc: pointer to a ADC_HandleTypeDef structure that contains
* the configuration information for the specified ADC.
* @param Timeout: Timeout value in millisecond.
@@ -507,7 +592,7 @@ HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Ti
HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_DMA) )
{
/* Update ADC state machine to error */
- hadc->State = HAL_ADC_STATE_ERROR;
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
/* Process unlocked */
__HAL_UNLOCK(hadc);
@@ -521,29 +606,46 @@ HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Ti
/* Check End of conversion flag */
while(!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC)))
{
- /* Check for the Timeout */
+ /* Check if timeout is disabled (set to infinite wait) */
if(Timeout != HAL_MAX_DELAY)
{
- if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
+ if((Timeout == 0) || ((HAL_GetTick() - tickstart ) > Timeout))
{
- hadc->State= HAL_ADC_STATE_TIMEOUT;
+ /* Update ADC state machine to timeout */
+ SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
+
/* Process unlocked */
__HAL_UNLOCK(hadc);
+
return HAL_TIMEOUT;
}
}
}
- /* Check if an injected conversion is ready */
- if(hadc->State == HAL_ADC_STATE_EOC_INJ)
- {
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_EOC_INJ_REG;
- }
- else
+ /* Clear regular group conversion flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_STRT | ADC_FLAG_EOC);
+
+ /* Update ADC state machine */
+ 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. */
+ /* Note: On STM32F7, there is no independent flag of end of sequence. */
+ /* The test of scan sequence on going is done either with scan */
+ /* sequence disabled or with end of conversion flag set to */
+ /* of end of sequence. */
+ if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
+ (hadc->Init.ContinuousConvMode == DISABLE) &&
+ (HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) ||
+ HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS) ) )
{
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_EOC_REG;
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY))
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
}
/* Return ADC state */
@@ -566,6 +668,7 @@ HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventTy
uint32_t tickstart = 0;
/* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
assert_param(IS_ADC_EVENT_TYPE(EventType));
/* Get tick */
@@ -577,32 +680,38 @@ HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventTy
/* Check for the Timeout */
if(Timeout != HAL_MAX_DELAY)
{
- if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
+ if((Timeout == 0) || ((HAL_GetTick() - tickstart ) > Timeout))
{
- hadc->State= HAL_ADC_STATE_TIMEOUT;
+ /* Update ADC state machine to timeout */
+ SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
+
/* Process unlocked */
__HAL_UNLOCK(hadc);
+
return HAL_TIMEOUT;
}
}
}
- /* Check analog watchdog flag */
+ /* Analog watchdog (level out of window) event */
if(EventType == ADC_AWD_EVENT)
{
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_AWD;
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_AWD1);
- /* Clear the ADCx's analog watchdog flag */
- __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD);
+ /* Clear ADC analog watchdog flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD);
}
+ /* Overrun event */
else
{
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_ERROR;
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_REG_OVR);
+ /* Set ADC error code to overrun */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR);
- /* Clear the ADCx's Overrun flag */
- __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
+ /* Clear ADC overrun flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
}
/* Return ADC state */
@@ -627,21 +736,7 @@ HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc)
/* Process locked */
__HAL_LOCK(hadc);
- /* Check if an injected conversion is ongoing */
- if(hadc->State == HAL_ADC_STATE_BUSY_INJ)
- {
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_BUSY_INJ_REG;
- }
- else
- {
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_BUSY_REG;
- }
-
- /* Set ADC error code to none */
- hadc->ErrorCode = HAL_ADC_ERROR_NONE;
-
+ /* Enable the ADC peripheral */
/* Check if ADC peripheral is disabled in order to enable it and wait during
Tstab time the ADC's stabilization */
if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
@@ -658,32 +753,65 @@ HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc)
}
}
- /* Enable the ADC overrun interrupt */
- __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
+ /* Start conversion if ADC is effectively enabled */
+ if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON))
+ {
+ /* Set ADC state */
+ /* - Clear state bitfield related to regular group conversion results */
+ /* - Set state bitfield related to regular group operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR,
+ HAL_ADC_STATE_REG_BUSY);
+
+ /* If conversions on group regular are also triggering group injected, */
+ /* update ADC state. */
+ if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
+ {
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
+ }
- /* Enable the ADC end of conversion interrupt for regular group */
- __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOC);
+ /* State machine update: Check if an injected conversion is ongoing */
+ if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
+ {
+ /* Reset ADC error code fields related to conversions on group regular */
+ CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
+ }
+ else
+ {
+ /* Reset ADC all error code fields */
+ ADC_CLEAR_ERRORCODE(hadc);
+ }
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
- /* Check if Multimode enabled */
- if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
- {
- /* if no external trigger present enable software conversion of regular channels */
- if((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)
+ /* Clear regular group conversion flag and overrun flag */
+ /* (To ensure of no unknown state from potential previous ADC operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC | ADC_FLAG_OVR);
+
+ /* Enable end of conversion interrupt for regular group */
+ __HAL_ADC_ENABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_OVR));
+
+ /* Check if Multimode enabled */
+ if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
{
- /* Enable the selected ADC software conversion for regular group */
- hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
+ /* if no external trigger present enable software conversion of regular channels */
+ if((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)
+ {
+ /* Enable the selected ADC software conversion for regular group */
+ hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
+ }
}
- }
- else
- {
- /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */
- if((hadc->Instance == (ADC_TypeDef*)0x40012000) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET))
+ else
{
- /* Enable the selected ADC software conversion for regular group */
- hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
+ /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */
+ if((hadc->Instance == ADC1) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET))
+ {
+ /* Enable the selected ADC software conversion for regular group */
+ hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
+ }
}
}
@@ -702,17 +830,30 @@ HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc)
*/
HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc)
{
- /* Disable the ADC end of conversion interrupt for regular group */
- __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
- /* Disable the ADC end of conversion interrupt for injected group */
- __HAL_ADC_DISABLE_IT(hadc, ADC_CR1_JEOCIE);
+ /* Process locked */
+ __HAL_LOCK(hadc);
- /* Enable the Peripheral */
+ /* Stop potential conversion on going, on regular and injected groups */
+ /* Disable ADC peripheral */
__HAL_ADC_DISABLE(hadc);
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_READY;
+ /* Check if ADC is effectively disabled */
+ if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON))
+ {
+ /* Disable ADC end of conversion interrupt for regular group */
+ __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_OVR));
+
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
/* Return function status */
return HAL_OK;
@@ -738,55 +879,44 @@ void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)
/* Check End of conversion flag for regular channels */
if(tmp1 && tmp2)
{
- /* Check if an injected conversion is ready */
- if(hadc->State == HAL_ADC_STATE_EOC_INJ)
+ /* Update state machine on conversion status if not in error state */
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL))
{
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_EOC_INJ_REG;
- }
- else
- {
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_EOC_REG;
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
}
- if((hadc->Init.ContinuousConvMode == DISABLE) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET))
+ /* Determine whether any further conversion upcoming on group regular */
+ /* by external trigger, continuous mode or scan sequence on going. */
+ /* Note: On STM32F7, there is no independent flag of end of sequence. */
+ /* The test of scan sequence on going is done either with scan */
+ /* sequence disabled or with end of conversion flag set to */
+ /* of end of sequence. */
+ if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
+ (hadc->Init.ContinuousConvMode == DISABLE) &&
+ (HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) ||
+ HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS) ) )
{
- if(hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV)
- {
- /* DISABLE the ADC end of conversion interrupt for regular group */
- __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
+ /* Disable ADC end of single conversion interrupt on group regular */
+ /* Note: Overrun interrupt was enabled with EOC interrupt in */
+ /* HAL_ADC_Start_IT(), but is not disabled here because can be used */
+ /* by overrun IRQ process below. */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
- /* DISABLE the ADC overrun interrupt */
- __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
- }
- else
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY))
{
- if (hadc->NbrOfCurrentConversionRank == 0)
- {
- hadc->NbrOfCurrentConversionRank = hadc->Init.NbrOfConversion;
- }
-
- /* Decrement the number of conversion when an interrupt occurs */
- hadc->NbrOfCurrentConversionRank--;
-
- /* Check if all conversions are finished */
- if(hadc->NbrOfCurrentConversionRank == 0)
- {
- /* DISABLE the ADC end of conversion interrupt for regular group */
- __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
-
- /* DISABLE the ADC overrun interrupt */
- __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
- }
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
}
}
/* Conversion complete callback */
HAL_ADC_ConvCpltCallback(hadc);
- /* Clear the ADCx flag for regular end of conversion */
- __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_EOC);
+ /* Clear regular group conversion flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_STRT | ADC_FLAG_EOC);
}
tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC);
@@ -794,31 +924,41 @@ void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)
/* Check End of conversion flag for injected channels */
if(tmp1 && tmp2)
{
- /* Check if a regular conversion is ready */
- if(hadc->State == HAL_ADC_STATE_EOC_REG)
+ /* Update state machine on conversion status if not in error state */
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL))
{
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_EOC_INJ_REG;
- }
- else
- {
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_EOC_INJ;
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
}
- tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
- tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
- if(((hadc->Init.ContinuousConvMode == DISABLE) || tmp1) && tmp2)
+ /* Determine whether any further conversion upcoming on group injected */
+ /* by external trigger, scan sequence on going or by automatic injected */
+ /* conversion from group regular (same conditions as group regular */
+ /* interruption disabling above). */
+ if(ADC_IS_SOFTWARE_START_INJECTED(hadc) &&
+ (HAL_IS_BIT_CLR(hadc->Instance->JSQR, ADC_JSQR_JL) ||
+ HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS)) &&
+ (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) &&
+ (ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
+ (hadc->Init.ContinuousConvMode == DISABLE))))
{
- /* DISABLE the ADC end of conversion interrupt for injected group */
+ /* Disable ADC end of single conversion interrupt on group injected */
__HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
+
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
+
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
}
/* Conversion complete callback */
HAL_ADCEx_InjectedConvCpltCallback(hadc);
- /* Clear the ADCx flag for injected end of conversion */
- __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_JEOC);
+ /* Clear injected group conversion flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JSTRT | ADC_FLAG_JEOC));
}
tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_AWD);
@@ -826,14 +966,17 @@ void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)
/* Check Analog watchdog flag */
if(tmp1 && tmp2)
{
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_AWD;
+ if(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_AWD))
+ {
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_AWD1);
- /* Clear the ADCx's Analog watchdog flag */
- __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_AWD);
+ /* Level out of window callback */
+ HAL_ADC_LevelOutOfWindowCallback(hadc);
- /* Level out of window callback */
- HAL_ADC_LevelOutOfWindowCallback(hadc);
+ /* Clear the ADC analog watchdog flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD);
+ }
}
tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_OVR);
@@ -841,17 +984,21 @@ void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)
/* Check Overrun flag */
if(tmp1 && tmp2)
{
- /* Change ADC state to overrun state */
- hadc->State = HAL_ADC_STATE_ERROR;
+ /* Note: On STM32F7, ADC overrun can be set through other parameters */
+ /* refer to description of parameter "EOCSelection" for more */
+ /* details. */
/* Set ADC error code to overrun */
- hadc->ErrorCode |= HAL_ADC_ERROR_OVR;
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR);
- /* Clear the Overrun flag */
- __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_OVR);
+ /* Clear ADC overrun flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
/* Error callback */
HAL_ADC_ErrorCallback(hadc);
+
+ /* Clear the Overrun flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
}
}
@@ -874,30 +1021,7 @@ HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, ui
/* Process locked */
__HAL_LOCK(hadc);
- /* Enable ADC overrun interrupt */
- __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
-
- /* Enable ADC DMA mode */
- hadc->Instance->CR2 |= ADC_CR2_DMA;
-
- /* Set the DMA transfer complete callback */
- hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
-
- /* Set the DMA half transfer complete callback */
- hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt;
-
- /* Set the DMA error callback */
- hadc->DMA_Handle->XferErrorCallback = ADC_DMAError ;
-
- /* Enable the DMA Stream */
- HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length);
-
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_BUSY_REG;
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
+ /* Enable the ADC peripheral */
/* Check if ADC peripheral is disabled in order to enable it and wait during
Tstab time the ADC's stabilization */
if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
@@ -914,11 +1038,85 @@ HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, ui
}
}
- /* if no external trigger present enable software conversion of regular channels */
- if((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)
+ /* Start conversion if ADC is effectively enabled */
+ if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON))
{
- /* Enable the selected ADC software conversion for regular group */
- hadc->Instance->CR2 |= ADC_CR2_SWSTART;
+ /* Set ADC state */
+ /* - Clear state bitfield related to regular group conversion results */
+ /* - Set state bitfield related to regular group operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR,
+ HAL_ADC_STATE_REG_BUSY);
+
+ /* If conversions on group regular are also triggering group injected, */
+ /* update ADC state. */
+ if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
+ {
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
+ }
+
+ /* State machine update: Check if an injected conversion is ongoing */
+ if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
+ {
+ /* Reset ADC error code fields related to conversions on group regular */
+ CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
+ }
+ else
+ {
+ /* Reset ADC all error code fields */
+ ADC_CLEAR_ERRORCODE(hadc);
+ }
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* Set the DMA transfer complete callback */
+ hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
+
+ /* Set the DMA half transfer complete callback */
+ hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt;
+
+ /* Set the DMA error callback */
+ hadc->DMA_Handle->XferErrorCallback = ADC_DMAError;
+
+
+ /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */
+ /* start (in case of SW start): */
+
+ /* Clear regular group conversion flag and overrun flag */
+ /* (To ensure of no unknown state from potential previous ADC operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC | ADC_FLAG_OVR);
+
+ /* Enable ADC overrun interrupt */
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
+
+ /* Enable ADC DMA mode */
+ hadc->Instance->CR2 |= ADC_CR2_DMA;
+
+ /* Start the DMA channel */
+ HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length);
+
+ /* Check if Multimode enabled */
+ if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
+ {
+ /* if no external trigger present enable software conversion of regular channels */
+ if((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)
+ {
+ /* Enable the selected ADC software conversion for regular group */
+ hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
+ }
+ }
+ else
+ {
+ /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */
+ if((hadc->Instance == ADC1) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET))
+ {
+ /* Enable the selected ADC software conversion for regular group */
+ hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
+ }
+ }
}
/* Return function status */
@@ -933,23 +1131,42 @@ HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, ui
*/
HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc)
{
- /* Disable the Peripheral */
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Stop potential conversion on going, on regular and injected groups */
+ /* Disable ADC peripheral */
__HAL_ADC_DISABLE(hadc);
- /* Disable ADC overrun interrupt */
- __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
+ /* Check if ADC is effectively disabled */
+ if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON))
+ {
+ /* Disable the selected ADC DMA mode */
+ hadc->Instance->CR2 &= ~ADC_CR2_DMA;
- /* Disable the selected ADC DMA mode */
- hadc->Instance->CR2 &= ~ADC_CR2_DMA;
+ /* Disable the DMA channel (in case of DMA in circular mode or stop while */
+ /* DMA transfer is on going) */
+ tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
- /* Disable the ADC DMA Stream */
- HAL_DMA_Abort(hadc->DMA_Handle);
+ /* Disable ADC overrun interrupt */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_READY;
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
/* Return function status */
- return HAL_OK;
+ return tmp_hal_status;
}
/**
@@ -972,6 +1189,8 @@ uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc)
*/
__weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_ADC_ConvCpltCallback could be implemented in the user file
*/
@@ -985,6 +1204,8 @@ __weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
*/
__weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_ADC_ConvHalfCpltCallback could be implemented in the user file
*/
@@ -998,6 +1219,8 @@ __weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
*/
__weak void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_ADC_LevelOoutOfWindowCallback could be implemented in the user file
*/
@@ -1005,12 +1228,20 @@ __weak void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
/**
* @brief Error ADC callback.
+ * @note In case of error due to overrun when using ADC with DMA transfer
+ * (HAL ADC handle paramater "ErrorCode" to state "HAL_ADC_ERROR_OVR"):
+ * - Reinitialize the DMA using function "HAL_ADC_Stop_DMA()".
+ * - If needed, restart a new ADC conversion using function
+ * "HAL_ADC_Start_DMA()"
+ * (this function is also clearing overrun flag)
* @param hadc: pointer to a ADC_HandleTypeDef structure that contains
* the configuration information for the specified ADC.
* @retval None
*/
__weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_ADC_ErrorCallback could be implemented in the user file
*/
@@ -1057,14 +1288,22 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConf
/* Process locked */
__HAL_LOCK(hadc);
- /* if ADC_Channel_10 ... ADC_Channel_18 is selected */
- if (sConfig->Channel > ADC_CHANNEL_9)
- {
- /* Clear the old sample time */
- hadc->Instance->SMPR1 &= ~ADC_SMPR1(ADC_SMPR1_SMP10, sConfig->Channel);
-
- /* Set the new sample time */
- hadc->Instance->SMPR1 |= ADC_SMPR1(sConfig->SamplingTime, sConfig->Channel);
+ /* if ADC_Channel_10 ... ADC_Channel_18 is selected */
+ if (sConfig->Channel > ADC_CHANNEL_9)
+ {
+ /* Clear the old sample time */
+ hadc->Instance->SMPR1 &= ~ADC_SMPR1(ADC_SMPR1_SMP10, sConfig->Channel);
+
+ if (sConfig->Channel == ADC_CHANNEL_TEMPSENSOR)
+ {
+ /* Set the new sample time */
+ hadc->Instance->SMPR1 |= ADC_SMPR1(sConfig->SamplingTime, ADC_CHANNEL_18);
+ }
+ else
+ {
+ /* Set the new sample time */
+ hadc->Instance->SMPR1 |= ADC_SMPR1(sConfig->SamplingTime, sConfig->Channel);
+ }
}
else /* ADC_Channel include in ADC_Channel_[0..9] */
{
@@ -1110,13 +1349,13 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConf
ADC->CCR |= ADC_CCR_VBATE;
}
- /* if ADC1 Channel_16 or Channel_17 is selected enable TSVREFE Channel(Temperature sensor and VREFINT) */
+ /* if ADC1 Channel_18 or Channel_17 is selected enable TSVREFE Channel(Temperature sensor and VREFINT) */
if ((hadc->Instance == ADC1) && ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) || (sConfig->Channel == ADC_CHANNEL_VREFINT)))
{
/* Enable the TSVREFE channel*/
ADC->CCR |= ADC_CCR_TSVREFE;
- if((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR))
+ if(sConfig->Channel == ADC_CHANNEL_TEMPSENSOR)
{
/* Delay for temperature sensor stabilization time */
/* Compute number of CPU cycles to wait for */
@@ -1137,6 +1376,14 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConf
/**
* @brief Configures the analog watchdog.
+ * @note Analog watchdog thresholds can be modified while ADC conversion
+ * is on going.
+ * In this case, some constraints must be taken into account:
+ * the programmed threshold values are effective from the next
+ * ADC EOC (end of unitary conversion).
+ * Considering that registers write delay may happen due to
+ * bus activity, this might cause an uncertainty on the
+ * effective timing of the new programmed threshold values.
* @param hadc: pointer to a ADC_HandleTypeDef structure that contains
* the configuration information for the specified ADC.
* @param AnalogWDGConfig : pointer to an ADC_AnalogWDGConfTypeDef structure
@@ -1225,7 +1472,7 @@ HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDG
* the configuration information for the specified ADC.
* @retval HAL state
*/
-HAL_ADC_StateTypeDef HAL_ADC_GetState(ADC_HandleTypeDef* hadc)
+uint32_t HAL_ADC_GetState(ADC_HandleTypeDef* hadc)
{
/* Return ADC state */
return hadc->State;
@@ -1346,21 +1593,49 @@ static void ADC_Init(ADC_HandleTypeDef* hadc)
*/
static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma)
{
+ /* Retrieve ADC handle corresponding to current DMA handle */
ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- /* Check if an injected conversion is ready */
- if(hadc->State == HAL_ADC_STATE_EOC_INJ)
+ /* Update state machine on conversion status if not in error state */
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA))
{
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_EOC_INJ_REG;
+ /* Update ADC state machine */
+ 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. */
+ /* Note: On STM32F7, there is no independent flag of end of sequence. */
+ /* The test of scan sequence on going is done either with scan */
+ /* sequence disabled or with end of conversion flag set to */
+ /* of end of sequence. */
+ if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
+ (hadc->Init.ContinuousConvMode == DISABLE) &&
+ (HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) ||
+ HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS) ) )
+ {
+ /* Disable ADC end of single conversion interrupt on group regular */
+ /* Note: Overrun interrupt was enabled with EOC interrupt in */
+ /* HAL_ADC_Start_IT(), but is not disabled here because can be used */
+ /* by overrun IRQ process below. */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
+
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY))
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
+ }
+
+ /* Conversion complete callback */
+ HAL_ADC_ConvCpltCallback(hadc);
}
else
{
- /* Change ADC state */
- hadc->State = HAL_ADC_STATE_EOC_REG;
+ /* Call DMA error callback */
+ hadc->DMA_Handle->XferErrorCallback(hdma);
}
-
- HAL_ADC_ConvCpltCallback(hadc);
}
/**
@@ -1385,12 +1660,15 @@ static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma)
static void ADC_DMAError(DMA_HandleTypeDef *hdma)
{
ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- hadc->State= HAL_ADC_STATE_ERROR;
+ hadc->State= HAL_ADC_STATE_ERROR_DMA;
/* Set ADC error code to DMA error */
hadc->ErrorCode |= HAL_ADC_ERROR_DMA;
HAL_ADC_ErrorCallback(hadc);
}
+/**
+ * @}
+ */
/**
* @}