comparison Common/Drivers/STM32F4xx_HAL_DRIVER_v120/Src/stm32f4xx_hal_dma.c @ 38:5f11787b4f42

include in ostc4 repository
author heinrichsweikamp
date Sat, 28 Apr 2018 11:52:34 +0200
parents
children
comparison
equal deleted inserted replaced
37:ccc45c0e1ea2 38:5f11787b4f42
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_dma.c
4 * @author MCD Application Team
5 * @version V1.2.0
6 * @date 26-December-2014
7 * @brief DMA HAL module driver.
8 *
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
14 @verbatim
15 ==============================================================================
16 ##### How to use this driver #####
17 ==============================================================================
18 [..]
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
22 and DMA requests .
23
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.
29
30 *** Polling mode IO operation ***
31 =================================
32 [..]
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.
37
38 *** Interrupt mode IO operation ***
39 ===================================
40 [..]
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).
50 [..]
51 (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
52 detection.
53
54 (#) Use HAL_DMA_Abort() function to abort the current transfer
55
56 -@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
57
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).
63
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
66 and Destination.
67
68 *** DMA HAL driver macros list ***
69 =============================================
70 [..]
71 Below the list of most used macros in DMA HAL driver.
72
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.
81
82 [..]
83 (@) You can refer to the DMA HAL driver header file for more useful macros
84
85 @endverbatim
86 ******************************************************************************
87 * @attention
88 *
89 * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
90 *
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.
101 *
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.
112 *
113 ******************************************************************************
114 */
115
116 /* Includes ------------------------------------------------------------------*/
117 #include "stm32f4xx_hal.h"
118
119 /** @addtogroup STM32F4xx_HAL_Driver
120 * @{
121 */
122
123 /** @defgroup DMA DMA
124 * @brief DMA HAL module driver
125 * @{
126 */
127
128 #ifdef HAL_DMA_MODULE_ENABLED
129
130 /* Private types -------------------------------------------------------------*/
131 /* Private variables ---------------------------------------------------------*/
132 /* Private constants ---------------------------------------------------------*/
133 /** @addtogroup DMA_Private_Constants
134 * @{
135 */
136 #define HAL_TIMEOUT_DMA_ABORT ((uint32_t)1000) /* 1s */
137 /**
138 * @}
139 */
140 /* Private macros ------------------------------------------------------------*/
141 /* Private functions ---------------------------------------------------------*/
142 /** @addtogroup DMA_Private_Functions
143 * @{
144 */
145 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
146 /**
147 * @}
148 */
149
150 /* Exported functions ---------------------------------------------------------*/
151 /** @addtogroup DMA_Exported_Functions
152 * @{
153 */
154
155 /** @addtogroup DMA_Exported_Functions_Group1
156 *
157 @verbatim
158 ===============================================================================
159 ##### Initialization and de-initialization functions #####
160 ===============================================================================
161 [..]
162 This section provides functions allowing to initialize the DMA Stream source
163 and destination addresses, incrementation and data sizes, transfer direction,
164 circular/normal mode selection, memory-to-memory mode selection and Stream priority value.
165 [..]
166 The HAL_DMA_Init() function follows the DMA configuration procedures as described in
167 reference manual.
168
169 @endverbatim
170 * @{
171 */
172
173 /**
174 * @brief Initializes the DMA according to the specified
175 * parameters in the DMA_InitTypeDef and create the associated handle.
176 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
177 * the configuration information for the specified DMA Stream.
178 * @retval HAL status
179 */
180 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
181 {
182 uint32_t tmp = 0;
183
184 /* Check the DMA peripheral state */
185 if(hdma == NULL)
186 {
187 return HAL_ERROR;
188 }
189
190 /* Check the parameters */
191 assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
192 assert_param(IS_DMA_CHANNEL(hdma->Init.Channel));
193 assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
194 assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
195 assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
196 assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
197 assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
198 assert_param(IS_DMA_MODE(hdma->Init.Mode));
199 assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
200 assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode));
201 /* Check the memory burst, peripheral burst and FIFO threshold parameters only
202 when FIFO mode is enabled */
203 if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE)
204 {
205 assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold));
206 assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst));
207 assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst));
208 }
209
210 /* Change DMA peripheral state */
211 hdma->State = HAL_DMA_STATE_BUSY;
212
213 /* Get the CR register value */
214 tmp = hdma->Instance->CR;
215
216 /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */
217 tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
218 DMA_SxCR_PL | DMA_SxCR_MSIZE | DMA_SxCR_PSIZE | \
219 DMA_SxCR_MINC | DMA_SxCR_PINC | DMA_SxCR_CIRC | \
220 DMA_SxCR_DIR | DMA_SxCR_CT | DMA_SxCR_DBM));
221
222 /* Prepare the DMA Stream configuration */
223 tmp |= hdma->Init.Channel | hdma->Init.Direction |
224 hdma->Init.PeriphInc | hdma->Init.MemInc |
225 hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
226 hdma->Init.Mode | hdma->Init.Priority;
227
228 /* the Memory burst and peripheral burst are not used when the FIFO is disabled */
229 if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
230 {
231 /* Get memory burst and peripheral burst */
232 tmp |= hdma->Init.MemBurst | hdma->Init.PeriphBurst;
233 }
234
235 /* Write to DMA Stream CR register */
236 hdma->Instance->CR = tmp;
237
238 /* Get the FCR register value */
239 tmp = hdma->Instance->FCR;
240
241 /* Clear Direct mode and FIFO threshold bits */
242 tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
243
244 /* Prepare the DMA Stream FIFO configuration */
245 tmp |= hdma->Init.FIFOMode;
246
247 /* the FIFO threshold is not used when the FIFO mode is disabled */
248 if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
249 {
250 /* Get the FIFO threshold */
251 tmp |= hdma->Init.FIFOThreshold;
252 }
253
254 /* Write to DMA Stream FCR */
255 hdma->Instance->FCR = tmp;
256
257 /* Initialize the error code */
258 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
259
260 /* Initialize the DMA state */
261 hdma->State = HAL_DMA_STATE_READY;
262
263 return HAL_OK;
264 }
265
266 /**
267 * @brief DeInitializes the DMA peripheral
268 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
269 * the configuration information for the specified DMA Stream.
270 * @retval HAL status
271 */
272 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
273 {
274 /* Check the DMA peripheral state */
275 if(hdma == NULL)
276 {
277 return HAL_ERROR;
278 }
279
280 /* Check the DMA peripheral state */
281 if(hdma->State == HAL_DMA_STATE_BUSY)
282 {
283 return HAL_ERROR;
284 }
285
286 /* Disable the selected DMA Streamx */
287 __HAL_DMA_DISABLE(hdma);
288
289 /* Reset DMA Streamx control register */
290 hdma->Instance->CR = 0;
291
292 /* Reset DMA Streamx number of data to transfer register */
293 hdma->Instance->NDTR = 0;
294
295 /* Reset DMA Streamx peripheral address register */
296 hdma->Instance->PAR = 0;
297
298 /* Reset DMA Streamx memory 0 address register */
299 hdma->Instance->M0AR = 0;
300
301 /* Reset DMA Streamx memory 1 address register */
302 hdma->Instance->M1AR = 0;
303
304 /* Reset DMA Streamx FIFO control register */
305 hdma->Instance->FCR = (uint32_t)0x00000021;
306
307 /* Clear all flags */
308 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
309 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
310 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
311 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
312 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
313
314 /* Initialize the error code */
315 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
316
317 /* Initialize the DMA state */
318 hdma->State = HAL_DMA_STATE_RESET;
319
320 /* Release Lock */
321 __HAL_UNLOCK(hdma);
322
323 return HAL_OK;
324 }
325
326 /**
327 * @}
328 */
329
330 /** @addtogroup DMA_Exported_Functions_Group2
331 *
332 @verbatim
333 ===============================================================================
334 ##### IO operation functions #####
335 ===============================================================================
336 [..] This section provides functions allowing to:
337 (+) Configure the source, destination address and data length and Start DMA transfer
338 (+) Configure the source, destination address and data length and
339 Start DMA transfer with interrupt
340 (+) Abort DMA transfer
341 (+) Poll for transfer complete
342 (+) Handle DMA interrupt request
343
344 @endverbatim
345 * @{
346 */
347
348 /**
349 * @brief Starts the DMA Transfer.
350 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
351 * the configuration information for the specified DMA Stream.
352 * @param SrcAddress: The source memory Buffer address
353 * @param DstAddress: The destination memory Buffer address
354 * @param DataLength: The length of data to be transferred from source to destination
355 * @retval HAL status
356 */
357 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
358 {
359 /* Process locked */
360 __HAL_LOCK(hdma);
361
362 /* Change DMA peripheral state */
363 hdma->State = HAL_DMA_STATE_BUSY;
364
365 /* Check the parameters */
366 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
367
368 /* Disable the peripheral */
369 __HAL_DMA_DISABLE(hdma);
370
371 /* Configure the source, destination address and the data length */
372 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
373
374 /* Enable the Peripheral */
375 __HAL_DMA_ENABLE(hdma);
376
377 return HAL_OK;
378 }
379
380 /**
381 * @brief Start the DMA Transfer with interrupt enabled.
382 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
383 * the configuration information for the specified DMA Stream.
384 * @param SrcAddress: The source memory Buffer address
385 * @param DstAddress: The destination memory Buffer address
386 * @param DataLength: The length of data to be transferred from source to destination
387 * @retval HAL status
388 */
389 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
390 {
391 /* Process locked */
392 __HAL_LOCK(hdma);
393
394 /* Change DMA peripheral state */
395 hdma->State = HAL_DMA_STATE_BUSY;
396
397 /* Check the parameters */
398 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
399
400 /* Disable the peripheral */
401 __HAL_DMA_DISABLE(hdma);
402
403 /* Configure the source, destination address and the data length */
404 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
405
406 /* Enable the transfer complete interrupt */
407 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC);
408
409 /* Enable the Half transfer complete interrupt */
410 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);
411
412 /* Enable the transfer Error interrupt */
413 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE);
414
415 /* Enable the FIFO Error interrupt */
416 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_FE);
417
418 /* Enable the direct mode Error interrupt */
419 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_DME);
420
421 /* Enable the Peripheral */
422 __HAL_DMA_ENABLE(hdma);
423
424 return HAL_OK;
425 }
426
427 /**
428 * @brief Aborts the DMA Transfer.
429 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
430 * the configuration information for the specified DMA Stream.
431 *
432 * @note After disabling a DMA Stream, a check for wait until the DMA Stream is
433 * effectively disabled is added. If a Stream is disabled
434 * while a data transfer is ongoing, the current data will be transferred
435 * and the Stream will be effectively disabled only after the transfer of
436 * this single data is finished.
437 * @retval HAL status
438 */
439 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
440 {
441 uint32_t tickstart = 0;
442
443 /* Disable the stream */
444 __HAL_DMA_DISABLE(hdma);
445
446 /* Get tick */
447 tickstart = HAL_GetTick();
448
449 /* Check if the DMA Stream is effectively disabled */
450 while((hdma->Instance->CR & DMA_SxCR_EN) != 0)
451 {
452 /* Check for the Timeout */
453 if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
454 {
455 /* Update error code */
456 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
457
458 /* Process Unlocked */
459 __HAL_UNLOCK(hdma);
460
461 /* Change the DMA state */
462 hdma->State = HAL_DMA_STATE_TIMEOUT;
463
464 return HAL_TIMEOUT;
465 }
466 }
467 /* Process Unlocked */
468 __HAL_UNLOCK(hdma);
469
470 /* Change the DMA state*/
471 hdma->State = HAL_DMA_STATE_READY;
472
473 return HAL_OK;
474 }
475
476 /**
477 * @brief Polling for transfer complete.
478 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
479 * the configuration information for the specified DMA Stream.
480 * @param CompleteLevel: Specifies the DMA level complete.
481 * @param Timeout: Timeout duration.
482 * @retval HAL status
483 */
484 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
485 {
486 uint32_t temp, tmp, tmp1, tmp2;
487 uint32_t tickstart = 0;
488
489 /* Get the level transfer complete flag */
490 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
491 {
492 /* Transfer Complete flag */
493 temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
494 }
495 else
496 {
497 /* Half Transfer Complete flag */
498 temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
499 }
500
501 /* Get tick */
502 tickstart = HAL_GetTick();
503
504 while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
505 {
506 tmp = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
507 tmp1 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
508 tmp2 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
509 if((tmp != RESET) || (tmp1 != RESET) || (tmp2 != RESET))
510 {
511 if(tmp != RESET)
512 {
513 /* Update error code */
514 hdma->ErrorCode |= HAL_DMA_ERROR_TE;
515
516 /* Clear the transfer error flag */
517 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
518 }
519 if(tmp1 != RESET)
520 {
521 /* Update error code */
522 hdma->ErrorCode |= HAL_DMA_ERROR_FE;
523
524 /* Clear the FIFO error flag */
525 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
526 }
527 if(tmp2 != RESET)
528 {
529 /* Update error code */
530 hdma->ErrorCode |= HAL_DMA_ERROR_DME;
531
532 /* Clear the Direct Mode error flag */
533 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
534 }
535 /* Change the DMA state */
536 hdma->State= HAL_DMA_STATE_ERROR;
537
538 /* Process Unlocked */
539 __HAL_UNLOCK(hdma);
540
541 return HAL_ERROR;
542 }
543 /* Check for the Timeout */
544 if(Timeout != HAL_MAX_DELAY)
545 {
546 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
547 {
548 /* Update error code */
549 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
550
551 /* Change the DMA state */
552 hdma->State = HAL_DMA_STATE_TIMEOUT;
553
554 /* Process Unlocked */
555 __HAL_UNLOCK(hdma);
556
557 return HAL_TIMEOUT;
558 }
559 }
560 }
561
562 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
563 {
564 /* Multi_Buffering mode enabled */
565 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
566 {
567 /* Clear the half transfer complete flag */
568 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
569 /* Clear the transfer complete flag */
570 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
571
572 /* Current memory buffer used is Memory 0 */
573 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
574 {
575 /* Change DMA peripheral state */
576 hdma->State = HAL_DMA_STATE_READY_MEM0;
577 }
578 /* Current memory buffer used is Memory 1 */
579 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
580 {
581 /* Change DMA peripheral state */
582 hdma->State = HAL_DMA_STATE_READY_MEM1;
583 }
584 }
585 else
586 {
587 /* Clear the half transfer complete flag */
588 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
589 /* Clear the transfer complete flag */
590 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
591
592 /* The selected Streamx EN bit is cleared (DMA is disabled and all transfers
593 are complete) */
594 hdma->State = HAL_DMA_STATE_READY_MEM0;
595 }
596 /* Process Unlocked */
597 __HAL_UNLOCK(hdma);
598 }
599 else
600 {
601 /* Multi_Buffering mode enabled */
602 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
603 {
604 /* Clear the half transfer complete flag */
605 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
606
607 /* Current memory buffer used is Memory 0 */
608 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
609 {
610 /* Change DMA peripheral state */
611 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
612 }
613 /* Current memory buffer used is Memory 1 */
614 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
615 {
616 /* Change DMA peripheral state */
617 hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;
618 }
619 }
620 else
621 {
622 /* Clear the half transfer complete flag */
623 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
624
625 /* Change DMA peripheral state */
626 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
627 }
628 }
629 return HAL_OK;
630 }
631
632 /**
633 * @brief Handles DMA interrupt request.
634 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
635 * the configuration information for the specified DMA Stream.
636 * @retval None
637 */
638 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
639 {
640 /* Transfer Error Interrupt management ***************************************/
641 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)
642 {
643 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
644 {
645 /* Disable the transfer error interrupt */
646 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);
647
648 /* Clear the transfer error flag */
649 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
650
651 /* Update error code */
652 hdma->ErrorCode |= HAL_DMA_ERROR_TE;
653
654 /* Change the DMA state */
655 hdma->State = HAL_DMA_STATE_ERROR;
656
657 /* Process Unlocked */
658 __HAL_UNLOCK(hdma);
659
660 if(hdma->XferErrorCallback != NULL)
661 {
662 /* Transfer error callback */
663 hdma->XferErrorCallback(hdma);
664 }
665 }
666 }
667 /* FIFO Error Interrupt management ******************************************/
668 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)) != RESET)
669 {
670 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
671 {
672 /* Disable the FIFO Error interrupt */
673 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_FE);
674
675 /* Clear the FIFO error flag */
676 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
677
678 /* Update error code */
679 hdma->ErrorCode |= HAL_DMA_ERROR_FE;
680
681 /* Change the DMA state */
682 hdma->State = HAL_DMA_STATE_ERROR;
683
684 /* Process Unlocked */
685 __HAL_UNLOCK(hdma);
686
687 if(hdma->XferErrorCallback != NULL)
688 {
689 /* Transfer error callback */
690 hdma->XferErrorCallback(hdma);
691 }
692 }
693 }
694 /* Direct Mode Error Interrupt management ***********************************/
695 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)) != RESET)
696 {
697 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
698 {
699 /* Disable the direct mode Error interrupt */
700 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_DME);
701
702 /* Clear the direct mode error flag */
703 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
704
705 /* Update error code */
706 hdma->ErrorCode |= HAL_DMA_ERROR_DME;
707
708 /* Change the DMA state */
709 hdma->State = HAL_DMA_STATE_ERROR;
710
711 /* Process Unlocked */
712 __HAL_UNLOCK(hdma);
713
714 if(hdma->XferErrorCallback != NULL)
715 {
716 /* Transfer error callback */
717 hdma->XferErrorCallback(hdma);
718 }
719 }
720 }
721 /* Half Transfer Complete Interrupt management ******************************/
722 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
723 {
724 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
725 {
726 /* Multi_Buffering mode enabled */
727 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
728 {
729 /* Clear the half transfer complete flag */
730 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
731
732 /* Current memory buffer used is Memory 0 */
733 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
734 {
735 /* Change DMA peripheral state */
736 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
737 }
738 /* Current memory buffer used is Memory 1 */
739 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
740 {
741 /* Change DMA peripheral state */
742 hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;
743 }
744 }
745 else
746 {
747 /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
748 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
749 {
750 /* Disable the half transfer interrupt */
751 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
752 }
753 /* Clear the half transfer complete flag */
754 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
755
756 /* Change DMA peripheral state */
757 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
758 }
759
760 if(hdma->XferHalfCpltCallback != NULL)
761 {
762 /* Half transfer callback */
763 hdma->XferHalfCpltCallback(hdma);
764 }
765 }
766 }
767 /* Transfer Complete Interrupt management ***********************************/
768 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)
769 {
770 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
771 {
772 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
773 {
774 /* Clear the transfer complete flag */
775 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
776
777 /* Current memory buffer used is Memory 1 */
778 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
779 {
780 if(hdma->XferM1CpltCallback != NULL)
781 {
782 /* Transfer complete Callback for memory1 */
783 hdma->XferM1CpltCallback(hdma);
784 }
785 }
786 /* Current memory buffer used is Memory 0 */
787 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
788 {
789 if(hdma->XferCpltCallback != NULL)
790 {
791 /* Transfer complete Callback for memory0 */
792 hdma->XferCpltCallback(hdma);
793 }
794 }
795 }
796 /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
797 else
798 {
799 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
800 {
801 /* Disable the transfer complete interrupt */
802 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);
803 }
804 /* Clear the transfer complete flag */
805 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
806
807 /* Update error code */
808 hdma->ErrorCode |= HAL_DMA_ERROR_NONE;
809
810 /* Change the DMA state */
811 hdma->State = HAL_DMA_STATE_READY_MEM0;
812
813 /* Process Unlocked */
814 __HAL_UNLOCK(hdma);
815
816 if(hdma->XferCpltCallback != NULL)
817 {
818 /* Transfer complete callback */
819 hdma->XferCpltCallback(hdma);
820 }
821 }
822 }
823 }
824 }
825
826 /**
827 * @}
828 */
829
830 /** @addtogroup DMA_Exported_Functions_Group3
831 *
832 @verbatim
833 ===============================================================================
834 ##### State and Errors functions #####
835 ===============================================================================
836 [..]
837 This subsection provides functions allowing to
838 (+) Check the DMA state
839 (+) Get error code
840
841 @endverbatim
842 * @{
843 */
844
845 /**
846 * @brief Returns the DMA state.
847 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
848 * the configuration information for the specified DMA Stream.
849 * @retval HAL state
850 */
851 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
852 {
853 return hdma->State;
854 }
855
856 /**
857 * @brief Return the DMA error code
858 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
859 * the configuration information for the specified DMA Stream.
860 * @retval DMA Error Code
861 */
862 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
863 {
864 return hdma->ErrorCode;
865 }
866
867 /**
868 * @}
869 */
870
871 /**
872 * @}
873 */
874
875 /** @addtogroup DMA_Private_Functions
876 * @{
877 */
878
879 /**
880 * @brief Sets the DMA Transfer parameter.
881 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
882 * the configuration information for the specified DMA Stream.
883 * @param SrcAddress: The source memory Buffer address
884 * @param DstAddress: The destination memory Buffer address
885 * @param DataLength: The length of data to be transferred from source to destination
886 * @retval HAL status
887 */
888 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
889 {
890 /* Clear DBM bit */
891 hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);
892
893 /* Configure DMA Stream data length */
894 hdma->Instance->NDTR = DataLength;
895
896 /* Peripheral to Memory */
897 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
898 {
899 /* Configure DMA Stream destination address */
900 hdma->Instance->PAR = DstAddress;
901
902 /* Configure DMA Stream source address */
903 hdma->Instance->M0AR = SrcAddress;
904 }
905 /* Memory to Peripheral */
906 else
907 {
908 /* Configure DMA Stream source address */
909 hdma->Instance->PAR = SrcAddress;
910
911 /* Configure DMA Stream destination address */
912 hdma->Instance->M0AR = DstAddress;
913 }
914 }
915 /**
916 * @}
917 */
918
919 #endif /* HAL_DMA_MODULE_ENABLED */
920 /**
921 * @}
922 */
923
924 /**
925 * @}
926 */
927
928 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/