2 ******************************************************************************
3 * @file stm32f4xx_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 Stream
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 Stream, program the required configuration through the following parameters:
25 Transfer Direction, Source and Destination data formats,
26 Circular, Normal or peripheral flow control mode, Stream 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 -@- The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is
59 possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set
60 Half-Word data size for the peripheral to access its data register and set Word data size
61 for the Memory to gain in access time. Each two half words will be packed and written in
62 a single access to a Word in the Memory).
64 -@- When FIFO is disabled, it is not allowed to configure different Data Sizes for Source
65 and Destination. In this case the Peripheral Data Size will be applied to both Source
68 *** DMA HAL driver macros list ***
69 =============================================
71 Below the list of most used macros in DMA HAL driver.
73 (+) __HAL_DMA_ENABLE: Enable the specified DMA Stream.
74 (+) __HAL_DMA_DISABLE: Disable the specified DMA Stream.
75 (+) __HAL_DMA_GET_FS: Return the current DMA Stream FIFO filled level.
76 (+) __HAL_DMA_GET_FLAG: Get the DMA Stream pending flags.
77 (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Stream pending flags.
78 (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Stream interrupts.
79 (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Stream interrupts.
80 (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Stream interrupt has occurred or not.
83 (@) You can refer to the DMA HAL driver header file for more useful macros
86 ******************************************************************************
89 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
91 * Redistribution and use in source and binary forms, with or without modification,
92 * are permitted provided that the following conditions are met:
93 * 1. Redistributions of source code must retain the above copyright notice,
94 * this list of conditions and the following disclaimer.
95 * 2. Redistributions in binary form must reproduce the above copyright notice,
96 * this list of conditions and the following disclaimer in the documentation
97 * and/or other materials provided with the distribution.
98 * 3. Neither the name of STMicroelectronics nor the names of its contributors
99 * may be used to endorse or promote products derived from this software
100 * without specific prior written permission.
102 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
103 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
104 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
106 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
107 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
108 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
109 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
110 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
111 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
113 ******************************************************************************
116 /* Includes ------------------------------------------------------------------*/
117 #include "stm32f4xx_hal.h"
119 /** @addtogroup STM32F4xx_HAL_Driver
124 * @brief DMA HAL module driver
128 #ifdef HAL_DMA_MODULE_ENABLED
130 /* Private typedef -----------------------------------------------------------*/
131 /* Private define ------------------------------------------------------------*/
132 #define HAL_TIMEOUT_DMA_ABORT ((uint32_t)1000) /* 1s */
133 /* Private macro -------------------------------------------------------------*/
134 /* Private variables ---------------------------------------------------------*/
135 /* Private function prototypes -----------------------------------------------*/
136 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
138 /* Private functions ---------------------------------------------------------*/
140 /** @defgroup DMA_Private_Functions
144 /** @defgroup DMA_Group1 Initialization and de-initialization functions
145 * @brief Initialization and de-initialization functions
148 ===============================================================================
149 ##### Initialization and de-initialization functions #####
150 ===============================================================================
152 This section provides functions allowing to initialize the DMA Stream source
153 and destination addresses, incrementation and data sizes, transfer direction,
154 circular/normal mode selection, memory-to-memory mode selection and Stream priority value.
156 The HAL_DMA_Init() function follows the DMA configuration procedures as described in
164 * @brief Initializes the DMA according to the specified
165 * parameters in the DMA_InitTypeDef and create the associated handle.
166 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
167 * the configuration information for the specified DMA Stream.
170 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
174 /* Check the DMA peripheral state */
180 /* Check the parameters */
181 assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
182 assert_param(IS_DMA_CHANNEL(hdma->Init.Channel));
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));
190 assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode));
191 /* Check the memory burst, peripheral burst and FIFO threshold parameters only
192 when FIFO mode is enabled */
193 if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE)
195 assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold));
196 assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst));
197 assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst));
200 /* Change DMA peripheral state */
201 hdma->State = HAL_DMA_STATE_BUSY;
203 /* Get the CR register value */
204 tmp = hdma->Instance->CR;
206 /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR and CT bits */
207 tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
208 DMA_SxCR_PL | DMA_SxCR_MSIZE | DMA_SxCR_PSIZE | \
209 DMA_SxCR_MINC | DMA_SxCR_PINC | DMA_SxCR_CIRC | \
210 DMA_SxCR_DIR | DMA_SxCR_CT ));
212 /* Prepare the DMA Stream configuration */
213 tmp |= hdma->Init.Channel | hdma->Init.Direction |
214 hdma->Init.PeriphInc | hdma->Init.MemInc |
215 hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
216 hdma->Init.Mode | hdma->Init.Priority;
218 /* the Memory burst and peripheral burst are not used when the FIFO is disabled */
219 if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
221 /* Get memory burst and peripheral burst */
222 tmp |= hdma->Init.MemBurst | hdma->Init.PeriphBurst;
225 /* Write to DMA Stream CR register */
226 hdma->Instance->CR = tmp;
228 /* Get the FCR register value */
229 tmp = hdma->Instance->FCR;
231 /* Clear Direct mode and FIFO threshold bits */
232 tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
234 /* Prepare the DMA Stream FIFO configuration */
235 tmp |= hdma->Init.FIFOMode;
237 /* the FIFO threshold is not used when the FIFO mode is disabled */
238 if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
240 /* Get the FIFO threshold */
241 tmp |= hdma->Init.FIFOThreshold;
244 /* Write to DMA Stream FCR */
245 hdma->Instance->FCR = tmp;
247 /* Initialise the error code */
248 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
250 /* Initialize the DMA state */
251 hdma->State = HAL_DMA_STATE_READY;
257 * @brief DeInitializes the DMA peripheral
258 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
259 * the configuration information for the specified DMA Stream.
262 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
264 /* Check the DMA peripheral state */
270 /* Check the DMA peripheral state */
271 if(hdma->State == HAL_DMA_STATE_BUSY)
276 /* Disable the selected DMA Streamx */
277 __HAL_DMA_DISABLE(hdma);
279 /* Reset DMA Streamx control register */
280 hdma->Instance->CR = 0;
282 /* Reset DMA Streamx number of data to transfer register */
283 hdma->Instance->NDTR = 0;
285 /* Reset DMA Streamx peripheral address register */
286 hdma->Instance->PAR = 0;
288 /* Reset DMA Streamx memory 0 address register */
289 hdma->Instance->M0AR = 0;
291 /* Reset DMA Streamx memory 1 address register */
292 hdma->Instance->M1AR = 0;
294 /* Reset DMA Streamx FIFO control register */
295 hdma->Instance->FCR = (uint32_t)0x00000021;
297 /* Clear all flags */
298 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
299 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
300 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
301 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
302 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
304 /* Initialise the error code */
305 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
307 /* Initialize the DMA state */
308 hdma->State = HAL_DMA_STATE_RESET;
320 /** @defgroup DMA_Group2 I/O operation functions
321 * @brief I/O operation functions
324 ===============================================================================
325 ##### IO operation functions #####
326 ===============================================================================
327 [..] This section provides functions allowing to:
328 (+) Configure the source, destination address and data length and Start DMA transfer
329 (+) Configure the source, destination address and data length and
330 Start DMA transfer with interrupt
331 (+) Abort DMA transfer
332 (+) Poll for transfer complete
333 (+) Handle DMA interrupt request
340 * @brief Starts the DMA Transfer.
341 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
342 * the configuration information for the specified DMA Stream.
343 * @param SrcAddress: The source memory Buffer address
344 * @param DstAddress: The destination memory Buffer address
345 * @param DataLength: The length of data to be transferred from source to destination
348 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
353 /* Change DMA peripheral state */
354 hdma->State = HAL_DMA_STATE_BUSY;
356 /* Check the parameters */
357 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
359 /* Disable the peripheral */
360 __HAL_DMA_DISABLE(hdma);
362 /* Configure the source, destination address and the data length */
363 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
365 /* Enable the Peripheral */
366 __HAL_DMA_ENABLE(hdma);
372 * @brief Start the DMA Transfer with interrupt enabled.
373 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
374 * the configuration information for the specified DMA Stream.
375 * @param SrcAddress: The source memory Buffer address
376 * @param DstAddress: The destination memory Buffer address
377 * @param DataLength: The length of data to be transferred from source to destination
380 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
385 /* Change DMA peripheral state */
386 hdma->State = HAL_DMA_STATE_BUSY;
388 /* Check the parameters */
389 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
391 /* Disable the peripheral */
392 __HAL_DMA_DISABLE(hdma);
394 /* Configure the source, destination address and the data length */
395 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
397 /* Enable the transfer complete interrupt */
398 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC);
400 /* Enable the Half transfer complete interrupt */
401 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);
403 /* Enable the transfer Error interrupt */
404 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE);
406 /* Enable the FIFO Error interrupt */
407 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_FE);
409 /* Enable the direct mode Error interrupt */
410 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_DME);
412 /* Enable the Peripheral */
413 __HAL_DMA_ENABLE(hdma);
419 * @brief Aborts the DMA Transfer.
420 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
421 * the configuration information for the specified DMA Stream.
423 * @note After disabling a DMA Stream, a check for wait until the DMA Stream is
424 * effectively disabled is added. If a Stream is disabled
425 * while a data transfer is ongoing, the current data will be transferred
426 * and the Stream will be effectively disabled only after the transfer of
427 * this single data is finished.
430 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
432 uint32_t tickstart = 0;
434 /* Disable the stream */
435 __HAL_DMA_DISABLE(hdma);
438 tickstart = HAL_GetTick();
440 /* Check if the DMA Stream is effectively disabled */
441 while((hdma->Instance->CR & DMA_SxCR_EN) != 0)
443 /* Check for the Timeout */
444 if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
446 /* Update error code */
447 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
449 /* Process Unlocked */
452 /* Change the DMA state */
453 hdma->State = HAL_DMA_STATE_TIMEOUT;
458 /* Process Unlocked */
461 /* Change the DMA state*/
462 hdma->State = HAL_DMA_STATE_READY;
468 * @brief Polling for transfer complete.
469 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
470 * the configuration information for the specified DMA Stream.
471 * @param CompleteLevel: Specifies the DMA level complete.
472 * @param Timeout: Timeout duration.
475 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
477 uint32_t temp, tmp, tmp1, tmp2;
478 uint32_t tickstart = 0;
480 /* Get the level transfer complete flag */
481 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
483 /* Transfer Complete flag */
484 temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
488 /* Half Transfer Complete flag */
489 temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
493 tickstart = HAL_GetTick();
495 while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
497 tmp = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
498 tmp1 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
499 tmp2 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
500 if((tmp != RESET) || (tmp1 != RESET) || (tmp2 != RESET))
504 /* Update error code */
505 hdma->ErrorCode |= HAL_DMA_ERROR_TE;
507 /* Clear the transfer error flag */
508 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
512 /* Update error code */
513 hdma->ErrorCode |= HAL_DMA_ERROR_FE;
515 /* Clear the FIFO error flag */
516 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
520 /* Update error code */
521 hdma->ErrorCode |= HAL_DMA_ERROR_DME;
523 /* Clear the Direct Mode error flag */
524 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
526 /* Change the DMA state */
527 hdma->State= HAL_DMA_STATE_ERROR;
529 /* Process Unlocked */
534 /* Check for the Timeout */
535 if(Timeout != HAL_MAX_DELAY)
537 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
539 /* Update error code */
540 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
542 /* Change the DMA state */
543 hdma->State = HAL_DMA_STATE_TIMEOUT;
545 /* Process Unlocked */
553 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
555 /* Multi_Buffering mode enabled */
556 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
558 /* Clear the half transfer complete flag */
559 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
560 /* Clear the transfer complete flag */
561 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
563 /* Current memory buffer used is Memory 0 */
564 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
566 /* Change DMA peripheral state */
567 hdma->State = HAL_DMA_STATE_READY_MEM0;
569 /* Current memory buffer used is Memory 1 */
570 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
572 /* Change DMA peripheral state */
573 hdma->State = HAL_DMA_STATE_READY_MEM1;
578 /* Clear the half transfer complete flag */
579 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
580 /* Clear the transfer complete flag */
581 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
583 /* The selected Streamx EN bit is cleared (DMA is disabled and all transfers
585 hdma->State = HAL_DMA_STATE_READY_MEM0;
587 /* Process Unlocked */
592 /* Multi_Buffering mode enabled */
593 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
595 /* Clear the half transfer complete flag */
596 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
598 /* Current memory buffer used is Memory 0 */
599 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
601 /* Change DMA peripheral state */
602 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
604 /* Current memory buffer used is Memory 1 */
605 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
607 /* Change DMA peripheral state */
608 hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;
613 /* Clear the half transfer complete flag */
614 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
616 /* Change DMA peripheral state */
617 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
624 * @brief Handles DMA interrupt request.
625 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
626 * the configuration information for the specified DMA Stream.
629 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
631 /* Transfer Error Interrupt management ***************************************/
632 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)
634 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
636 /* Disable the transfer error interrupt */
637 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);
639 /* Clear the transfer error flag */
640 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
642 /* Update error code */
643 hdma->ErrorCode |= HAL_DMA_ERROR_TE;
645 /* Change the DMA state */
646 hdma->State = HAL_DMA_STATE_ERROR;
648 /* Process Unlocked */
651 if(hdma->XferErrorCallback != HAL_NULL)
653 /* Transfer error callback */
654 hdma->XferErrorCallback(hdma);
658 /* FIFO Error Interrupt management ******************************************/
659 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)) != RESET)
661 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
663 /* Disable the FIFO Error interrupt */
664 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_FE);
666 /* Clear the FIFO error flag */
667 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
669 /* Update error code */
670 hdma->ErrorCode |= HAL_DMA_ERROR_FE;
672 /* Change the DMA state */
673 hdma->State = HAL_DMA_STATE_ERROR;
675 /* Process Unlocked */
678 if(hdma->XferErrorCallback != HAL_NULL)
680 /* Transfer error callback */
681 hdma->XferErrorCallback(hdma);
685 /* Direct Mode Error Interrupt management ***********************************/
686 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)) != RESET)
688 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
690 /* Disable the direct mode Error interrupt */
691 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_DME);
693 /* Clear the direct mode error flag */
694 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
696 /* Update error code */
697 hdma->ErrorCode |= HAL_DMA_ERROR_DME;
699 /* Change the DMA state */
700 hdma->State = HAL_DMA_STATE_ERROR;
702 /* Process Unlocked */
705 if(hdma->XferErrorCallback != HAL_NULL)
707 /* Transfer error callback */
708 hdma->XferErrorCallback(hdma);
712 /* Half Transfer Complete Interrupt management ******************************/
713 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
715 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
717 /* Multi_Buffering mode enabled */
718 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
720 /* Clear the half transfer complete flag */
721 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
723 /* Current memory buffer used is Memory 0 */
724 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
726 /* Change DMA peripheral state */
727 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
729 /* Current memory buffer used is Memory 1 */
730 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
732 /* Change DMA peripheral state */
733 hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;
738 /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
739 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
741 /* Disable the half transfer interrupt */
742 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
744 /* Clear the half transfer complete flag */
745 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
747 /* Change DMA peripheral state */
748 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
751 if(hdma->XferHalfCpltCallback != HAL_NULL)
753 /* Half transfer callback */
754 hdma->XferHalfCpltCallback(hdma);
758 /* Transfer Complete Interrupt management ***********************************/
759 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)
761 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
763 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
765 /* Clear the transfer complete flag */
766 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
768 /* Current memory buffer used is Memory 1 */
769 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
771 if(hdma->XferM1CpltCallback != HAL_NULL)
773 /* Transfer complete Callback for memory1 */
774 hdma->XferM1CpltCallback(hdma);
777 /* Current memory buffer used is Memory 0 */
778 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
780 if(hdma->XferCpltCallback != HAL_NULL)
782 /* Transfer complete Callback for memory0 */
783 hdma->XferCpltCallback(hdma);
787 /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
790 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
792 /* Disable the transfer complete interrupt */
793 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);
795 /* Clear the transfer complete flag */
796 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
798 /* Update error code */
799 hdma->ErrorCode |= HAL_DMA_ERROR_NONE;
801 /* Change the DMA state */
802 hdma->State = HAL_DMA_STATE_READY_MEM0;
804 /* Process Unlocked */
807 if(hdma->XferCpltCallback != HAL_NULL)
809 /* Transfer complete callback */
810 hdma->XferCpltCallback(hdma);
821 /** @defgroup DMA_Group3 Peripheral State functions
822 * @brief Peripheral State functions
825 ===============================================================================
826 ##### State and Errors functions #####
827 ===============================================================================
829 This subsection provides functions allowing to
830 (+) Check the DMA state
838 * @brief Returns the DMA state.
839 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
840 * the configuration information for the specified DMA Stream.
843 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
849 * @brief Return the DMA error code
850 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
851 * the configuration information for the specified DMA Stream.
852 * @retval DMA Error Code
854 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
856 return hdma->ErrorCode;
864 * @brief Sets the DMA Transfer parameter.
865 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
866 * the configuration information for the specified DMA Stream.
867 * @param SrcAddress: The source memory Buffer address
868 * @param DstAddress: The destination memory Buffer address
869 * @param DataLength: The length of data to be transferred from source to destination
872 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
874 /* Configure DMA Stream data length */
875 hdma->Instance->NDTR = DataLength;
877 /* Peripheral to Memory */
878 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
880 /* Configure DMA Stream destination address */
881 hdma->Instance->PAR = DstAddress;
883 /* Configure DMA Stream source address */
884 hdma->Instance->M0AR = SrcAddress;
886 /* Memory to Peripheral */
889 /* Configure DMA Stream source address */
890 hdma->Instance->PAR = SrcAddress;
892 /* Configure DMA Stream destination address */
893 hdma->Instance->M0AR = DstAddress;
901 #endif /* HAL_DMA_MODULE_ENABLED */
910 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/