2 ******************************************************************************
\r
3 * @file stm32f7xx_hal_dma.c
\r
4 * @author MCD Application Team
\r
7 * @brief DMA HAL module driver.
\r
9 * This file provides firmware functions to manage the following
\r
10 * functionalities of the Direct Memory Access (DMA) peripheral:
\r
11 * + Initialization and de-initialization functions
\r
12 * + IO operation functions
\r
13 * + Peripheral State and errors functions
\r
15 ==============================================================================
\r
16 ##### How to use this driver #####
\r
17 ==============================================================================
\r
19 (#) Enable and configure the peripheral to be connected to the DMA Stream
\r
20 (except for internal SRAM/FLASH memories: no initialization is
\r
21 necessary) please refer to Reference manual for connection between peripherals
\r
24 (#) For a given Stream, program the required configuration through the following parameters:
\r
25 Transfer Direction, Source and Destination data formats,
\r
26 Circular, Normal or peripheral flow control mode, Stream Priority level,
\r
27 Source and Destination Increment mode, FIFO mode and its Threshold (if needed),
\r
28 Burst mode for Source and/or Destination (if needed) using HAL_DMA_Init() function.
\r
30 *** Polling mode IO operation ***
\r
31 =================================
\r
33 (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
\r
34 address and destination address and the Length of data to be transferred
\r
35 (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
\r
36 case a fixed Timeout can be configured by User depending from his application.
\r
38 *** Interrupt mode IO operation ***
\r
39 ===================================
\r
41 (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
\r
42 (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
\r
43 (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
\r
44 Source address and destination address and the Length of data to be transferred. In this
\r
45 case the DMA interrupt is configured
\r
46 (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
\r
47 (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
\r
48 add his own function by customization of function pointer XferCpltCallback and
\r
49 XferErrorCallback (i.e a member of DMA handle structure).
\r
51 (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
\r
54 (#) Use HAL_DMA_Abort() function to abort the current transfer
\r
56 -@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
\r
58 -@- The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is
\r
59 possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set
\r
60 Half-Word data size for the peripheral to access its data register and set Word data size
\r
61 for the Memory to gain in access time. Each two half words will be packed and written in
\r
62 a single access to a Word in the Memory).
\r
64 -@- When FIFO is disabled, it is not allowed to configure different Data Sizes for Source
\r
65 and Destination. In this case the Peripheral Data Size will be applied to both Source
\r
68 *** DMA HAL driver macros list ***
\r
69 =============================================
\r
71 Below the list of most used macros in DMA HAL driver.
\r
73 (+) __HAL_DMA_ENABLE: Enable the specified DMA Stream.
\r
74 (+) __HAL_DMA_DISABLE: Disable the specified DMA Stream.
\r
75 (+) __HAL_DMA_GET_FS: Return the current DMA Stream FIFO filled level.
\r
76 (+) __HAL_DMA_GET_FLAG: Get the DMA Stream pending flags.
\r
77 (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Stream pending flags.
\r
78 (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Stream interrupts.
\r
79 (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Stream interrupts.
\r
80 (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Stream interrupt has occurred or not.
\r
83 (@) You can refer to the DMA HAL driver header file for more useful macros
\r
86 ******************************************************************************
\r
89 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
\r
91 * Redistribution and use in source and binary forms, with or without modification,
\r
92 * are permitted provided that the following conditions are met:
\r
93 * 1. Redistributions of source code must retain the above copyright notice,
\r
94 * this list of conditions and the following disclaimer.
\r
95 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
96 * this list of conditions and the following disclaimer in the documentation
\r
97 * and/or other materials provided with the distribution.
\r
98 * 3. Neither the name of STMicroelectronics nor the names of its contributors
\r
99 * may be used to endorse or promote products derived from this software
\r
100 * without specific prior written permission.
\r
102 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
\r
103 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
104 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
105 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
\r
106 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
107 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
\r
108 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
\r
109 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
\r
110 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
\r
111 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
113 ******************************************************************************
\r
116 /* Includes ------------------------------------------------------------------*/
\r
117 #include "stm32f7xx_hal.h"
\r
119 /** @addtogroup STM32F7xx_HAL_Driver
\r
123 /** @defgroup DMA DMA
\r
124 * @brief DMA HAL module driver
\r
128 #ifdef HAL_DMA_MODULE_ENABLED
\r
130 /* Private types -------------------------------------------------------------*/
\r
131 /* Private variables ---------------------------------------------------------*/
\r
132 /* Private constants ---------------------------------------------------------*/
\r
133 /** @addtogroup DMA_Private_Constants
\r
136 #define HAL_TIMEOUT_DMA_ABORT ((uint32_t)1000) /* 1s */
\r
140 /* Private macros ------------------------------------------------------------*/
\r
141 /* Private functions ---------------------------------------------------------*/
\r
142 /** @addtogroup DMA_Private_Functions
\r
145 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
\r
147 * @brief Sets the DMA Transfer parameter.
\r
148 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
\r
149 * the configuration information for the specified DMA Stream.
\r
150 * @param SrcAddress: The source memory Buffer address
\r
151 * @param DstAddress: The destination memory Buffer address
\r
152 * @param DataLength: The length of data to be transferred from source to destination
\r
153 * @retval HAL status
\r
155 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
\r
157 /* Clear DBM bit */
\r
158 hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);
\r
160 /* Configure DMA Stream data length */
\r
161 hdma->Instance->NDTR = DataLength;
\r
163 /* Peripheral to Memory */
\r
164 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
\r
166 /* Configure DMA Stream destination address */
\r
167 hdma->Instance->PAR = DstAddress;
\r
169 /* Configure DMA Stream source address */
\r
170 hdma->Instance->M0AR = SrcAddress;
\r
172 /* Memory to Peripheral */
\r
175 /* Configure DMA Stream source address */
\r
176 hdma->Instance->PAR = SrcAddress;
\r
178 /* Configure DMA Stream destination address */
\r
179 hdma->Instance->M0AR = DstAddress;
\r
187 /* Exported functions ---------------------------------------------------------*/
\r
188 /** @addtogroup DMA_Exported_Functions
\r
192 /** @addtogroup DMA_Exported_Functions_Group1
\r
195 ===============================================================================
\r
196 ##### Initialization and de-initialization functions #####
\r
197 ===============================================================================
\r
199 This section provides functions allowing to initialize the DMA Stream source
\r
200 and destination addresses, incrementation and data sizes, transfer direction,
\r
201 circular/normal mode selection, memory-to-memory mode selection and Stream priority value.
\r
203 The HAL_DMA_Init() function follows the DMA configuration procedures as described in
\r
211 * @brief Initializes the DMA according to the specified
\r
212 * parameters in the DMA_InitTypeDef and create the associated handle.
\r
213 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
\r
214 * the configuration information for the specified DMA Stream.
\r
215 * @retval HAL status
\r
217 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
\r
221 /* Check the DMA peripheral state */
\r
227 /* Check the parameters */
\r
228 assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
\r
229 assert_param(IS_DMA_CHANNEL(hdma->Init.Channel));
\r
230 assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
\r
231 assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
\r
232 assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
\r
233 assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
\r
234 assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
\r
235 assert_param(IS_DMA_MODE(hdma->Init.Mode));
\r
236 assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
\r
237 assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode));
\r
238 /* Check the memory burst, peripheral burst and FIFO threshold parameters only
\r
239 when FIFO mode is enabled */
\r
240 if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE)
\r
242 assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold));
\r
243 assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst));
\r
244 assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst));
\r
247 /* Change DMA peripheral state */
\r
248 hdma->State = HAL_DMA_STATE_BUSY;
\r
250 /* Get the CR register value */
\r
251 tmp = hdma->Instance->CR;
\r
253 /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */
\r
254 tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
\r
255 DMA_SxCR_PL | DMA_SxCR_MSIZE | DMA_SxCR_PSIZE | \
\r
256 DMA_SxCR_MINC | DMA_SxCR_PINC | DMA_SxCR_CIRC | \
\r
257 DMA_SxCR_DIR | DMA_SxCR_CT | DMA_SxCR_DBM));
\r
259 /* Prepare the DMA Stream configuration */
\r
260 tmp |= hdma->Init.Channel | hdma->Init.Direction |
\r
261 hdma->Init.PeriphInc | hdma->Init.MemInc |
\r
262 hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
\r
263 hdma->Init.Mode | hdma->Init.Priority;
\r
265 /* the Memory burst and peripheral burst are not used when the FIFO is disabled */
\r
266 if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
\r
268 /* Get memory burst and peripheral burst */
\r
269 tmp |= hdma->Init.MemBurst | hdma->Init.PeriphBurst;
\r
272 /* Write to DMA Stream CR register */
\r
273 hdma->Instance->CR = tmp;
\r
275 /* Get the FCR register value */
\r
276 tmp = hdma->Instance->FCR;
\r
278 /* Clear Direct mode and FIFO threshold bits */
\r
279 tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
\r
281 /* Prepare the DMA Stream FIFO configuration */
\r
282 tmp |= hdma->Init.FIFOMode;
\r
284 /* the FIFO threshold is not used when the FIFO mode is disabled */
\r
285 if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
\r
287 /* Get the FIFO threshold */
\r
288 tmp |= hdma->Init.FIFOThreshold;
\r
291 /* Write to DMA Stream FCR */
\r
292 hdma->Instance->FCR = tmp;
\r
294 /* Initialize the error code */
\r
295 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
\r
297 /* Initialize the DMA state */
\r
298 hdma->State = HAL_DMA_STATE_READY;
\r
304 * @brief DeInitializes the DMA peripheral
\r
305 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
\r
306 * the configuration information for the specified DMA Stream.
\r
307 * @retval HAL status
\r
309 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
\r
311 /* Check the DMA peripheral state */
\r
317 /* Check the DMA peripheral state */
\r
318 if(hdma->State == HAL_DMA_STATE_BUSY)
\r
323 /* Disable the selected DMA Streamx */
\r
324 __HAL_DMA_DISABLE(hdma);
\r
326 /* Reset DMA Streamx control register */
\r
327 hdma->Instance->CR = 0;
\r
329 /* Reset DMA Streamx number of data to transfer register */
\r
330 hdma->Instance->NDTR = 0;
\r
332 /* Reset DMA Streamx peripheral address register */
\r
333 hdma->Instance->PAR = 0;
\r
335 /* Reset DMA Streamx memory 0 address register */
\r
336 hdma->Instance->M0AR = 0;
\r
338 /* Reset DMA Streamx memory 1 address register */
\r
339 hdma->Instance->M1AR = 0;
\r
341 /* Reset DMA Streamx FIFO control register */
\r
342 hdma->Instance->FCR = (uint32_t)0x00000021;
\r
344 /* Clear all flags */
\r
345 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
\r
346 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
\r
347 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
\r
348 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
\r
349 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
\r
351 /* Initialize the error code */
\r
352 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
\r
354 /* Initialize the DMA state */
\r
355 hdma->State = HAL_DMA_STATE_RESET;
\r
358 __HAL_UNLOCK(hdma);
\r
367 /** @addtogroup DMA_Exported_Functions_Group2
\r
370 ===============================================================================
\r
371 ##### IO operation functions #####
\r
372 ===============================================================================
\r
373 [..] This section provides functions allowing to:
\r
374 (+) Configure the source, destination address and data length and Start DMA transfer
\r
375 (+) Configure the source, destination address and data length and
\r
376 Start DMA transfer with interrupt
\r
377 (+) Abort DMA transfer
\r
378 (+) Poll for transfer complete
\r
379 (+) Handle DMA interrupt request
\r
386 * @brief Starts the DMA Transfer.
\r
387 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
\r
388 * the configuration information for the specified DMA Stream.
\r
389 * @param SrcAddress: The source memory Buffer address
\r
390 * @param DstAddress: The destination memory Buffer address
\r
391 * @param DataLength: The length of data to be transferred from source to destination
\r
392 * @retval HAL status
\r
394 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
\r
396 /* Process locked */
\r
399 /* Change DMA peripheral state */
\r
400 hdma->State = HAL_DMA_STATE_BUSY;
\r
402 /* Check the parameters */
\r
403 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
\r
405 /* Disable the peripheral */
\r
406 __HAL_DMA_DISABLE(hdma);
\r
408 /* Configure the source, destination address and the data length */
\r
409 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
\r
411 /* Enable the Peripheral */
\r
412 __HAL_DMA_ENABLE(hdma);
\r
418 * @brief Start the DMA Transfer with interrupt enabled.
\r
419 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
\r
420 * the configuration information for the specified DMA Stream.
\r
421 * @param SrcAddress: The source memory Buffer address
\r
422 * @param DstAddress: The destination memory Buffer address
\r
423 * @param DataLength: The length of data to be transferred from source to destination
\r
424 * @retval HAL status
\r
426 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
\r
428 /* Process locked */
\r
431 /* Change DMA peripheral state */
\r
432 hdma->State = HAL_DMA_STATE_BUSY;
\r
434 /* Check the parameters */
\r
435 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
\r
437 /* Disable the peripheral */
\r
438 __HAL_DMA_DISABLE(hdma);
\r
440 /* Configure the source, destination address and the data length */
\r
441 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
\r
443 /* Enable the transfer complete interrupt */
\r
444 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC);
\r
446 /* Enable the Half transfer complete interrupt */
\r
447 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);
\r
449 /* Enable the transfer Error interrupt */
\r
450 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE);
\r
452 /* Enable the FIFO Error interrupt */
\r
453 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_FE);
\r
455 /* Enable the direct mode Error interrupt */
\r
456 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_DME);
\r
458 /* Enable the Peripheral */
\r
459 __HAL_DMA_ENABLE(hdma);
\r
465 * @brief Aborts the DMA Transfer.
\r
466 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
\r
467 * the configuration information for the specified DMA Stream.
\r
469 * @note After disabling a DMA Stream, a check for wait until the DMA Stream is
\r
470 * effectively disabled is added. If a Stream is disabled
\r
471 * while a data transfer is ongoing, the current data will be transferred
\r
472 * and the Stream will be effectively disabled only after the transfer of
\r
473 * this single data is finished.
\r
474 * @retval HAL status
\r
476 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
\r
478 uint32_t tickstart = 0;
\r
480 /* Disable the stream */
\r
481 __HAL_DMA_DISABLE(hdma);
\r
484 tickstart = HAL_GetTick();
\r
486 /* Check if the DMA Stream is effectively disabled */
\r
487 while((hdma->Instance->CR & DMA_SxCR_EN) != 0)
\r
489 /* Check for the Timeout */
\r
490 if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
\r
492 /* Update error code */
\r
493 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
\r
495 /* Process Unlocked */
\r
496 __HAL_UNLOCK(hdma);
\r
498 /* Change the DMA state */
\r
499 hdma->State = HAL_DMA_STATE_TIMEOUT;
\r
501 return HAL_TIMEOUT;
\r
504 /* Process Unlocked */
\r
505 __HAL_UNLOCK(hdma);
\r
507 /* Change the DMA state*/
\r
508 hdma->State = HAL_DMA_STATE_READY;
\r
514 * @brief Polling for transfer complete.
\r
515 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
\r
516 * the configuration information for the specified DMA Stream.
\r
517 * @param CompleteLevel: Specifies the DMA level complete.
\r
518 * @param Timeout: Timeout duration.
\r
519 * @retval HAL status
\r
521 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
\r
523 uint32_t temp, tmp, tmp1, tmp2;
\r
524 uint32_t tickstart = 0;
\r
526 /* Get the level transfer complete flag */
\r
527 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
\r
529 /* Transfer Complete flag */
\r
530 temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
\r
534 /* Half Transfer Complete flag */
\r
535 temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
\r
539 tickstart = HAL_GetTick();
\r
541 while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
\r
543 tmp = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
\r
544 tmp1 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
\r
545 tmp2 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
\r
546 if((tmp != RESET) || (tmp1 != RESET) || (tmp2 != RESET))
\r
550 /* Update error code */
\r
551 hdma->ErrorCode |= HAL_DMA_ERROR_TE;
\r
553 /* Clear the transfer error flag */
\r
554 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
\r
558 /* Update error code */
\r
559 hdma->ErrorCode |= HAL_DMA_ERROR_FE;
\r
561 /* Clear the FIFO error flag */
\r
562 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
\r
566 /* Update error code */
\r
567 hdma->ErrorCode |= HAL_DMA_ERROR_DME;
\r
569 /* Clear the Direct Mode error flag */
\r
570 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
\r
572 /* Change the DMA state */
\r
573 hdma->State= HAL_DMA_STATE_ERROR;
\r
575 /* Process Unlocked */
\r
576 __HAL_UNLOCK(hdma);
\r
580 /* Check for the Timeout */
\r
581 if(Timeout != HAL_MAX_DELAY)
\r
583 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
585 /* Update error code */
\r
586 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
\r
588 /* Change the DMA state */
\r
589 hdma->State = HAL_DMA_STATE_TIMEOUT;
\r
591 /* Process Unlocked */
\r
592 __HAL_UNLOCK(hdma);
\r
594 return HAL_TIMEOUT;
\r
599 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
\r
601 /* Multi_Buffering mode enabled */
\r
602 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
\r
604 /* Clear the half transfer complete flag */
\r
605 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
\r
606 /* Clear the transfer complete flag */
\r
607 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
\r
609 /* Current memory buffer used is Memory 0 */
\r
610 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
\r
612 /* Change DMA peripheral state */
\r
613 hdma->State = HAL_DMA_STATE_READY_MEM0;
\r
615 /* Current memory buffer used is Memory 1 */
\r
616 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
\r
618 /* Change DMA peripheral state */
\r
619 hdma->State = HAL_DMA_STATE_READY_MEM1;
\r
624 /* Clear the half transfer complete flag */
\r
625 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
\r
626 /* Clear the transfer complete flag */
\r
627 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
\r
629 /* The selected Streamx EN bit is cleared (DMA is disabled and all transfers
\r
631 hdma->State = HAL_DMA_STATE_READY_MEM0;
\r
633 /* Process Unlocked */
\r
634 __HAL_UNLOCK(hdma);
\r
638 /* Multi_Buffering mode enabled */
\r
639 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
\r
641 /* Clear the half transfer complete flag */
\r
642 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
\r
644 /* Current memory buffer used is Memory 0 */
\r
645 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
\r
647 /* Change DMA peripheral state */
\r
648 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
\r
650 /* Current memory buffer used is Memory 1 */
\r
651 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
\r
653 /* Change DMA peripheral state */
\r
654 hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;
\r
659 /* Clear the half transfer complete flag */
\r
660 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
\r
662 /* Change DMA peripheral state */
\r
663 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
\r
670 * @brief Handles DMA interrupt request.
\r
671 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
\r
672 * the configuration information for the specified DMA Stream.
\r
675 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
\r
677 /* Transfer Error Interrupt management ***************************************/
\r
678 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)
\r
680 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
\r
682 /* Disable the transfer error interrupt */
\r
683 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);
\r
685 /* Clear the transfer error flag */
\r
686 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
\r
688 /* Update error code */
\r
689 hdma->ErrorCode |= HAL_DMA_ERROR_TE;
\r
691 /* Change the DMA state */
\r
692 hdma->State = HAL_DMA_STATE_ERROR;
\r
694 /* Process Unlocked */
\r
695 __HAL_UNLOCK(hdma);
\r
697 if(hdma->XferErrorCallback != NULL)
\r
699 /* Transfer error callback */
\r
700 hdma->XferErrorCallback(hdma);
\r
704 /* FIFO Error Interrupt management ******************************************/
\r
705 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)) != RESET)
\r
707 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
\r
709 /* Disable the FIFO Error interrupt */
\r
710 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_FE);
\r
712 /* Clear the FIFO error flag */
\r
713 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
\r
715 /* Update error code */
\r
716 hdma->ErrorCode |= HAL_DMA_ERROR_FE;
\r
718 /* Change the DMA state */
\r
719 hdma->State = HAL_DMA_STATE_ERROR;
\r
721 /* Process Unlocked */
\r
722 __HAL_UNLOCK(hdma);
\r
724 if(hdma->XferErrorCallback != NULL)
\r
726 /* Transfer error callback */
\r
727 hdma->XferErrorCallback(hdma);
\r
731 /* Direct Mode Error Interrupt management ***********************************/
\r
732 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)) != RESET)
\r
734 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
\r
736 /* Disable the direct mode Error interrupt */
\r
737 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_DME);
\r
739 /* Clear the direct mode error flag */
\r
740 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
\r
742 /* Update error code */
\r
743 hdma->ErrorCode |= HAL_DMA_ERROR_DME;
\r
745 /* Change the DMA state */
\r
746 hdma->State = HAL_DMA_STATE_ERROR;
\r
748 /* Process Unlocked */
\r
749 __HAL_UNLOCK(hdma);
\r
751 if(hdma->XferErrorCallback != NULL)
\r
753 /* Transfer error callback */
\r
754 hdma->XferErrorCallback(hdma);
\r
758 /* Half Transfer Complete Interrupt management ******************************/
\r
759 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
\r
761 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
\r
763 /* Multi_Buffering mode enabled */
\r
764 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
\r
766 /* Clear the half transfer complete flag */
\r
767 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
\r
769 /* Current memory buffer used is Memory 0 */
\r
770 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
\r
772 /* Change DMA peripheral state */
\r
773 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
\r
775 /* Current memory buffer used is Memory 1 */
\r
776 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
\r
778 /* Change DMA peripheral state */
\r
779 hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;
\r
784 /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
\r
785 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
\r
787 /* Disable the half transfer interrupt */
\r
788 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
\r
790 /* Clear the half transfer complete flag */
\r
791 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
\r
793 /* Change DMA peripheral state */
\r
794 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
\r
797 if(hdma->XferHalfCpltCallback != NULL)
\r
799 /* Half transfer callback */
\r
800 hdma->XferHalfCpltCallback(hdma);
\r
804 /* Transfer Complete Interrupt management ***********************************/
\r
805 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)
\r
807 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
\r
809 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
\r
811 /* Clear the transfer complete flag */
\r
812 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
\r
814 /* Current memory buffer used is Memory 1 */
\r
815 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
\r
817 if(hdma->XferM1CpltCallback != NULL)
\r
819 /* Transfer complete Callback for memory1 */
\r
820 hdma->XferM1CpltCallback(hdma);
\r
823 /* Current memory buffer used is Memory 0 */
\r
824 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
\r
826 if(hdma->XferCpltCallback != NULL)
\r
828 /* Transfer complete Callback for memory0 */
\r
829 hdma->XferCpltCallback(hdma);
\r
833 /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
\r
836 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
\r
838 /* Disable the transfer complete interrupt */
\r
839 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);
\r
841 /* Clear the transfer complete flag */
\r
842 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
\r
844 /* Update error code */
\r
845 hdma->ErrorCode |= HAL_DMA_ERROR_NONE;
\r
847 /* Change the DMA state */
\r
848 hdma->State = HAL_DMA_STATE_READY_MEM0;
\r
850 /* Process Unlocked */
\r
851 __HAL_UNLOCK(hdma);
\r
853 if(hdma->XferCpltCallback != NULL)
\r
855 /* Transfer complete callback */
\r
856 hdma->XferCpltCallback(hdma);
\r
867 /** @addtogroup DMA_Exported_Functions_Group3
\r
870 ===============================================================================
\r
871 ##### State and Errors functions #####
\r
872 ===============================================================================
\r
874 This subsection provides functions allowing to
\r
875 (+) Check the DMA state
\r
883 * @brief Returns the DMA state.
\r
884 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
\r
885 * the configuration information for the specified DMA Stream.
\r
886 * @retval HAL state
\r
888 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
\r
890 return hdma->State;
\r
894 * @brief Return the DMA error code
\r
895 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
\r
896 * the configuration information for the specified DMA Stream.
\r
897 * @retval DMA Error Code
\r
899 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
\r
901 return hdma->ErrorCode;
\r
912 #endif /* HAL_DMA_MODULE_ENABLED */
\r
921 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r