fix LPC812 PWM
Fork of mbed-dev by
Diff: targets/cmsis/TARGET_STM/TARGET_STM32F7/stm32f7xx_hal_dma.c
- 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; +} +/** * @} */