]> git.gir.st - tmk_keyboard.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/stm32f4xx_hal_dma.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[tmk_keyboard.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F4 / stm32f4xx_hal_dma.c
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_dma.c
4 * @author MCD Application Team
5 * @version V1.1.0
6 * @date 19-June-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
124 * @brief DMA HAL module driver
125 * @{
126 */
127
128 #ifdef HAL_DMA_MODULE_ENABLED
129
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);
137
138 /* Private functions ---------------------------------------------------------*/
139
140 /** @defgroup DMA_Private_Functions
141 * @{
142 */
143
144 /** @defgroup DMA_Group1 Initialization and de-initialization functions
145 * @brief Initialization and de-initialization functions
146 *
147 @verbatim
148 ===============================================================================
149 ##### Initialization and de-initialization functions #####
150 ===============================================================================
151 [..]
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.
155 [..]
156 The HAL_DMA_Init() function follows the DMA configuration procedures as described in
157 reference manual.
158
159 @endverbatim
160 * @{
161 */
162
163 /**
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.
168 * @retval HAL status
169 */
170 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
171 {
172 uint32_t tmp = 0;
173
174 /* Check the DMA peripheral state */
175 if(hdma == HAL_NULL)
176 {
177 return HAL_ERROR;
178 }
179
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)
194 {
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));
198 }
199
200 /* Change DMA peripheral state */
201 hdma->State = HAL_DMA_STATE_BUSY;
202
203 /* Get the CR register value */
204 tmp = hdma->Instance->CR;
205
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 ));
211
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;
217
218 /* the Memory burst and peripheral burst are not used when the FIFO is disabled */
219 if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
220 {
221 /* Get memory burst and peripheral burst */
222 tmp |= hdma->Init.MemBurst | hdma->Init.PeriphBurst;
223 }
224
225 /* Write to DMA Stream CR register */
226 hdma->Instance->CR = tmp;
227
228 /* Get the FCR register value */
229 tmp = hdma->Instance->FCR;
230
231 /* Clear Direct mode and FIFO threshold bits */
232 tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
233
234 /* Prepare the DMA Stream FIFO configuration */
235 tmp |= hdma->Init.FIFOMode;
236
237 /* the FIFO threshold is not used when the FIFO mode is disabled */
238 if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
239 {
240 /* Get the FIFO threshold */
241 tmp |= hdma->Init.FIFOThreshold;
242 }
243
244 /* Write to DMA Stream FCR */
245 hdma->Instance->FCR = tmp;
246
247 /* Initialise the error code */
248 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
249
250 /* Initialize the DMA state */
251 hdma->State = HAL_DMA_STATE_READY;
252
253 return HAL_OK;
254 }
255
256 /**
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.
260 * @retval HAL status
261 */
262 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
263 {
264 /* Check the DMA peripheral state */
265 if(hdma == HAL_NULL)
266 {
267 return HAL_ERROR;
268 }
269
270 /* Check the DMA peripheral state */
271 if(hdma->State == HAL_DMA_STATE_BUSY)
272 {
273 return HAL_ERROR;
274 }
275
276 /* Disable the selected DMA Streamx */
277 __HAL_DMA_DISABLE(hdma);
278
279 /* Reset DMA Streamx control register */
280 hdma->Instance->CR = 0;
281
282 /* Reset DMA Streamx number of data to transfer register */
283 hdma->Instance->NDTR = 0;
284
285 /* Reset DMA Streamx peripheral address register */
286 hdma->Instance->PAR = 0;
287
288 /* Reset DMA Streamx memory 0 address register */
289 hdma->Instance->M0AR = 0;
290
291 /* Reset DMA Streamx memory 1 address register */
292 hdma->Instance->M1AR = 0;
293
294 /* Reset DMA Streamx FIFO control register */
295 hdma->Instance->FCR = (uint32_t)0x00000021;
296
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));
303
304 /* Initialise the error code */
305 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
306
307 /* Initialize the DMA state */
308 hdma->State = HAL_DMA_STATE_RESET;
309
310 /* Release Lock */
311 __HAL_UNLOCK(hdma);
312
313 return HAL_OK;
314 }
315
316 /**
317 * @}
318 */
319
320 /** @defgroup DMA_Group2 I/O operation functions
321 * @brief I/O operation functions
322 *
323 @verbatim
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
334
335 @endverbatim
336 * @{
337 */
338
339 /**
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
346 * @retval HAL status
347 */
348 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
349 {
350 /* Process locked */
351 __HAL_LOCK(hdma);
352
353 /* Change DMA peripheral state */
354 hdma->State = HAL_DMA_STATE_BUSY;
355
356 /* Check the parameters */
357 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
358
359 /* Disable the peripheral */
360 __HAL_DMA_DISABLE(hdma);
361
362 /* Configure the source, destination address and the data length */
363 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
364
365 /* Enable the Peripheral */
366 __HAL_DMA_ENABLE(hdma);
367
368 return HAL_OK;
369 }
370
371 /**
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
378 * @retval HAL status
379 */
380 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
381 {
382 /* Process locked */
383 __HAL_LOCK(hdma);
384
385 /* Change DMA peripheral state */
386 hdma->State = HAL_DMA_STATE_BUSY;
387
388 /* Check the parameters */
389 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
390
391 /* Disable the peripheral */
392 __HAL_DMA_DISABLE(hdma);
393
394 /* Configure the source, destination address and the data length */
395 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
396
397 /* Enable the transfer complete interrupt */
398 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC);
399
400 /* Enable the Half transfer complete interrupt */
401 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);
402
403 /* Enable the transfer Error interrupt */
404 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE);
405
406 /* Enable the FIFO Error interrupt */
407 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_FE);
408
409 /* Enable the direct mode Error interrupt */
410 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_DME);
411
412 /* Enable the Peripheral */
413 __HAL_DMA_ENABLE(hdma);
414
415 return HAL_OK;
416 }
417
418 /**
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.
422 *
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.
428 * @retval HAL status
429 */
430 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
431 {
432 uint32_t tickstart = 0;
433
434 /* Disable the stream */
435 __HAL_DMA_DISABLE(hdma);
436
437 /* Get tick */
438 tickstart = HAL_GetTick();
439
440 /* Check if the DMA Stream is effectively disabled */
441 while((hdma->Instance->CR & DMA_SxCR_EN) != 0)
442 {
443 /* Check for the Timeout */
444 if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
445 {
446 /* Update error code */
447 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
448
449 /* Process Unlocked */
450 __HAL_UNLOCK(hdma);
451
452 /* Change the DMA state */
453 hdma->State = HAL_DMA_STATE_TIMEOUT;
454
455 return HAL_TIMEOUT;
456 }
457 }
458 /* Process Unlocked */
459 __HAL_UNLOCK(hdma);
460
461 /* Change the DMA state*/
462 hdma->State = HAL_DMA_STATE_READY;
463
464 return HAL_OK;
465 }
466
467 /**
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.
473 * @retval HAL status
474 */
475 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
476 {
477 uint32_t temp, tmp, tmp1, tmp2;
478 uint32_t tickstart = 0;
479
480 /* Get the level transfer complete flag */
481 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
482 {
483 /* Transfer Complete flag */
484 temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
485 }
486 else
487 {
488 /* Half Transfer Complete flag */
489 temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
490 }
491
492 /* Get tick */
493 tickstart = HAL_GetTick();
494
495 while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
496 {
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))
501 {
502 if(tmp != RESET)
503 {
504 /* Update error code */
505 hdma->ErrorCode |= HAL_DMA_ERROR_TE;
506
507 /* Clear the transfer error flag */
508 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
509 }
510 if(tmp1 != RESET)
511 {
512 /* Update error code */
513 hdma->ErrorCode |= HAL_DMA_ERROR_FE;
514
515 /* Clear the FIFO error flag */
516 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
517 }
518 if(tmp2 != RESET)
519 {
520 /* Update error code */
521 hdma->ErrorCode |= HAL_DMA_ERROR_DME;
522
523 /* Clear the Direct Mode error flag */
524 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
525 }
526 /* Change the DMA state */
527 hdma->State= HAL_DMA_STATE_ERROR;
528
529 /* Process Unlocked */
530 __HAL_UNLOCK(hdma);
531
532 return HAL_ERROR;
533 }
534 /* Check for the Timeout */
535 if(Timeout != HAL_MAX_DELAY)
536 {
537 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
538 {
539 /* Update error code */
540 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
541
542 /* Change the DMA state */
543 hdma->State = HAL_DMA_STATE_TIMEOUT;
544
545 /* Process Unlocked */
546 __HAL_UNLOCK(hdma);
547
548 return HAL_TIMEOUT;
549 }
550 }
551 }
552
553 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
554 {
555 /* Multi_Buffering mode enabled */
556 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
557 {
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));
562
563 /* Current memory buffer used is Memory 0 */
564 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
565 {
566 /* Change DMA peripheral state */
567 hdma->State = HAL_DMA_STATE_READY_MEM0;
568 }
569 /* Current memory buffer used is Memory 1 */
570 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
571 {
572 /* Change DMA peripheral state */
573 hdma->State = HAL_DMA_STATE_READY_MEM1;
574 }
575 }
576 else
577 {
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));
582
583 /* The selected Streamx EN bit is cleared (DMA is disabled and all transfers
584 are complete) */
585 hdma->State = HAL_DMA_STATE_READY_MEM0;
586 }
587 /* Process Unlocked */
588 __HAL_UNLOCK(hdma);
589 }
590 else
591 {
592 /* Multi_Buffering mode enabled */
593 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
594 {
595 /* Clear the half transfer complete flag */
596 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
597
598 /* Current memory buffer used is Memory 0 */
599 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
600 {
601 /* Change DMA peripheral state */
602 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
603 }
604 /* Current memory buffer used is Memory 1 */
605 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
606 {
607 /* Change DMA peripheral state */
608 hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;
609 }
610 }
611 else
612 {
613 /* Clear the half transfer complete flag */
614 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
615
616 /* Change DMA peripheral state */
617 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
618 }
619 }
620 return HAL_OK;
621 }
622
623 /**
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.
627 * @retval None
628 */
629 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
630 {
631 /* Transfer Error Interrupt management ***************************************/
632 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)
633 {
634 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
635 {
636 /* Disable the transfer error interrupt */
637 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);
638
639 /* Clear the transfer error flag */
640 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
641
642 /* Update error code */
643 hdma->ErrorCode |= HAL_DMA_ERROR_TE;
644
645 /* Change the DMA state */
646 hdma->State = HAL_DMA_STATE_ERROR;
647
648 /* Process Unlocked */
649 __HAL_UNLOCK(hdma);
650
651 if(hdma->XferErrorCallback != HAL_NULL)
652 {
653 /* Transfer error callback */
654 hdma->XferErrorCallback(hdma);
655 }
656 }
657 }
658 /* FIFO Error Interrupt management ******************************************/
659 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)) != RESET)
660 {
661 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
662 {
663 /* Disable the FIFO Error interrupt */
664 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_FE);
665
666 /* Clear the FIFO error flag */
667 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
668
669 /* Update error code */
670 hdma->ErrorCode |= HAL_DMA_ERROR_FE;
671
672 /* Change the DMA state */
673 hdma->State = HAL_DMA_STATE_ERROR;
674
675 /* Process Unlocked */
676 __HAL_UNLOCK(hdma);
677
678 if(hdma->XferErrorCallback != HAL_NULL)
679 {
680 /* Transfer error callback */
681 hdma->XferErrorCallback(hdma);
682 }
683 }
684 }
685 /* Direct Mode Error Interrupt management ***********************************/
686 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)) != RESET)
687 {
688 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
689 {
690 /* Disable the direct mode Error interrupt */
691 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_DME);
692
693 /* Clear the direct mode error flag */
694 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
695
696 /* Update error code */
697 hdma->ErrorCode |= HAL_DMA_ERROR_DME;
698
699 /* Change the DMA state */
700 hdma->State = HAL_DMA_STATE_ERROR;
701
702 /* Process Unlocked */
703 __HAL_UNLOCK(hdma);
704
705 if(hdma->XferErrorCallback != HAL_NULL)
706 {
707 /* Transfer error callback */
708 hdma->XferErrorCallback(hdma);
709 }
710 }
711 }
712 /* Half Transfer Complete Interrupt management ******************************/
713 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
714 {
715 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
716 {
717 /* Multi_Buffering mode enabled */
718 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
719 {
720 /* Clear the half transfer complete flag */
721 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
722
723 /* Current memory buffer used is Memory 0 */
724 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
725 {
726 /* Change DMA peripheral state */
727 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
728 }
729 /* Current memory buffer used is Memory 1 */
730 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
731 {
732 /* Change DMA peripheral state */
733 hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;
734 }
735 }
736 else
737 {
738 /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
739 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
740 {
741 /* Disable the half transfer interrupt */
742 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
743 }
744 /* Clear the half transfer complete flag */
745 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
746
747 /* Change DMA peripheral state */
748 hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
749 }
750
751 if(hdma->XferHalfCpltCallback != HAL_NULL)
752 {
753 /* Half transfer callback */
754 hdma->XferHalfCpltCallback(hdma);
755 }
756 }
757 }
758 /* Transfer Complete Interrupt management ***********************************/
759 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)
760 {
761 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
762 {
763 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
764 {
765 /* Clear the transfer complete flag */
766 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
767
768 /* Current memory buffer used is Memory 1 */
769 if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
770 {
771 if(hdma->XferM1CpltCallback != HAL_NULL)
772 {
773 /* Transfer complete Callback for memory1 */
774 hdma->XferM1CpltCallback(hdma);
775 }
776 }
777 /* Current memory buffer used is Memory 0 */
778 else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
779 {
780 if(hdma->XferCpltCallback != HAL_NULL)
781 {
782 /* Transfer complete Callback for memory0 */
783 hdma->XferCpltCallback(hdma);
784 }
785 }
786 }
787 /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
788 else
789 {
790 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
791 {
792 /* Disable the transfer complete interrupt */
793 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);
794 }
795 /* Clear the transfer complete flag */
796 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
797
798 /* Update error code */
799 hdma->ErrorCode |= HAL_DMA_ERROR_NONE;
800
801 /* Change the DMA state */
802 hdma->State = HAL_DMA_STATE_READY_MEM0;
803
804 /* Process Unlocked */
805 __HAL_UNLOCK(hdma);
806
807 if(hdma->XferCpltCallback != HAL_NULL)
808 {
809 /* Transfer complete callback */
810 hdma->XferCpltCallback(hdma);
811 }
812 }
813 }
814 }
815 }
816
817 /**
818 * @}
819 */
820
821 /** @defgroup DMA_Group3 Peripheral State functions
822 * @brief Peripheral State functions
823 *
824 @verbatim
825 ===============================================================================
826 ##### State and Errors functions #####
827 ===============================================================================
828 [..]
829 This subsection provides functions allowing to
830 (+) Check the DMA state
831 (+) Get error code
832
833 @endverbatim
834 * @{
835 */
836
837 /**
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.
841 * @retval HAL state
842 */
843 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
844 {
845 return hdma->State;
846 }
847
848 /**
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
853 */
854 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
855 {
856 return hdma->ErrorCode;
857 }
858
859 /**
860 * @}
861 */
862
863 /**
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
870 * @retval HAL status
871 */
872 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
873 {
874 /* Configure DMA Stream data length */
875 hdma->Instance->NDTR = DataLength;
876
877 /* Peripheral to Memory */
878 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
879 {
880 /* Configure DMA Stream destination address */
881 hdma->Instance->PAR = DstAddress;
882
883 /* Configure DMA Stream source address */
884 hdma->Instance->M0AR = SrcAddress;
885 }
886 /* Memory to Peripheral */
887 else
888 {
889 /* Configure DMA Stream source address */
890 hdma->Instance->PAR = SrcAddress;
891
892 /* Configure DMA Stream destination address */
893 hdma->Instance->M0AR = DstAddress;
894 }
895 }
896
897 /**
898 * @}
899 */
900
901 #endif /* HAL_DMA_MODULE_ENABLED */
902 /**
903 * @}
904 */
905
906 /**
907 * @}
908 */
909
910 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Imprint / Impressum