fix LPC812 PWM

Dependents:   IR_LED_Send

Fork of mbed-dev by mbed official

Revision:
83:a036322b8637
Parent:
0:9b334a45a8ff
diff -r 98895dd43cc3 -r a036322b8637 targets/cmsis/TARGET_STM/TARGET_STM32F7/stm32f7xx_hal_adc.c
--- 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); 
 }
 
+/**
+  * @}
+  */
 
 /**
   * @}