fix LPC812 PWM

Dependents:   IR_LED_Send

Fork of mbed-dev by mbed official

Revision:
83:a036322b8637
Parent:
0:9b334a45a8ff
--- a/targets/cmsis/TARGET_STM/TARGET_STM32F7/stm32f7xx_hal_adc_ex.c	Sat Mar 05 06:00:11 2016 +0000
+++ b/targets/cmsis/TARGET_STM/TARGET_STM32F7/stm32f7xx_hal_adc_ex.c	Mon Mar 07 10:00:14 2016 +0000
@@ -2,8 +2,8 @@
   ******************************************************************************
   * @file    stm32f7xx_hal_adc_ex.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 ADC extension peripheral:
   *           + Extended features functions
@@ -131,25 +131,25 @@
 /* Private define ------------------------------------------------------------*/ 
 /* Private macro -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
 /** @addtogroup ADCEx_Private_Functions
   * @{
   */
+/* Private function prototypes -----------------------------------------------*/
 static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma);
 static void ADC_MultiModeDMAError(DMA_HandleTypeDef *hdma);
-static void ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef *hdma);
+static void ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef *hdma); 
 /**
   * @}
   */
 
-/* Exported functions ---------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
 /** @defgroup ADCEx_Exported_Functions ADC Exported Functions
   * @{
-  */ 
+  */
 
-/** @defgroup ADCEx_Exported_Functions_Group1  Extended features functions
- *  @brief    Extended features functions  
- *
+/** @defgroup ADCEx_Exported_Functions_Group1  Extended features functions 
+  *  @brief    Extended features functions  
+  *
 @verbatim   
  ===============================================================================
                  ##### Extended features functions #####
@@ -182,17 +182,7 @@
   /* Process locked */
   __HAL_LOCK(hadc);
   
-  /* Check if a regular conversion is ongoing */
-  if(hadc->State == HAL_ADC_STATE_BUSY_REG)
-  {
-    /* Change ADC state */
-    hadc->State = HAL_ADC_STATE_BUSY_INJ_REG;  
-  }
-  else
-  {
-    /* Change ADC state */
-    hadc->State = HAL_ADC_STATE_BUSY_INJ;
-  } 
+  /* Enable the ADC peripheral */
   
   /* Check if ADC peripheral is disabled in order to enable it and wait during 
      Tstab time the ADC's stabilization */
@@ -201,7 +191,7 @@
     /* Enable the Peripheral */
     __HAL_ADC_ENABLE(hadc);
     
-    /* Delay for temperature sensor stabilization time */
+    /* Delay for ADC stabilization time */
     /* Compute number of CPU cycles to wait for */
     counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000));
     while(counter != 0)
@@ -210,30 +200,57 @@
     }
   }
   
-  /* 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))
   {
-    tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
-    tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
-    if(tmp1 && tmp2)
+    /* Set ADC state                                                          */
+    /* - Clear state bitfield related to injected group conversion results    */
+    /* - Set state bitfield related to injected operation                     */
+    ADC_STATE_CLR_SET(hadc->State,
+                      HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
+                      HAL_ADC_STATE_INJ_BUSY);
+    
+    /* Check if a regular conversion is ongoing */
+    /* Note: On this device, there is no ADC error code fields related to     */
+    /*       conversions on group injected only. In case of conversion on     */
+    /*       going on group regular, no error code is reset.                  */
+    if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
     {
-      /* Enable the selected ADC software conversion for injected group */
-      hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
+      /* 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 injected group conversion flag */
+    /* (To ensure of no unknown state from potential previous ADC operations) */
+    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
+    
+    /* Check if Multimode enabled */
+    if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
+    {
+      tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
+      tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
+      if(tmp1 && tmp2)
+      {
+        /* Enable the selected ADC software conversion for injected group */
+        hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
+      }
+    }
+    else
+    {
+      tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
+      tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
+      if((hadc->Instance == ADC1) && tmp1 && tmp2)  
+      {
+        /* Enable the selected ADC software conversion for injected group */
+        hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
+      }
     }
   }
-  else
-  {
-    tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
-    tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
-    if((hadc->Instance == ADC1) && tmp1 && tmp2)  
-    {
-      /* Enable the selected ADC software conversion for injected group */
-      hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
-    }
-  }
-  
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
   
   /* Return function status */
   return HAL_OK;
@@ -249,25 +266,12 @@
 HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc)
 {
   __IO uint32_t counter = 0;
-  uint32_t tmp1 = 0, tmp2 =0;
+  uint32_t tmp1 = 0, tmp2 = 0;
   
   /* Process locked */
   __HAL_LOCK(hadc);
   
-  /* Check if a regular conversion is ongoing */
-  if(hadc->State == HAL_ADC_STATE_BUSY_REG)
-  {
-    /* Change ADC state */
-    hadc->State = HAL_ADC_STATE_BUSY_INJ_REG;  
-  }
-  else
-  {
-    /* Change ADC state */
-    hadc->State = HAL_ADC_STATE_BUSY_INJ;
-  }
-  
-  /* 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 */
@@ -276,7 +280,7 @@
     /* Enable the Peripheral */
     __HAL_ADC_ENABLE(hadc);
     
-    /* Delay for temperature sensor stabilization time */
+    /* Delay for ADC stabilization time */
     /* Compute number of CPU cycles to wait for */
     counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000));
     while(counter != 0)
@@ -285,60 +289,122 @@
     }
   }
   
-  /* Enable the ADC end of conversion interrupt for injected group */
-  __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
-  
-  /* 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 injected group conversion results    */
+    /* - Set state bitfield related to injected operation                     */
+    ADC_STATE_CLR_SET(hadc->State,
+                      HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
+                      HAL_ADC_STATE_INJ_BUSY);
+    
+    /* Check if a regular conversion is ongoing */
+    /* Note: On this device, there is no ADC error code fields related to     */
+    /*       conversions on group injected only. In case of conversion on     */
+    /*       going on group regular, no error code is reset.                  */
+    if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
+    {
+      /* 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 injected group conversion flag */
+    /* (To ensure of no unknown state from potential previous ADC operations) */
+    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
+    
+    /* Enable end of conversion interrupt for injected channels */
+    __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
+    
+    /* Check if Multimode enabled */
+    if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
+    {
+      tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
+      tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
+      if(tmp1 && tmp2)
+      {
+        /* Enable the selected ADC software conversion for injected group */
+        hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
+      }
+    }
+    else
+    {
+      tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
+      tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
+      if((hadc->Instance == ADC1) && tmp1 && tmp2)  
+      {
+        /* Enable the selected ADC software conversion for injected group */
+        hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
+      }
+    }
+  }
   
-  /* Check if Multimode enabled */
-  if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
+  /* Return function status */
+  return HAL_OK;
+}
+
+/**
+  * @brief  Stop conversion of injected channels. Disable ADC peripheral if
+  *         no regular conversion is on going.
+  * @note   If ADC must be disabled and if conversion is on going on 
+  *         regular group, function HAL_ADC_Stop must be used to stop both
+  *         injected and regular groups, and disable the ADC.
+  * @note   If injected group mode auto-injection is enabled,
+  *         function HAL_ADC_Stop must be used.
+  * @note   In case of auto-injection mode, HAL_ADC_Stop must be used.
+  * @param  hadc: ADC handle
+  * @retval None
+  */
+HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc)
+{
+  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 and disable ADC peripheral                     */
+  /* Conditioned to:                                                          */
+  /* - No conversion on the other group (regular group) is intended to        */
+  /*   continue (injected and regular groups stop conversion and ADC disable  */
+  /*   are common)                                                            */
+  /* - In case of auto-injection mode, HAL_ADC_Stop must be used.             */
+  if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET)  &&
+     HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO)   )
   {
-    tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
-    tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
-    if(tmp1 && tmp2)
+    /* Stop potential conversion on going, on regular and injected groups */
+    /* Disable ADC peripheral */
+    __HAL_ADC_DISABLE(hadc);
+    
+    /* Check if ADC is effectively disabled */
+    if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON))
     {
-      /* Enable the selected ADC software conversion for injected group */
-      hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
+      /* Set ADC state */
+      ADC_STATE_CLR_SET(hadc->State,
+                        HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+                        HAL_ADC_STATE_READY);
     }
   }
   else
   {
-    tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
-    tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
-    if((hadc->Instance == ADC1) && tmp1 && tmp2)  
-    {
-      /* Enable the selected ADC software conversion for injected group */
-      hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
-    }
+    /* Update ADC state machine to error */
+    SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+      
+    tmp_hal_status = HAL_ERROR;
   }
   
   /* Process unlocked */
   __HAL_UNLOCK(hadc);
   
   /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Disables ADC and stop conversion of injected channels.
-  *
-  * @note   Caution: This function will stop also regular channels.  
-  *
-  * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains
-  *         the configuration information for the specified ADC.
-  * @retval HAL status.
-  */
-HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc)
-{
-  /* Disable the Peripheral */
-  __HAL_ADC_DISABLE(hadc);
-  
-  /* Change ADC state */
-  hadc->State = HAL_ADC_STATE_READY;
-  
-  /* Return function status */
-  return HAL_OK;
+  return tmp_hal_status;
 }
 
 /**
@@ -371,16 +437,32 @@
     }
   }
   
-  /* Check if a regular conversion is ready */
-  if(hadc->State == HAL_ADC_STATE_EOC_REG)
+  /* Clear injected group conversion flag */
+  __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JSTRT | ADC_FLAG_JEOC);
+    
+  /* Update ADC state machine */
+  SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
+  
+  /* Determine whether any further conversion upcoming on group injected      */
+  /* 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_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)   )       )   )
   {
-    /* 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 */
+    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);
+    }
   }
   
   /* Return ADC state */
@@ -388,30 +470,65 @@
 }      
   
 /**
-  * @brief  Disables the interrupt and stop ADC conversion of injected channels.
-  * 
-  * @note   Caution: This function will stop also regular channels.  
-  *
-  * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains
-  *         the configuration information for the specified ADC.
-  * @retval HAL status.
+  * @brief  Stop conversion of injected channels, disable interruption of 
+  *         end-of-conversion. Disable ADC peripheral if no regular conversion
+  *         is on going.
+  * @note   If ADC must be disabled and if conversion is on going on 
+  *         regular group, function HAL_ADC_Stop must be used to stop both
+  *         injected and regular groups, and disable the ADC.
+  * @note   If injected group mode auto-injection is enabled,
+  *         function HAL_ADC_Stop must be used.
+  * @param  hadc: ADC handle
+  * @retval None
   */
 HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc)
 {
-  /* Disable the ADC end of conversion interrupt for regular group */
-  __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
-  
-  /* Disable the ADC end of conversion interrupt for injected group */
-  __HAL_ADC_DISABLE_IT(hadc, ADC_CR1_JEOCIE);
+  HAL_StatusTypeDef tmp_hal_status = HAL_OK;
   
-  /* Enable the Peripheral */
-  __HAL_ADC_DISABLE(hadc);
+  /* Check the parameters */
+  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+  /* Process locked */
+  __HAL_LOCK(hadc);
+    
+  /* Stop potential conversion and disable ADC peripheral                     */
+  /* Conditioned to:                                                          */
+  /* - No conversion on the other group (regular group) is intended to        */
+  /*   continue (injected and regular groups stop conversion and ADC disable  */
+  /*   are common)                                                            */
+  /* - In case of auto-injection mode, HAL_ADC_Stop must be used.             */ 
+  if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET)  &&
+     HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO)   )
+  {
+    /* Stop potential conversion on going, on regular and injected groups */
+    /* Disable ADC peripheral */
+    __HAL_ADC_DISABLE(hadc);
+    
+    /* Check if ADC is effectively disabled */
+    if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON))
+    {
+      /* Disable ADC end of conversion interrupt for injected channels */
+      __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
+      
+      /* Set ADC state */
+      ADC_STATE_CLR_SET(hadc->State,
+                        HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+                        HAL_ADC_STATE_READY);
+    }
+  }
+  else
+  {
+    /* Update ADC state machine to error */
+    SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+      
+    tmp_hal_status = HAL_ERROR;
+  }
   
-  /* Change ADC state */
-  hadc->State = HAL_ADC_STATE_READY;
+  /* Process unlocked */
+  __HAL_UNLOCK(hadc);
   
   /* Return function status */
-  return HAL_OK;
+  return tmp_hal_status;
 }
 
 /**
@@ -433,8 +550,9 @@
   /* Check the parameters */
   assert_param(IS_ADC_INJECTED_RANK(InjectedRank));
   
-   /* Clear the ADCx's flag for injected end of conversion */
-   __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_JEOC);
+  /* Clear injected group conversion flag to have similar behaviour as        */
+  /* regular group: reading data register also clears end of conversion flag. */
+  __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
   
   /* Return the selected ADC converted value */ 
   switch(InjectedRank)
@@ -488,35 +606,6 @@
   /* Process locked */
   __HAL_LOCK(hadc);
   
-  /* Enable ADC overrun interrupt */
-  __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
-  
-  if (hadc->Init.DMAContinuousRequests != DISABLE)
-  {
-    /* Enable the selected ADC DMA request after last transfer */
-    ADC->CCR |= ADC_CCR_DDS;
-  }
-  else
-  {
-    /* Disable the selected ADC EOC rising on each regular channel conversion */
-    ADC->CCR &= ~ADC_CCR_DDS;
-  }
-  
-  /* Set the DMA transfer complete callback */
-  hadc->DMA_Handle->XferCpltCallback = ADC_MultiModeDMAConvCplt;
-  
-  /* Set the DMA half transfer complete callback */
-  hadc->DMA_Handle->XferHalfCpltCallback = ADC_MultiModeDMAHalfConvCplt;
-     
-  /* Set the DMA error callback */
-  hadc->DMA_Handle->XferErrorCallback = ADC_MultiModeDMAError ;
-  
-  /* Enable the DMA Stream */
-  HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&ADC->CDR, (uint32_t)pData, Length);
-  
-  /* Change ADC state */
-  hadc->State = HAL_ADC_STATE_BUSY_REG;
-  
   /* 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)
@@ -533,16 +622,81 @@
     }
   }
   
-  /* 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 |= (uint32_t)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_MultiModeDMAConvCplt;
+    
+    /* Set the DMA half transfer complete callback */
+    hadc->DMA_Handle->XferHalfCpltCallback = ADC_MultiModeDMAHalfConvCplt;
+    
+    /* Set the DMA error callback */
+    hadc->DMA_Handle->XferErrorCallback = ADC_MultiModeDMAError ;
+    
+    /* 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);
+    
+    if (hadc->Init.DMAContinuousRequests != DISABLE)
+    {
+      /* Enable the selected ADC DMA request after last transfer */
+      ADC->CCR |= ADC_CCR_DDS;
+    }
+    else
+    {
+      /* Disable the selected ADC EOC rising on each regular channel conversion */
+      ADC->CCR &= ~ADC_CCR_DDS;
+    }
+    
+    /* Enable the DMA Stream */
+    HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&ADC->CDR, (uint32_t)pData, Length);
+    
+    /* 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;
+    }
   }
   
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-  
   /* Return function status */
   return HAL_OK;
 }
@@ -555,29 +709,42 @@
   */
 HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc)
 {
+  HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+  
+  /* Check the parameters */
+  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+  
   /* 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);
   
-  /* Disable ADC overrun interrupt */
-  __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
-  
-  /* Disable the selected ADC DMA request after last transfer */
-  ADC->CCR &= ~ADC_CCR_DDS;
-  
-  /* Disable the ADC DMA Stream */
-  HAL_DMA_Abort(hadc->DMA_Handle);
-  
-  /* 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 the selected ADC DMA mode for multimode */
+    ADC->CCR &= ~ADC_CCR_DDS;
+    
+    /* 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);
+  }
   
   /* Process unlocked */
   __HAL_UNLOCK(hadc);
-    
+  
   /* Return function status */
-  return HAL_OK;
+  return tmp_hal_status;
 }
 
 /**
@@ -601,6 +768,8 @@
   */
 __weak void HAL_ADCEx_InjectedConvCpltCallback(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_InjectedConvCpltCallback could be implemented in the user file
    */
@@ -616,7 +785,7 @@
   */
 HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_InjectionConfTypeDef* sConfigInjected)
 {
-
+  
 #ifdef USE_FULL_ASSERT  
   uint32_t tmp = 0;
 #endif /* USE_FULL_ASSERT  */
@@ -626,7 +795,6 @@
   assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank));
   assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime));
   assert_param(IS_ADC_EXT_INJEC_TRIG(sConfigInjected->ExternalTrigInjecConv));
-  assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(sConfigInjected->ExternalTrigInjecConvEdge));
   assert_param(IS_ADC_INJECTED_LENGTH(sConfigInjected->InjectedNbrOfConversion));
   assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv));
   assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode));
@@ -636,6 +804,11 @@
   assert_param(IS_ADC_RANGE(tmp, sConfigInjected->InjectedOffset));
 #endif /* USE_FULL_ASSERT  */
 
+  if(sConfigInjected->ExternalTrigInjecConvEdge != ADC_INJECTED_SOFTWARE_START)
+  {
+    assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(sConfigInjected->ExternalTrigInjecConvEdge));
+  }
+
   /* Process locked */
   __HAL_LOCK(hadc);
   
@@ -669,13 +842,27 @@
   /* Set the SQx bits for the selected rank */
   hadc->Instance->JSQR |= ADC_JSQR(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank,sConfigInjected->InjectedNbrOfConversion);
 
-  /* Select external trigger to start conversion */
-  hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL);
-  hadc->Instance->CR2 |=  sConfigInjected->ExternalTrigInjecConv;
-  
-  /* Select external trigger polarity */
-  hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN);
-  hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConvEdge;
+  /* Enable external trigger if trigger selection is different of software  */
+  /* start.                                                                 */
+  /* Note: This configuration keeps the hardware feature of parameter       */
+  /*       ExternalTrigConvEdge "trigger edge none" equivalent to           */
+  /*       software start.                                                  */ 
+  if(sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START)
+  {  
+    /* Select external trigger to start conversion */
+    hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL);
+    hadc->Instance->CR2 |=  sConfigInjected->ExternalTrigInjecConv;
+    
+    /* Select external trigger polarity */
+    hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN);
+    hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConvEdge;
+  }
+  else
+  {
+    /* Reset the external trigger */
+    hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL);
+    hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN);  
+  }
   
   if (sConfigInjected->AutoInjectedConv != DISABLE)
   {
@@ -793,21 +980,49 @@
   */
 static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma)   
 {
-    ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+  /* 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); 
 }
 
 /**
@@ -832,7 +1047,7 @@
 static void ADC_MultiModeDMAError(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);