--- /dev/null
+/**\r
+ ******************************************************************************\r
+ * @file stm32f7xx_hal_dma.c\r
+ * @author MCD Application Team\r
+ * @version V1.0.0RC1\r
+ * @date 24-March-2015\r
+ * @brief DMA HAL module driver.\r
+ * \r
+ * This file provides firmware functions to manage the following \r
+ * functionalities of the Direct Memory Access (DMA) peripheral:\r
+ * + Initialization and de-initialization functions\r
+ * + IO operation functions\r
+ * + Peripheral State and errors functions\r
+ @verbatim \r
+ ============================================================================== \r
+ ##### How to use this driver #####\r
+ ============================================================================== \r
+ [..]\r
+ (#) Enable and configure the peripheral to be connected to the DMA Stream\r
+ (except for internal SRAM/FLASH memories: no initialization is \r
+ necessary) please refer to Reference manual for connection between peripherals\r
+ and DMA requests . \r
+ \r
+ (#) For a given Stream, program the required configuration through the following parameters: \r
+ Transfer Direction, Source and Destination data formats, \r
+ Circular, Normal or peripheral flow control mode, Stream Priority level, \r
+ Source and Destination Increment mode, FIFO mode and its Threshold (if needed), \r
+ Burst mode for Source and/or Destination (if needed) using HAL_DMA_Init() function.\r
+ \r
+ *** Polling mode IO operation ***\r
+ ================================= \r
+ [..] \r
+ (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source \r
+ address and destination address and the Length of data to be transferred\r
+ (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this \r
+ case a fixed Timeout can be configured by User depending from his application.\r
+ \r
+ *** Interrupt mode IO operation *** \r
+ =================================== \r
+ [..] \r
+ (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()\r
+ (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ() \r
+ (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of \r
+ Source address and destination address and the Length of data to be transferred. In this \r
+ case the DMA interrupt is configured \r
+ (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine\r
+ (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can \r
+ add his own function by customization of function pointer XferCpltCallback and \r
+ XferErrorCallback (i.e a member of DMA handle structure). \r
+ [..] \r
+ (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error \r
+ detection.\r
+ \r
+ (#) Use HAL_DMA_Abort() function to abort the current transfer\r
+ \r
+ -@- In Memory-to-Memory transfer mode, Circular mode is not allowed.\r
+ \r
+ -@- The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is\r
+ possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set\r
+ Half-Word data size for the peripheral to access its data register and set Word data size\r
+ for the Memory to gain in access time. Each two half words will be packed and written in\r
+ a single access to a Word in the Memory).\r
+ \r
+ -@- When FIFO is disabled, it is not allowed to configure different Data Sizes for Source\r
+ and Destination. In this case the Peripheral Data Size will be applied to both Source\r
+ and Destination. \r
+ \r
+ *** DMA HAL driver macros list ***\r
+ ============================================= \r
+ [..]\r
+ Below the list of most used macros in DMA HAL driver.\r
+ \r
+ (+) __HAL_DMA_ENABLE: Enable the specified DMA Stream.\r
+ (+) __HAL_DMA_DISABLE: Disable the specified DMA Stream.\r
+ (+) __HAL_DMA_GET_FS: Return the current DMA Stream FIFO filled level.\r
+ (+) __HAL_DMA_GET_FLAG: Get the DMA Stream pending flags.\r
+ (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Stream pending flags.\r
+ (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Stream interrupts.\r
+ (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Stream interrupts.\r
+ (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Stream interrupt has occurred or not. \r
+ \r
+ [..] \r
+ (@) You can refer to the DMA HAL driver header file for more useful macros \r
+ \r
+ @endverbatim\r
+ ******************************************************************************\r
+ * @attention\r
+ *\r
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ * this list of conditions and the following disclaimer in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors\r
+ * may be used to endorse or promote products derived from this software\r
+ * without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ ******************************************************************************\r
+ */ \r
+\r
+/* Includes ------------------------------------------------------------------*/\r
+#include "stm32f7xx_hal.h"\r
+\r
+/** @addtogroup STM32F7xx_HAL_Driver\r
+ * @{\r
+ */\r
+\r
+/** @defgroup DMA DMA\r
+ * @brief DMA HAL module driver\r
+ * @{\r
+ */\r
+\r
+#ifdef HAL_DMA_MODULE_ENABLED\r
+\r
+/* Private types -------------------------------------------------------------*/\r
+/* Private variables ---------------------------------------------------------*/\r
+/* Private constants ---------------------------------------------------------*/\r
+/** @addtogroup DMA_Private_Constants\r
+ * @{\r
+ */\r
+ #define HAL_TIMEOUT_DMA_ABORT ((uint32_t)1000) /* 1s */\r
+/**\r
+ * @}\r
+ */\r
+/* Private macros ------------------------------------------------------------*/\r
+/* Private functions ---------------------------------------------------------*/\r
+/** @addtogroup DMA_Private_Functions\r
+ * @{\r
+ */\r
+static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);\r
+/**\r
+ * @brief Sets the DMA Transfer parameter.\r
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains\r
+ * the configuration information for the specified DMA Stream.\r
+ * @param SrcAddress: The source memory Buffer address\r
+ * @param DstAddress: The destination memory Buffer address\r
+ * @param DataLength: The length of data to be transferred from source to destination\r
+ * @retval HAL status\r
+ */\r
+static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)\r
+{\r
+ /* Clear DBM bit */\r
+ hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);\r
+ \r
+ /* Configure DMA Stream data length */\r
+ hdma->Instance->NDTR = DataLength;\r
+\r
+ /* Peripheral to Memory */\r
+ if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)\r
+ {\r
+ /* Configure DMA Stream destination address */\r
+ hdma->Instance->PAR = DstAddress;\r
+\r
+ /* Configure DMA Stream source address */\r
+ hdma->Instance->M0AR = SrcAddress;\r
+ }\r
+ /* Memory to Peripheral */\r
+ else\r
+ {\r
+ /* Configure DMA Stream source address */\r
+ hdma->Instance->PAR = SrcAddress;\r
+ \r
+ /* Configure DMA Stream destination address */\r
+ hdma->Instance->M0AR = DstAddress;\r
+ }\r
+}\r
+\r
+/**\r
+ * @}\r
+ */ \r
+ \r
+/* Exported functions ---------------------------------------------------------*/\r
+/** @addtogroup DMA_Exported_Functions\r
+ * @{\r
+ */\r
+\r
+/** @addtogroup DMA_Exported_Functions_Group1\r
+ *\r
+@verbatim \r
+ ===============================================================================\r
+ ##### Initialization and de-initialization functions #####\r
+ =============================================================================== \r
+ [..]\r
+ This section provides functions allowing to initialize the DMA Stream source\r
+ and destination addresses, incrementation and data sizes, transfer direction, \r
+ circular/normal mode selection, memory-to-memory mode selection and Stream priority value.\r
+ [..]\r
+ The HAL_DMA_Init() function follows the DMA configuration procedures as described in\r
+ reference manual. \r
+\r
+@endverbatim\r
+ * @{\r
+ */\r
+ \r
+/**\r
+ * @brief Initializes the DMA according to the specified\r
+ * parameters in the DMA_InitTypeDef and create the associated handle.\r
+ * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains\r
+ * the configuration information for the specified DMA Stream. \r
+ * @retval HAL status\r
+ */\r
+HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)\r
+{ \r
+ uint32_t tmp = 0;\r
+ \r
+ /* Check the DMA peripheral state */\r
+ if(hdma == NULL)\r
+ {\r
+ return HAL_ERROR;\r
+ }\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));\r
+ assert_param(IS_DMA_CHANNEL(hdma->Init.Channel));\r
+ assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));\r
+ assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));\r
+ assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));\r
+ assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));\r
+ assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));\r
+ assert_param(IS_DMA_MODE(hdma->Init.Mode));\r
+ assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));\r
+ assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode));\r
+ /* Check the memory burst, peripheral burst and FIFO threshold parameters only\r
+ when FIFO mode is enabled */\r
+ if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE)\r
+ {\r
+ assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold));\r
+ assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst));\r
+ assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst));\r
+ }\r
+\r
+ /* Change DMA peripheral state */\r
+ hdma->State = HAL_DMA_STATE_BUSY;\r
+\r
+ /* Get the CR register value */\r
+ tmp = hdma->Instance->CR;\r
+\r
+ /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */\r
+ tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \\r
+ DMA_SxCR_PL | DMA_SxCR_MSIZE | DMA_SxCR_PSIZE | \\r
+ DMA_SxCR_MINC | DMA_SxCR_PINC | DMA_SxCR_CIRC | \\r
+ DMA_SxCR_DIR | DMA_SxCR_CT | DMA_SxCR_DBM));\r
+\r
+ /* Prepare the DMA Stream configuration */\r
+ tmp |= hdma->Init.Channel | hdma->Init.Direction |\r
+ hdma->Init.PeriphInc | hdma->Init.MemInc |\r
+ hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |\r
+ hdma->Init.Mode | hdma->Init.Priority;\r
+\r
+ /* the Memory burst and peripheral burst are not used when the FIFO is disabled */\r
+ if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)\r
+ {\r
+ /* Get memory burst and peripheral burst */\r
+ tmp |= hdma->Init.MemBurst | hdma->Init.PeriphBurst;\r
+ }\r
+ \r
+ /* Write to DMA Stream CR register */\r
+ hdma->Instance->CR = tmp; \r
+\r
+ /* Get the FCR register value */\r
+ tmp = hdma->Instance->FCR;\r
+\r
+ /* Clear Direct mode and FIFO threshold bits */\r
+ tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);\r
+\r
+ /* Prepare the DMA Stream FIFO configuration */\r
+ tmp |= hdma->Init.FIFOMode;\r
+\r
+ /* the FIFO threshold is not used when the FIFO mode is disabled */\r
+ if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)\r
+ {\r
+ /* Get the FIFO threshold */\r
+ tmp |= hdma->Init.FIFOThreshold;\r
+ }\r
+ \r
+ /* Write to DMA Stream FCR */\r
+ hdma->Instance->FCR = tmp;\r
+\r
+ /* Initialize the error code */\r
+ hdma->ErrorCode = HAL_DMA_ERROR_NONE;\r
+\r
+ /* Initialize the DMA state */\r
+ hdma->State = HAL_DMA_STATE_READY;\r
+\r
+ return HAL_OK;\r
+}\r
+\r
+/**\r
+ * @brief DeInitializes the DMA peripheral \r
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains\r
+ * the configuration information for the specified DMA Stream. \r
+ * @retval HAL status\r
+ */\r
+HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)\r
+{\r
+ /* Check the DMA peripheral state */\r
+ if(hdma == NULL)\r
+ {\r
+ return HAL_ERROR;\r
+ }\r
+ \r
+ /* Check the DMA peripheral state */\r
+ if(hdma->State == HAL_DMA_STATE_BUSY)\r
+ {\r
+ return HAL_ERROR;\r
+ }\r
+\r
+ /* Disable the selected DMA Streamx */\r
+ __HAL_DMA_DISABLE(hdma);\r
+\r
+ /* Reset DMA Streamx control register */\r
+ hdma->Instance->CR = 0;\r
+\r
+ /* Reset DMA Streamx number of data to transfer register */\r
+ hdma->Instance->NDTR = 0;\r
+\r
+ /* Reset DMA Streamx peripheral address register */\r
+ hdma->Instance->PAR = 0;\r
+\r
+ /* Reset DMA Streamx memory 0 address register */\r
+ hdma->Instance->M0AR = 0;\r
+\r
+ /* Reset DMA Streamx memory 1 address register */\r
+ hdma->Instance->M1AR = 0;\r
+\r
+ /* Reset DMA Streamx FIFO control register */\r
+ hdma->Instance->FCR = (uint32_t)0x00000021;\r
+\r
+ /* Clear all flags */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
+\r
+ /* Initialize the error code */\r
+ hdma->ErrorCode = HAL_DMA_ERROR_NONE;\r
+\r
+ /* Initialize the DMA state */\r
+ hdma->State = HAL_DMA_STATE_RESET;\r
+\r
+ /* Release Lock */\r
+ __HAL_UNLOCK(hdma);\r
+\r
+ return HAL_OK;\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/** @addtogroup DMA_Exported_Functions_Group2\r
+ *\r
+@verbatim \r
+ ===============================================================================\r
+ ##### IO operation functions #####\r
+ =============================================================================== \r
+ [..] This section provides functions allowing to:\r
+ (+) Configure the source, destination address and data length and Start DMA transfer\r
+ (+) Configure the source, destination address and data length and \r
+ Start DMA transfer with interrupt\r
+ (+) Abort DMA transfer\r
+ (+) Poll for transfer complete\r
+ (+) Handle DMA interrupt request \r
+\r
+@endverbatim\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Starts the DMA Transfer.\r
+ * @param hdma : pointer to a DMA_HandleTypeDef structure that contains\r
+ * the configuration information for the specified DMA Stream. \r
+ * @param SrcAddress: The source memory Buffer address\r
+ * @param DstAddress: The destination memory Buffer address\r
+ * @param DataLength: The length of data to be transferred from source to destination\r
+ * @retval HAL status\r
+ */\r
+HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)\r
+{\r
+ /* Process locked */\r
+ __HAL_LOCK(hdma);\r
+\r
+ /* Change DMA peripheral state */\r
+ hdma->State = HAL_DMA_STATE_BUSY;\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_DMA_BUFFER_SIZE(DataLength));\r
+\r
+ /* Disable the peripheral */\r
+ __HAL_DMA_DISABLE(hdma);\r
+\r
+ /* Configure the source, destination address and the data length */\r
+ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);\r
+\r
+ /* Enable the Peripheral */\r
+ __HAL_DMA_ENABLE(hdma);\r
+\r
+ return HAL_OK; \r
+}\r
+\r
+/**\r
+ * @brief Start the DMA Transfer with interrupt enabled.\r
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains\r
+ * the configuration information for the specified DMA Stream. \r
+ * @param SrcAddress: The source memory Buffer address\r
+ * @param DstAddress: The destination memory Buffer address\r
+ * @param DataLength: The length of data to be transferred from source to destination\r
+ * @retval HAL status\r
+ */\r
+HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)\r
+{\r
+ /* Process locked */\r
+ __HAL_LOCK(hdma);\r
+\r
+ /* Change DMA peripheral state */\r
+ hdma->State = HAL_DMA_STATE_BUSY;\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_DMA_BUFFER_SIZE(DataLength));\r
+\r
+ /* Disable the peripheral */\r
+ __HAL_DMA_DISABLE(hdma);\r
+\r
+ /* Configure the source, destination address and the data length */\r
+ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);\r
+\r
+ /* Enable the transfer complete interrupt */\r
+ __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC);\r
+\r
+ /* Enable the Half transfer complete interrupt */\r
+ __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT); \r
+\r
+ /* Enable the transfer Error interrupt */\r
+ __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE);\r
+\r
+ /* Enable the FIFO Error interrupt */\r
+ __HAL_DMA_ENABLE_IT(hdma, DMA_IT_FE);\r
+\r
+ /* Enable the direct mode Error interrupt */\r
+ __HAL_DMA_ENABLE_IT(hdma, DMA_IT_DME);\r
+\r
+ /* Enable the Peripheral */\r
+ __HAL_DMA_ENABLE(hdma);\r
+\r
+ return HAL_OK;\r
+} \r
+\r
+/**\r
+ * @brief Aborts the DMA Transfer.\r
+ * @param hdma : pointer to a DMA_HandleTypeDef structure that contains\r
+ * the configuration information for the specified DMA Stream.\r
+ * \r
+ * @note After disabling a DMA Stream, a check for wait until the DMA Stream is \r
+ * effectively disabled is added. If a Stream is disabled \r
+ * while a data transfer is ongoing, the current data will be transferred\r
+ * and the Stream will be effectively disabled only after the transfer of\r
+ * this single data is finished. \r
+ * @retval HAL status\r
+ */\r
+HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)\r
+{\r
+ uint32_t tickstart = 0;\r
+\r
+ /* Disable the stream */\r
+ __HAL_DMA_DISABLE(hdma);\r
+\r
+ /* Get tick */\r
+ tickstart = HAL_GetTick();\r
+\r
+ /* Check if the DMA Stream is effectively disabled */\r
+ while((hdma->Instance->CR & DMA_SxCR_EN) != 0)\r
+ {\r
+ /* Check for the Timeout */\r
+ if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)\r
+ {\r
+ /* Update error code */\r
+ hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;\r
+ \r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(hdma);\r
+ \r
+ /* Change the DMA state */\r
+ hdma->State = HAL_DMA_STATE_TIMEOUT;\r
+ \r
+ return HAL_TIMEOUT;\r
+ }\r
+ }\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(hdma);\r
+\r
+ /* Change the DMA state*/\r
+ hdma->State = HAL_DMA_STATE_READY;\r
+\r
+ return HAL_OK;\r
+}\r
+\r
+/**\r
+ * @brief Polling for transfer complete.\r
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains\r
+ * the configuration information for the specified DMA Stream.\r
+ * @param CompleteLevel: Specifies the DMA level complete. \r
+ * @param Timeout: Timeout duration.\r
+ * @retval HAL status\r
+ */\r
+HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)\r
+{\r
+ uint32_t temp, tmp, tmp1, tmp2;\r
+ uint32_t tickstart = 0; \r
+\r
+ /* Get the level transfer complete flag */\r
+ if(CompleteLevel == HAL_DMA_FULL_TRANSFER)\r
+ {\r
+ /* Transfer Complete flag */\r
+ temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);\r
+ }\r
+ else\r
+ {\r
+ /* Half Transfer Complete flag */\r
+ temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);\r
+ }\r
+\r
+ /* Get tick */\r
+ tickstart = HAL_GetTick();\r
+\r
+ while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)\r
+ {\r
+ tmp = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));\r
+ tmp1 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));\r
+ tmp2 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));\r
+ if((tmp != RESET) || (tmp1 != RESET) || (tmp2 != RESET))\r
+ {\r
+ if(tmp != RESET)\r
+ {\r
+ /* Update error code */\r
+ hdma->ErrorCode |= HAL_DMA_ERROR_TE;\r
+\r
+ /* Clear the transfer error flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));\r
+ }\r
+ if(tmp1 != RESET)\r
+ {\r
+ /* Update error code */\r
+ hdma->ErrorCode |= HAL_DMA_ERROR_FE;\r
+ \r
+ /* Clear the FIFO error flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));\r
+ }\r
+ if(tmp2 != RESET)\r
+ {\r
+ /* Update error code */\r
+ hdma->ErrorCode |= HAL_DMA_ERROR_DME;\r
+\r
+ /* Clear the Direct Mode error flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));\r
+ }\r
+ /* Change the DMA state */\r
+ hdma->State= HAL_DMA_STATE_ERROR;\r
+ \r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(hdma);\r
+\r
+ return HAL_ERROR;\r
+ } \r
+ /* Check for the Timeout */\r
+ if(Timeout != HAL_MAX_DELAY)\r
+ {\r
+ if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))\r
+ {\r
+ /* Update error code */\r
+ hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;\r
+\r
+ /* Change the DMA state */\r
+ hdma->State = HAL_DMA_STATE_TIMEOUT;\r
+\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(hdma);\r
+ \r
+ return HAL_TIMEOUT;\r
+ }\r
+ }\r
+ }\r
+\r
+ if(CompleteLevel == HAL_DMA_FULL_TRANSFER)\r
+ {\r
+ /* Multi_Buffering mode enabled */\r
+ if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)\r
+ {\r
+ /* Clear the half transfer complete flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
+ /* Clear the transfer complete flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));\r
+\r
+ /* Current memory buffer used is Memory 0 */\r
+ if((hdma->Instance->CR & DMA_SxCR_CT) == 0)\r
+ {\r
+ /* Change DMA peripheral state */\r
+ hdma->State = HAL_DMA_STATE_READY_MEM0;\r
+ }\r
+ /* Current memory buffer used is Memory 1 */\r
+ else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)\r
+ {\r
+ /* Change DMA peripheral state */\r
+ hdma->State = HAL_DMA_STATE_READY_MEM1;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Clear the half transfer complete flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
+ /* Clear the transfer complete flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); \r
+\r
+ /* The selected Streamx EN bit is cleared (DMA is disabled and all transfers\r
+ are complete) */\r
+ hdma->State = HAL_DMA_STATE_READY_MEM0;\r
+ }\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(hdma);\r
+ }\r
+ else\r
+ { \r
+ /* Multi_Buffering mode enabled */\r
+ if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)\r
+ {\r
+ /* Clear the half transfer complete flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
+\r
+ /* Current memory buffer used is Memory 0 */\r
+ if((hdma->Instance->CR & DMA_SxCR_CT) == 0)\r
+ {\r
+ /* Change DMA peripheral state */\r
+ hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;\r
+ }\r
+ /* Current memory buffer used is Memory 1 */\r
+ else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)\r
+ {\r
+ /* Change DMA peripheral state */\r
+ hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Clear the half transfer complete flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
+\r
+ /* Change DMA peripheral state */\r
+ hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;\r
+ }\r
+ }\r
+ return HAL_OK;\r
+}\r
+\r
+/**\r
+ * @brief Handles DMA interrupt request.\r
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains\r
+ * the configuration information for the specified DMA Stream. \r
+ * @retval None\r
+ */\r
+void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)\r
+{\r
+ /* Transfer Error Interrupt management ***************************************/\r
+ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)\r
+ {\r
+ if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)\r
+ {\r
+ /* Disable the transfer error interrupt */\r
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);\r
+\r
+ /* Clear the transfer error flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));\r
+\r
+ /* Update error code */\r
+ hdma->ErrorCode |= HAL_DMA_ERROR_TE;\r
+\r
+ /* Change the DMA state */\r
+ hdma->State = HAL_DMA_STATE_ERROR;\r
+\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(hdma); \r
+\r
+ if(hdma->XferErrorCallback != NULL)\r
+ {\r
+ /* Transfer error callback */\r
+ hdma->XferErrorCallback(hdma);\r
+ }\r
+ }\r
+ }\r
+ /* FIFO Error Interrupt management ******************************************/\r
+ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)) != RESET)\r
+ {\r
+ if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)\r
+ {\r
+ /* Disable the FIFO Error interrupt */\r
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_FE);\r
+\r
+ /* Clear the FIFO error flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));\r
+\r
+ /* Update error code */\r
+ hdma->ErrorCode |= HAL_DMA_ERROR_FE;\r
+\r
+ /* Change the DMA state */\r
+ hdma->State = HAL_DMA_STATE_ERROR;\r
+\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(hdma);\r
+\r
+ if(hdma->XferErrorCallback != NULL)\r
+ {\r
+ /* Transfer error callback */\r
+ hdma->XferErrorCallback(hdma);\r
+ }\r
+ }\r
+ }\r
+ /* Direct Mode Error Interrupt management ***********************************/\r
+ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)) != RESET)\r
+ {\r
+ if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)\r
+ {\r
+ /* Disable the direct mode Error interrupt */\r
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_DME);\r
+\r
+ /* Clear the direct mode error flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));\r
+\r
+ /* Update error code */\r
+ hdma->ErrorCode |= HAL_DMA_ERROR_DME;\r
+\r
+ /* Change the DMA state */\r
+ hdma->State = HAL_DMA_STATE_ERROR;\r
+\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(hdma);\r
+\r
+ if(hdma->XferErrorCallback != NULL)\r
+ {\r
+ /* Transfer error callback */\r
+ hdma->XferErrorCallback(hdma);\r
+ }\r
+ }\r
+ }\r
+ /* Half Transfer Complete Interrupt management ******************************/\r
+ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)\r
+ {\r
+ if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)\r
+ { \r
+ /* Multi_Buffering mode enabled */\r
+ if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)\r
+ {\r
+ /* Clear the half transfer complete flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
+\r
+ /* Current memory buffer used is Memory 0 */\r
+ if((hdma->Instance->CR & DMA_SxCR_CT) == 0)\r
+ {\r
+ /* Change DMA peripheral state */\r
+ hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;\r
+ }\r
+ /* Current memory buffer used is Memory 1 */\r
+ else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)\r
+ {\r
+ /* Change DMA peripheral state */\r
+ hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */\r
+ if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)\r
+ {\r
+ /* Disable the half transfer interrupt */\r
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);\r
+ }\r
+ /* Clear the half transfer complete flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
+\r
+ /* Change DMA peripheral state */\r
+ hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;\r
+ }\r
+\r
+ if(hdma->XferHalfCpltCallback != NULL)\r
+ {\r
+ /* Half transfer callback */\r
+ hdma->XferHalfCpltCallback(hdma);\r
+ }\r
+ }\r
+ }\r
+ /* Transfer Complete Interrupt management ***********************************/\r
+ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)\r
+ {\r
+ if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)\r
+ {\r
+ if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)\r
+ {\r
+ /* Clear the transfer complete flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));\r
+\r
+ /* Current memory buffer used is Memory 1 */\r
+ if((hdma->Instance->CR & DMA_SxCR_CT) == 0)\r
+ {\r
+ if(hdma->XferM1CpltCallback != NULL)\r
+ {\r
+ /* Transfer complete Callback for memory1 */\r
+ hdma->XferM1CpltCallback(hdma);\r
+ }\r
+ }\r
+ /* Current memory buffer used is Memory 0 */\r
+ else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) \r
+ {\r
+ if(hdma->XferCpltCallback != NULL)\r
+ {\r
+ /* Transfer complete Callback for memory0 */\r
+ hdma->XferCpltCallback(hdma);\r
+ }\r
+ }\r
+ }\r
+ /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */\r
+ else\r
+ {\r
+ if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)\r
+ {\r
+ /* Disable the transfer complete interrupt */\r
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);\r
+ }\r
+ /* Clear the transfer complete flag */\r
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));\r
+\r
+ /* Update error code */\r
+ hdma->ErrorCode |= HAL_DMA_ERROR_NONE;\r
+\r
+ /* Change the DMA state */\r
+ hdma->State = HAL_DMA_STATE_READY_MEM0;\r
+\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(hdma); \r
+\r
+ if(hdma->XferCpltCallback != NULL)\r
+ {\r
+ /* Transfer complete callback */\r
+ hdma->XferCpltCallback(hdma);\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/** @addtogroup DMA_Exported_Functions_Group3\r
+ *\r
+@verbatim\r
+ ===============================================================================\r
+ ##### State and Errors functions #####\r
+ ===============================================================================\r
+ [..]\r
+ This subsection provides functions allowing to\r
+ (+) Check the DMA state\r
+ (+) Get error code\r
+\r
+@endverbatim\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Returns the DMA state.\r
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains\r
+ * the configuration information for the specified DMA Stream.\r
+ * @retval HAL state\r
+ */\r
+HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)\r
+{\r
+ return hdma->State;\r
+}\r
+\r
+/**\r
+ * @brief Return the DMA error code\r
+ * @param hdma : pointer to a DMA_HandleTypeDef structure that contains\r
+ * the configuration information for the specified DMA Stream.\r
+ * @retval DMA Error Code\r
+ */\r
+uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)\r
+{\r
+ return hdma->ErrorCode;\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#endif /* HAL_DMA_MODULE_ENABLED */\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r