2 ******************************************************************************
3 * @file stm32f3xx_hal_dma.c
4 * @author MCD Application Team
7 * @brief DMA HAL module driver.
9 * This file provides firmware functions to manage the following
10 * functionalities of the Direct Memory Access (DMA) peripheral:
11 * + Initialization and de-initialization functions
12 * + IO operation functions
13 * + Peripheral State and errors functions
15 ==============================================================================
16 ##### How to use this driver #####
17 ==============================================================================
19 (#) Enable and configure the peripheral to be connected to the DMA Channel
20 (except for internal SRAM / FLASH memories: no initialization is
21 necessary) please refer to Reference manual for connection between peripherals
24 (#) For a given Channel, program the required configuration through the following parameters:
25 Transfer Direction, Source and Destination data formats,
26 Circular, Normal or peripheral flow control mode, Channel Priority level,
27 Source and Destination Increment mode, FIFO mode and its Threshold (if needed),
28 Burst mode for Source and/or Destination (if needed) using HAL_DMA_Init() function.
30 *** Polling mode IO operation ***
31 =================================
33 (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
34 address and destination address and the Length of data to be transferred
35 (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
36 case a fixed Timeout can be configured by User depending from his application.
38 *** Interrupt mode IO operation ***
39 ===================================
41 (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
42 (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
43 (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
44 Source address and destination address and the Length of data to be transferred. In this
45 case the DMA interrupt is configured
46 (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
47 (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
48 add his own function by customization of function pointer XferCpltCallback and
49 XferErrorCallback (i.e a member of DMA handle structure).
51 (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
54 (#) Use HAL_DMA_Abort() function to abort the current transfer
56 -@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
58 *** DMA HAL driver macros list ***
59 =============================================
61 Below the list of most used macros in DMA HAL driver.
63 (+) __HAL_DMA_ENABLE: Enable the specified DMA Channel.
64 (+) __HAL_DMA_DISABLE: Disable the specified DMA Channel.
65 (+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags.
66 (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
67 (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
68 (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
69 (+) __HAL_DMA_IT_STATUS: Check whether the specified DMA Channel interrupt has occurred or not.
72 (@) You can refer to the DMA HAL driver header file for more useful macros
75 ******************************************************************************
78 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
80 * Redistribution and use in source and binary forms, with or without modification,
81 * are permitted provided that the following conditions are met:
82 * 1. Redistributions of source code must retain the above copyright notice,
83 * this list of conditions and the following disclaimer.
84 * 2. Redistributions in binary form must reproduce the above copyright notice,
85 * this list of conditions and the following disclaimer in the documentation
86 * and/or other materials provided with the distribution.
87 * 3. Neither the name of STMicroelectronics nor the names of its contributors
88 * may be used to endorse or promote products derived from this software
89 * without specific prior written permission.
91 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
92 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
95 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
97 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
98 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
99 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
100 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102 ******************************************************************************
105 /* Includes ------------------------------------------------------------------*/
106 #include "stm32f3xx_hal.h"
108 /** @addtogroup STM32F3xx_HAL_Driver
112 /** @defgroup DMA DMA HAL module driver
113 * @brief DMA HAL module driver
117 #ifdef HAL_DMA_MODULE_ENABLED
119 /* Private typedef -----------------------------------------------------------*/
120 /* Private define ------------------------------------------------------------*/
121 /** @defgroup DMA_Private_Defines DMA Private Define
124 #define HAL_TIMEOUT_DMA_ABORT ((uint32_t)1000) /* 1s */
129 /* Private macro -------------------------------------------------------------*/
130 /* Private variables ---------------------------------------------------------*/
131 /* Private function prototypes -----------------------------------------------*/
132 /** @defgroup DMA_Private_Functions DMA Private Functions
135 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
140 /* Exported functions ---------------------------------------------------------*/
141 /** @defgroup DMA_Exported_Functions DMA Exported Functions
145 /** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
146 * @brief Initialization and de-initialization functions
149 ===============================================================================
150 ##### Initialization and de-initialization functions #####
151 ===============================================================================
153 This section provides functions allowing to initialize the DMA Channel source
154 and destination addresses, incrementation and data sizes, transfer direction,
155 circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
157 The HAL_DMA_Init() function follows the DMA configuration procedures as described in
165 * @brief Initializes the DMA according to the specified
166 * parameters in the DMA_InitTypeDef and create the associated handle.
167 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
168 * the configuration information for the specified DMA Channel.
171 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
175 /* Check the DMA handle allocation */
181 /* Check the parameters */
182 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
183 assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
184 assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
185 assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
186 assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
187 assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
188 assert_param(IS_DMA_MODE(hdma->Init.Mode));
189 assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
191 /* Change DMA peripheral state */
192 hdma->State = HAL_DMA_STATE_BUSY;
194 /* Get the CR register value */
195 tmp = hdma->Instance->CCR;
197 /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR bits */
198 tmp &= ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \
199 DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \
202 /* Prepare the DMA Channel configuration */
203 tmp |= hdma->Init.Direction |
204 hdma->Init.PeriphInc | hdma->Init.MemInc |
205 hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
206 hdma->Init.Mode | hdma->Init.Priority;
208 /* Write to DMA Channel CR register */
209 hdma->Instance->CCR = tmp;
211 /* Initialise the error code */
212 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
214 /* Initialize the DMA state*/
215 hdma->State = HAL_DMA_STATE_READY;
221 * @brief DeInitializes the DMA peripheral
222 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
223 * the configuration information for the specified DMA Channel.
226 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
228 /* Check the DMA handle allocation */
234 /* Check the parameters */
235 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
237 /* Check the DMA peripheral state */
238 if(hdma->State == HAL_DMA_STATE_BUSY)
243 /* Disable the selected DMA Channelx */
244 __HAL_DMA_DISABLE(hdma);
246 /* Reset DMA Channel control register */
247 hdma->Instance->CCR = 0;
249 /* Reset DMA Channel Number of Data to Transfer register */
250 hdma->Instance->CNDTR = 0;
252 /* Reset DMA Channel peripheral address register */
253 hdma->Instance->CPAR = 0;
255 /* Reset DMA Channel memory address register */
256 hdma->Instance->CMAR = 0;
258 /* Clear all flags */
259 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
260 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
261 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
263 /* Initialise the error code */
264 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
266 /* Initialize the DMA state */
267 hdma->State = HAL_DMA_STATE_RESET;
279 /** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
280 * @brief I/O operation functions
283 ===============================================================================
284 ##### IO operation functions #####
285 ===============================================================================
286 [..] This section provides functions allowing to:
287 (+) Configure the source, destination address and data length and Start DMA transfer
288 (+) Configure the source, destination address and data length and
289 Start DMA transfer with interrupt
290 (+) Abort DMA transfer
291 (+) Poll for transfer complete
292 (+) Handle DMA interrupt request
299 * @brief Starts the DMA Transfer.
300 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
301 * the configuration information for the specified DMA Channel.
302 * @param SrcAddress: The source memory Buffer address
303 * @param DstAddress: The destination memory Buffer address
304 * @param DataLength: The length of data to be transferred from source to destination
307 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
312 /* Change DMA peripheral state */
313 hdma->State = HAL_DMA_STATE_BUSY;
315 /* Check the parameters */
316 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
318 /* Disable the peripheral */
319 __HAL_DMA_DISABLE(hdma);
321 /* Configure the source, destination address and the data length */
322 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
324 /* Enable the Peripheral */
325 __HAL_DMA_ENABLE(hdma);
331 * @brief Start the DMA Transfer with interrupt enabled.
332 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
333 * the configuration information for the specified DMA Channel.
334 * @param SrcAddress: The source memory Buffer address
335 * @param DstAddress: The destination memory Buffer address
336 * @param DataLength: The length of data to be transferred from source to destination
339 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
344 /* Change DMA peripheral state */
345 hdma->State = HAL_DMA_STATE_BUSY;
347 /* Check the parameters */
348 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
350 /* Disable the peripheral */
351 __HAL_DMA_DISABLE(hdma);
353 /* Configure the source, destination address and the data length */
354 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
356 /* Enable the transfer complete interrupt */
357 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC);
359 /* Enable the Half transfer complete interrupt */
360 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);
362 /* Enable the transfer Error interrupt */
363 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE);
365 /* Enable the Peripheral */
366 __HAL_DMA_ENABLE(hdma);
372 * @brief Aborts the DMA Transfer.
373 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
374 * the configuration information for the specified DMA Channel.
376 * @note After disabling a DMA Channel, a check for wait until the DMA Channel is
377 * effectively disabled is added. If a Channel is disabled
378 * while a data transfer is ongoing, the current data will be transferred
379 * and the Channel will be effectively disabled only after the transfer of
380 * this single data is finished.
383 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
385 uint32_t tickstart = 0x00;
387 /* Disable the channel */
388 __HAL_DMA_DISABLE(hdma);
391 tickstart = HAL_GetTick();
393 /* Check if the DMA Channel is effectively disabled */
394 while((hdma->Instance->CCR & DMA_CCR_EN) != 0)
396 /* Check for the Timeout */
397 if((HAL_GetTick()-tickstart) > HAL_TIMEOUT_DMA_ABORT)
399 /* Update error code */
400 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
402 /* Change the DMA state */
403 hdma->State = HAL_DMA_STATE_TIMEOUT;
405 /* Process Unlocked */
411 /* Change the DMA state*/
412 hdma->State = HAL_DMA_STATE_READY;
414 /* Process Unlocked */
421 * @brief Polling for transfer complete.
422 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
423 * the configuration information for the specified DMA Channel.
424 * @param CompleteLevel: Specifies the DMA level complete.
425 * @param Timeout: Timeout duration.
428 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
431 uint32_t tickstart = 0x00;
433 /* Get the level transfer complete flag */
434 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
436 /* Transfer Complete flag */
437 temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
441 /* Half Transfer Complete flag */
442 temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
446 tickstart = HAL_GetTick();
448 while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
450 if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET))
452 /* Clear the transfer error flags */
453 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
455 /* Change the DMA state */
456 hdma->State= HAL_DMA_STATE_ERROR;
458 /* Process Unlocked */
463 /* Check for the Timeout */
464 if(Timeout != HAL_MAX_DELAY)
466 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
468 /* Update error code */
469 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
471 /* Change the DMA state */
472 hdma->State = HAL_DMA_STATE_TIMEOUT;
474 /* Process Unlocked */
482 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
484 /* Clear the transfer complete flag */
485 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
487 /* The selected Channelx EN bit is cleared (DMA is disabled and
488 all transfers are complete) */
489 hdma->State = HAL_DMA_STATE_READY;
494 /* Clear the half transfer complete flag */
495 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
497 hdma->State = HAL_DMA_STATE_READY_HALF;
500 /* Process unlocked */
507 * @brief Handles DMA interrupt request.
508 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
509 * the configuration information for the specified DMA Channel.
512 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
514 /* Transfer Error Interrupt management ***************************************/
515 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)
517 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
519 /* Disable the transfer error interrupt */
520 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);
522 /* Clear the transfer error flag */
523 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
525 /* Update error code */
526 hdma->ErrorCode |= HAL_DMA_ERROR_TE;
528 /* Change the DMA state */
529 hdma->State = HAL_DMA_STATE_ERROR;
531 /* Process Unlocked */
534 if (hdma->XferErrorCallback != HAL_NULL)
536 /* Transfer error callback */
537 hdma->XferErrorCallback(hdma);
542 /* Half Transfer Complete Interrupt management ******************************/
543 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
545 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
547 /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
548 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
550 /* Disable the half transfer interrupt */
551 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
553 /* Clear the half transfer complete flag */
554 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
556 /* Change DMA peripheral state */
557 hdma->State = HAL_DMA_STATE_READY_HALF;
559 if(hdma->XferHalfCpltCallback != HAL_NULL)
561 /* Half transfer callback */
562 hdma->XferHalfCpltCallback(hdma);
567 /* Transfer Complete Interrupt management ***********************************/
568 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)
570 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
572 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
574 /* Disable the transfer complete interrupt */
575 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);
577 /* Clear the transfer complete flag */
578 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
580 /* Update error code */
581 hdma->ErrorCode |= HAL_DMA_ERROR_NONE;
583 /* Change the DMA state */
584 hdma->State = HAL_DMA_STATE_READY;
586 /* Process Unlocked */
589 if(hdma->XferCpltCallback != HAL_NULL)
591 /* Transfer complete callback */
592 hdma->XferCpltCallback(hdma);
602 /** @defgroup DMA_Exported_Functions_Group3 Peripheral State functions
603 * @brief Peripheral State functions
606 ===============================================================================
607 ##### State and Errors functions #####
608 ===============================================================================
610 This subsection provides functions allowing to
611 (+) Check the DMA state
619 * @brief Returns the DMA state.
620 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
621 * the configuration information for the specified DMA Channel.
624 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
630 * @brief Return the DMA error code
631 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
632 * the configuration information for the specified DMA Channel.
633 * @retval DMA Error Code
635 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
637 return hdma->ErrorCode;
648 /** @addtogroup DMA_Private_Functions DMA Private Functions
653 * @brief Sets the DMA Transfer parameter.
654 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
655 * the configuration information for the specified DMA Channel.
656 * @param SrcAddress: The source memory Buffer address
657 * @param DstAddress: The destination memory Buffer address
658 * @param DataLength: The length of data to be transferred from source to destination
661 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
663 /* Configure DMA Channel data length */
664 hdma->Instance->CNDTR = DataLength;
666 /* Peripheral to Memory */
667 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
669 /* Configure DMA Channel destination address */
670 hdma->Instance->CPAR = DstAddress;
672 /* Configure DMA Channel source address */
673 hdma->Instance->CMAR = SrcAddress;
675 /* Memory to Peripheral */
678 /* Configure DMA Channel source address */
679 hdma->Instance->CPAR = SrcAddress;
681 /* Configure DMA Channel destination address */
682 hdma->Instance->CMAR = DstAddress;
690 #endif /* HAL_DMA_MODULE_ENABLED */
699 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/