source: asp3_wo_tecs/trunk/arch/arm_m_gcc/stm32f4xx_stm32cube/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c@ 303

Last change on this file since 303 was 303, checked in by ertl-honda, 7 years ago

nucleo_f401re依存部の追加

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