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_dma.c	Sat Mar 05 06:00:11 2016 +0000
+++ b/targets/cmsis/TARGET_STM/TARGET_STM32F7/stm32f7xx_hal_dma.c	Mon Mar 07 10:00:14 2016 +0000
@@ -2,8 +2,8 @@
   ******************************************************************************
   * @file    stm32f7xx_hal_dma.c
   * @author  MCD Application Team
-  * @version V1.0.1
-  * @date    25-June-2015
+  * @version V1.0.4
+  * @date    09-December-2015
   * @brief   DMA HAL module driver.
   *    
   *          This file provides firmware functions to manage the following 
@@ -73,8 +73,6 @@
       (+) __HAL_DMA_ENABLE: Enable the specified DMA Stream.
       (+) __HAL_DMA_DISABLE: Disable the specified DMA Stream.
       (+) __HAL_DMA_GET_FS: Return the current DMA Stream FIFO filled level.
-      (+) __HAL_DMA_GET_FLAG: Get the DMA Stream pending flags.
-      (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Stream pending flags.
       (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Stream interrupts.
       (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Stream interrupts.
       (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Stream interrupt has occurred or not. 
@@ -128,6 +126,13 @@
 #ifdef HAL_DMA_MODULE_ENABLED
 
 /* Private types -------------------------------------------------------------*/
+typedef struct
+{
+  __IO uint32_t ISR;   /*!< DMA interrupt status register */
+  __IO uint32_t Reserved0;
+  __IO uint32_t IFCR;  /*!< DMA interrupt flag clear register */
+} DMA_Base_Registers;
+
 /* Private variables ---------------------------------------------------------*/
 /* Private constants ---------------------------------------------------------*/
 /** @addtogroup DMA_Private_Constants
@@ -143,6 +148,8 @@
   * @{
   */
 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
+static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
+
 /**
   * @brief  Sets the DMA Transfer parameter.
   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
@@ -291,6 +298,10 @@
   /* Write to DMA Stream FCR */
   hdma->Instance->FCR = tmp;
 
+  /* Initialize StreamBaseAddress and StreamIndex parameters to be used to calculate
+     DMA steam Base Address needed by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */
+  DMA_CalcBaseAndBitshift(hdma);
+	
   /* Initialize the error code */
   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
 
@@ -308,6 +319,8 @@
   */
 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
 {
+	DMA_Base_Registers *regs;
+	
   /* Check the DMA peripheral state */
   if(hdma == NULL)
   {
@@ -341,12 +354,11 @@
   /* Reset DMA Streamx FIFO control register */
   hdma->Instance->FCR  = (uint32_t)0x00000021;
 
-  /* Clear all flags */
-  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
-  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
-  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
-  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
-  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
+  /* Get DMA steam Base Address */  
+  regs = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
+  
+  /* Clear all interrupt flags at correct offset within the register */
+  regs->IFCR = 0x3F << hdma->StreamIndex;
 
   /* Initialize the error code */
   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
@@ -440,20 +452,9 @@
   /* Configure the source, destination address and the data length */
   DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
 
-  /* Enable the transfer complete interrupt */
-  __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC);
-
-  /* Enable the Half transfer complete interrupt */
-  __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);  
-
-  /* Enable the transfer Error interrupt */
-  __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE);
-
-  /* Enable the FIFO Error interrupt */
-  __HAL_DMA_ENABLE_IT(hdma, DMA_IT_FE);
-
-  /* Enable the direct mode Error interrupt */
-  __HAL_DMA_ENABLE_IT(hdma, DMA_IT_DME);
+  /* Enable all interrupts */
+  hdma->Instance->CR  |= DMA_IT_TC | DMA_IT_HT | DMA_IT_TE | DMA_IT_DME;
+  hdma->Instance->FCR |= DMA_IT_FE;
 
    /* Enable the Peripheral */
   __HAL_DMA_ENABLE(hdma);
@@ -523,26 +524,31 @@
   uint32_t temp, tmp, tmp1, tmp2;
   uint32_t tickstart = 0; 
 
+  /* calculate DMA base and stream number */
+  DMA_Base_Registers *regs;
+  
+  regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
+	
   /* Get the level transfer complete flag */
   if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
   {
     /* Transfer Complete flag */
-    temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
+		temp = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;
   }
   else
   {
     /* Half Transfer Complete flag */
-    temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
+		temp = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
   }
 
   /* Get tick */
   tickstart = HAL_GetTick();
 
-  while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
+  while((regs->ISR & temp) == RESET)
   {
-    tmp  = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
-    tmp1 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
-    tmp2 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
+    tmp  = regs->ISR & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex);
+    tmp1 = regs->ISR & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex);
+    tmp2 = regs->ISR & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex);
     if((tmp != RESET) || (tmp1 != RESET) || (tmp2 != RESET))
     {
       if(tmp != RESET)
@@ -551,7 +557,7 @@
         hdma->ErrorCode |= HAL_DMA_ERROR_TE;
 
         /* Clear the transfer error flag */
-        __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
+        regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex;
       }
       if(tmp1 != RESET)
       {
@@ -559,7 +565,7 @@
         hdma->ErrorCode |= HAL_DMA_ERROR_FE;
  
         /* Clear the FIFO error flag */
-        __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
+        regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;
       }
       if(tmp2 != RESET)
       {
@@ -567,7 +573,7 @@
         hdma->ErrorCode |= HAL_DMA_ERROR_DME;
 
         /* Clear the Direct Mode error flag */
-        __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
+        regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex;
       }
       /* Change the DMA state */
       hdma->State= HAL_DMA_STATE_ERROR;
@@ -598,14 +604,12 @@
 
   if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
   {
+    /* Clear the half transfer and transfer complete flags */
+    regs->IFCR = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << hdma->StreamIndex;
+		
     /* Multi_Buffering mode enabled */
     if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
     {
-      /* Clear the half transfer complete flag */
-      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
-      /* Clear the transfer complete flag */
-      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
-
       /* Current memory buffer used is Memory 0 */
       if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
       {
@@ -621,11 +625,6 @@
     }
     else
     {
-      /* Clear the half transfer complete flag */
-      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
-      /* Clear the transfer complete flag */
-      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); 
-
       /* The selected Streamx EN bit is cleared (DMA is disabled and all transfers
          are complete) */
       hdma->State = HAL_DMA_STATE_READY_MEM0;
@@ -634,13 +633,13 @@
     __HAL_UNLOCK(hdma);
   }
   else
-  { 
+  {
+    /* Clear the half transfer complete flag */
+    regs->IFCR = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
+		
     /* Multi_Buffering mode enabled */
     if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
     {
-      /* Clear the half transfer complete flag */
-      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
-
       /* Current memory buffer used is Memory 0 */
       if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
       {
@@ -656,9 +655,6 @@
     }
     else
     {
-      /* Clear the half transfer complete flag */
-      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
-
       /* Change DMA peripheral state */
       hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
     }
@@ -674,8 +670,13 @@
   */
 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
 {
+  /* calculate DMA base and stream number */
+  DMA_Base_Registers *regs;
+
+  regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
+	
   /* Transfer Error Interrupt management ***************************************/
-  if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)
+  if ((regs->ISR & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET)
   {
     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
     {
@@ -683,7 +684,7 @@
       __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);
 
       /* Clear the transfer error flag */
-      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
+      regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex;
 
       /* Update error code */
       hdma->ErrorCode |= HAL_DMA_ERROR_TE;
@@ -702,7 +703,7 @@
     }
   }
   /* FIFO Error Interrupt management ******************************************/
-  if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)) != RESET)
+  if ((regs->ISR & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
   {
     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
     {
@@ -710,7 +711,7 @@
       __HAL_DMA_DISABLE_IT(hdma, DMA_IT_FE);
 
       /* Clear the FIFO error flag */
-      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
+      regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;
 
       /* Update error code */
       hdma->ErrorCode |= HAL_DMA_ERROR_FE;
@@ -729,7 +730,7 @@
     }
   }
   /* Direct Mode Error Interrupt management ***********************************/
-  if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)) != RESET)
+  if ((regs->ISR & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET)
   {
     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
     {
@@ -737,7 +738,7 @@
       __HAL_DMA_DISABLE_IT(hdma, DMA_IT_DME);
 
       /* Clear the direct mode error flag */
-      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
+      regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex;
 
       /* Update error code */
       hdma->ErrorCode |= HAL_DMA_ERROR_DME;
@@ -756,7 +757,7 @@
     }
   }
   /* Half Transfer Complete Interrupt management ******************************/
-  if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
+  if ((regs->ISR & (DMA_FLAG_HTIF0_4 << hdma->StreamIndex)) != RESET)
   {
     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
     { 
@@ -764,7 +765,7 @@
       if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
       {
         /* Clear the half transfer complete flag */
-        __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
+        regs->IFCR = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
 
         /* Current memory buffer used is Memory 0 */
         if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
@@ -788,7 +789,7 @@
           __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
         }
         /* Clear the half transfer complete flag */
-        __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
+        regs->IFCR = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
 
         /* Change DMA peripheral state */
         hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
@@ -802,14 +803,14 @@
     }
   }
   /* Transfer Complete Interrupt management ***********************************/
-  if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)
+  if ((regs->ISR & (DMA_FLAG_TCIF0_4 << hdma->StreamIndex)) != RESET)
   {
     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
     {
       if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
       {
         /* Clear the transfer complete flag */
-        __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
+        regs->IFCR = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;
 
         /* Current memory buffer used is Memory 1 */
         if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
@@ -839,7 +840,7 @@
           __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);
         }
         /* Clear the transfer complete flag */
-        __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
+        regs->IFCR = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;
 
         /* Update error code */
         hdma->ErrorCode |= HAL_DMA_ERROR_NONE;
@@ -860,6 +861,7 @@
   }
 }
 
+
 /**
   * @}
   */
@@ -906,6 +908,33 @@
   */
 
 /**
+  * @brief  Returns the DMA Stream base address depending on stream number
+  * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
+  *                     the configuration information for the specified DMA Stream. 
+  * @retval Stream base address
+  */
+static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
+{
+  uint32_t stream_number = (((uint32_t)hdma->Instance & 0xFF) - 16) / 24;
+  
+  /* lookup table for necessary bitshift of flags within status registers */
+  static const uint8_t flagBitshiftOffset[8] = {0, 6, 16, 22, 0, 6, 16, 22};
+  hdma->StreamIndex = flagBitshiftOffset[stream_number];
+  
+  if (stream_number > 3)
+  {
+    /* return pointer to HISR and HIFCR */
+    hdma->StreamBaseAddress = (((uint32_t)hdma->Instance & (uint32_t)(~0x3FF)) + 4);
+  }
+  else
+  {
+    /* return pointer to LISR and LIFCR */
+    hdma->StreamBaseAddress = ((uint32_t)hdma->Instance & (uint32_t)(~0x3FF));
+  }
+  
+  return hdma->StreamBaseAddress;
+}
+/**
   * @}
   */