Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
Diff: targets/cmsis/TARGET_STM/TARGET_STM32F7/stm32f7xx_hal_adc.c
- Revision:
 - 83:a036322b8637
 - Parent:
 - 0:9b334a45a8ff
 - Child:
 - 144:ef7eb2e8f9f7
 
--- a/targets/cmsis/TARGET_STM/TARGET_STM32F7/stm32f7xx_hal_adc.c	Sat Mar 05 06:00:11 2016 +0000
+++ b/targets/cmsis/TARGET_STM/TARGET_STM32F7/stm32f7xx_hal_adc.c	Mon Mar 07 10:00:14 2016 +0000
@@ -2,8 +2,8 @@
   ******************************************************************************
   * @file    stm32f7xx_hal_adc.c
   * @author  MCD Application Team
-  * @version V1.0.1
-  * @date    25-June-2015
+  * @version V1.0.4
+  * @date    09-December-2015
   * @brief   This file provides firmware functions to manage the following 
   *          functionalities of the Analog to Digital Convertor (ADC) peripheral:
   *           + Initialization and de-initialization functions
@@ -258,10 +258,12 @@
   */
 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 @@
 
   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;
-  
-  /* Set ADC parameters */
-  ADC_Init(hadc);
   
-  /* Set ADC error code to none */
-  hadc->ErrorCode = HAL_ADC_ERROR_NONE;
+  /* 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 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
+  {
+    tmp_hal_status = HAL_ERROR;
+  }
   
-  /* Initialize the ADC state */
-  hadc->State = HAL_ADC_STATE_READY;
-
   /* Release Lock */
   __HAL_UNLOCK(hadc);
 
   /* Return function status */
-  return HAL_OK;
+  return tmp_hal_status;
 }
 
 /**
@@ -317,29 +335,43 @@
   */
 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);
   
-  /* DeInit the low level hardware */
-  HAL_ADC_MspDeInit(hadc);
+  /* Stop potential conversion on going, on regular and injected groups */
+  /* Disable ADC peripheral */
+  __HAL_ADC_DISABLE(hadc);
   
-  /* Set ADC error code to none */
-  hadc->ErrorCode = HAL_ADC_ERROR_NONE;
+  /* 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 */
+    ADC_CLEAR_ERRORCODE(hadc);
+    
+    /* Set ADC state */
+    hadc->State = HAL_ADC_STATE_RESET;
+  }
   
-  /* Change 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 @@
   */
 __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_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 @@
   /* 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)
@@ -436,27 +461,63 @@
       counter--;
     }
   }
-	
-  /* 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)
+    {
+      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
     {
-      /* Enable the selected ADC software conversion for regular group */
-      hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
+      /* Reset ADC all error code fields */
+      ADC_CLEAR_ERRORCODE(hadc);
     }
-  }
-  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))
+    
+    /* 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);
+    
+    /* 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_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 @@
 
 /**
   * @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_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 @@
   /* 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)
+  /* 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_INJ_REG;  
-  }
-  else
-  {
-    /* 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 @@
   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 @@
     /* 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;
-     
-     /* Clear the ADCx's Overrun flag */
-     __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
+    /* 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 ADC overrun flag */
+    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
   }
   
   /* Return ADC state */
@@ -622,26 +731,12 @@
   
   /* Check the parameters */
   assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
-  assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
+  assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); 
   
   /* 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 @@
     }
   }
   
-  /* Enable the ADC overrun interrupt */
-  __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
-  
-  /* Enable the ADC end of conversion interrupt for regular group */
-  __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOC);
-	
-  /* 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);  
+    }
+    
+    /* 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);
     }
-  }
-  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))
+    
+    /* 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);
+    
+    /* 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 */
+      /* 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;
+      }
     }
   }
   
@@ -702,17 +830,27 @@
   */
 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))
+  {
+    /* 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 +876,44 @@
   /* 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)
-    {
-      /* Change ADC state */
-      hadc->State = HAL_ADC_STATE_EOC_INJ_REG;  
-    }
-    else
-    {
-      /* Change ADC state */
-      hadc->State = HAL_ADC_STATE_EOC_REG;
-    }
-
-    if((hadc->Init.ContinuousConvMode == DISABLE) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET))
+    /* Update state machine on conversion status if not in error state */
+    if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL))
     {
-      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 the ADC overrun interrupt */
-        __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
-      }
-      else
+      /* 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.      */
+    /* 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))
       {
-        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 +921,41 @@
   /* 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)
-    {
-      /* Change ADC state */
-      hadc->State = HAL_ADC_STATE_EOC_INJ_REG;  
-    }
-    else
+    /* 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;
+      /* 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 +963,17 @@
   /* 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 +981,21 @@
   /* 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);
   }
 }
 
@@ -869,35 +1013,12 @@
   
   /* Check the parameters */
   assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
-  assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
+  assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); 
   
   /* 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 +1035,85 @@
     }
   }
   
-  /* 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);
+
+    /* 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 +1128,42 @@
   */
 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);
-  
-  /* Disable the selected ADC DMA mode */
-  hadc->Instance->CR2 &= ~ADC_CR2_DMA;
+  /* 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 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 ADC overrun interrupt */
+    __HAL_ADC_DISABLE_IT(hadc, 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);
+  }
   
-  /* Disable the ADC DMA Stream */
-  HAL_DMA_Abort(hadc->DMA_Handle);
-  
-  /* Change ADC state */
-  hadc->State = HAL_ADC_STATE_READY;
+  /* Process unlocked */
+  __HAL_UNLOCK(hadc);
   
   /* Return function status */
-  return HAL_OK;
+  return tmp_hal_status;
 }
 
 /**
@@ -972,6 +1186,8 @@
   */
 __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 +1201,8 @@
   */
 __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 +1216,8 @@
   */
 __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
    */
@@ -1011,6 +1231,8 @@
   */
 __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
    */
@@ -1056,15 +1278,23 @@
   
   /* 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 +1340,13 @@
     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 +1367,14 @@
 
 /**
   * @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 +1463,7 @@
   *         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 +1584,49 @@
   */
 static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma)   
 {
+  /* Retrieve ADC handle corresponding to current DMA handle */
   ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+  
+  /* 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))
+  {
+    /* Update ADC state machine */
+    SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
     
-  /* 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;  
+    /* 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 +1651,15 @@
 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); 
 }
 
+/**
+  * @}
+  */
 
 /**
   * @}
    