]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M7_STM32F7_STM32756G-EVAL/ST_Library/stm32f7xx_hal_dma.c
Update version number ready for V8.2.1 release.
[freertos] / FreeRTOS / Demo / CORTEX_M7_STM32F7_STM32756G-EVAL / ST_Library / stm32f7xx_hal_dma.c
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32f7xx_hal_dma.c\r
4   * @author  MCD Application Team\r
5   * @version V0.3.0\r
6   * @date    06-March-2015\r
7   * @brief   DMA HAL module driver.\r
8   *    \r
9   *          This file provides firmware functions to manage the following \r
10   *          functionalities of the Direct Memory Access (DMA) peripheral:\r
11   *           + Initialization and de-initialization functions\r
12   *           + IO operation functions\r
13   *           + Peripheral State and errors functions\r
14   @verbatim     \r
15   ==============================================================================      \r
16                         ##### How to use this driver #####\r
17   ============================================================================== \r
18   [..]\r
19    (#) Enable and configure the peripheral to be connected to the DMA Stream\r
20        (except for internal SRAM/FLASH memories: no initialization is \r
21        necessary) please refer to Reference manual for connection between peripherals\r
22        and DMA requests . \r
23           \r
24    (#) For a given Stream, program the required configuration through the following parameters:   \r
25        Transfer Direction, Source and Destination data formats, \r
26        Circular, Normal or peripheral flow control mode, Stream Priority level, \r
27        Source and Destination Increment mode, FIFO mode and its Threshold (if needed), \r
28        Burst mode for Source and/or Destination (if needed) using HAL_DMA_Init() function.\r
29                      \r
30      *** Polling mode IO operation ***\r
31      =================================   \r
32     [..] \r
33           (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source \r
34               address and destination address and the Length of data to be transferred\r
35           (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this  \r
36               case a fixed Timeout can be configured by User depending from his application.\r
37                \r
38      *** Interrupt mode IO operation ***    \r
39      =================================== \r
40     [..]     \r
41           (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()\r
42           (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ() \r
43           (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of  \r
44               Source address and destination address and the Length of data to be transferred. In this \r
45               case the DMA interrupt is configured \r
46           (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine\r
47           (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can \r
48               add his own function by customization of function pointer XferCpltCallback and \r
49               XferErrorCallback (i.e a member of DMA handle structure). \r
50     [..]                \r
51      (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error \r
52          detection.\r
53          \r
54      (#) Use HAL_DMA_Abort() function to abort the current transfer\r
55      \r
56      -@-   In Memory-to-Memory transfer mode, Circular mode is not allowed.\r
57     \r
58      -@-   The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is\r
59            possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set\r
60            Half-Word data size for the peripheral to access its data register and set Word data size\r
61            for the Memory to gain in access time. Each two half words will be packed and written in\r
62            a single access to a Word in the Memory).\r
63       \r
64      -@-   When FIFO is disabled, it is not allowed to configure different Data Sizes for Source\r
65            and Destination. In this case the Peripheral Data Size will be applied to both Source\r
66            and Destination.               \r
67   \r
68      *** DMA HAL driver macros list ***\r
69      ============================================= \r
70      [..]\r
71        Below the list of most used macros in DMA HAL driver.\r
72        \r
73       (+) __HAL_DMA_ENABLE: Enable the specified DMA Stream.\r
74       (+) __HAL_DMA_DISABLE: Disable the specified DMA Stream.\r
75       (+) __HAL_DMA_GET_FS: Return the current DMA Stream FIFO filled level.\r
76       (+) __HAL_DMA_GET_FLAG: Get the DMA Stream pending flags.\r
77       (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Stream pending flags.\r
78       (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Stream interrupts.\r
79       (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Stream interrupts.\r
80       (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Stream interrupt has occurred or not. \r
81      \r
82      [..] \r
83       (@) You can refer to the DMA HAL driver header file for more useful macros  \r
84   \r
85   @endverbatim\r
86   ******************************************************************************\r
87   * @attention\r
88   *\r
89   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>\r
90   *\r
91   * Redistribution and use in source and binary forms, with or without modification,\r
92   * are permitted provided that the following conditions are met:\r
93   *   1. Redistributions of source code must retain the above copyright notice,\r
94   *      this list of conditions and the following disclaimer.\r
95   *   2. Redistributions in binary form must reproduce the above copyright notice,\r
96   *      this list of conditions and the following disclaimer in the documentation\r
97   *      and/or other materials provided with the distribution.\r
98   *   3. Neither the name of STMicroelectronics nor the names of its contributors\r
99   *      may be used to endorse or promote products derived from this software\r
100   *      without specific prior written permission.\r
101   *\r
102   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
103   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
104   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
105   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
106   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
107   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
108   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
109   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
110   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
111   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
112   *\r
113   ******************************************************************************\r
114   */ \r
115 \r
116 /* Includes ------------------------------------------------------------------*/\r
117 #include "stm32f7xx_hal.h"\r
118 \r
119 /** @addtogroup STM32F7xx_HAL_Driver\r
120   * @{\r
121   */\r
122 \r
123 /** @defgroup DMA DMA\r
124   * @brief DMA HAL module driver\r
125   * @{\r
126   */\r
127 \r
128 #ifdef HAL_DMA_MODULE_ENABLED\r
129 \r
130 /* Private types -------------------------------------------------------------*/\r
131 /* Private variables ---------------------------------------------------------*/\r
132 /* Private constants ---------------------------------------------------------*/\r
133 /** @addtogroup DMA_Private_Constants\r
134  * @{\r
135  */\r
136  #define HAL_TIMEOUT_DMA_ABORT    ((uint32_t)1000)  /* 1s */\r
137 /**\r
138   * @}\r
139   */\r
140 /* Private macros ------------------------------------------------------------*/\r
141 /* Private functions ---------------------------------------------------------*/\r
142 /** @addtogroup DMA_Private_Functions\r
143   * @{\r
144   */\r
145 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);\r
146 /**\r
147   * @brief  Sets the DMA Transfer parameter.\r
148   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains\r
149   *                     the configuration information for the specified DMA Stream.\r
150   * @param  SrcAddress: The source memory Buffer address\r
151   * @param  DstAddress: The destination memory Buffer address\r
152   * @param  DataLength: The length of data to be transferred from source to destination\r
153   * @retval HAL status\r
154   */\r
155 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)\r
156 {\r
157   /* Clear DBM bit */\r
158   hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);\r
159         \r
160   /* Configure DMA Stream data length */\r
161   hdma->Instance->NDTR = DataLength;\r
162 \r
163   /* Peripheral to Memory */\r
164   if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)\r
165   {\r
166     /* Configure DMA Stream destination address */\r
167     hdma->Instance->PAR = DstAddress;\r
168 \r
169     /* Configure DMA Stream source address */\r
170     hdma->Instance->M0AR = SrcAddress;\r
171   }\r
172   /* Memory to Peripheral */\r
173   else\r
174   {\r
175     /* Configure DMA Stream source address */\r
176     hdma->Instance->PAR = SrcAddress;\r
177     \r
178     /* Configure DMA Stream destination address */\r
179     hdma->Instance->M0AR = DstAddress;\r
180   }\r
181 }\r
182 \r
183 /**\r
184   * @}\r
185   */  \r
186   \r
187 /* Exported functions ---------------------------------------------------------*/\r
188 /** @addtogroup DMA_Exported_Functions\r
189   * @{\r
190   */\r
191 \r
192 /** @addtogroup DMA_Exported_Functions_Group1\r
193   *\r
194 @verbatim   \r
195  ===============================================================================\r
196              ##### Initialization and de-initialization functions  #####\r
197  ===============================================================================  \r
198     [..]\r
199     This section provides functions allowing to initialize the DMA Stream source\r
200     and destination addresses, incrementation and data sizes, transfer direction, \r
201     circular/normal mode selection, memory-to-memory mode selection and Stream priority value.\r
202     [..]\r
203     The HAL_DMA_Init() function follows the DMA configuration procedures as described in\r
204     reference manual.  \r
205 \r
206 @endverbatim\r
207   * @{\r
208   */\r
209   \r
210 /**\r
211   * @brief  Initializes the DMA according to the specified\r
212   *         parameters in the DMA_InitTypeDef and create the associated handle.\r
213   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains\r
214   *               the configuration information for the specified DMA Stream.  \r
215   * @retval HAL status\r
216   */\r
217 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)\r
218\r
219   uint32_t tmp = 0;\r
220   \r
221   /* Check the DMA peripheral state */\r
222   if(hdma == NULL)\r
223   {\r
224     return HAL_ERROR;\r
225   }\r
226 \r
227   /* Check the parameters */\r
228   assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));\r
229   assert_param(IS_DMA_CHANNEL(hdma->Init.Channel));\r
230   assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));\r
231   assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));\r
232   assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));\r
233   assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));\r
234   assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));\r
235   assert_param(IS_DMA_MODE(hdma->Init.Mode));\r
236   assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));\r
237   assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode));\r
238   /* Check the memory burst, peripheral burst and FIFO threshold parameters only\r
239      when FIFO mode is enabled */\r
240   if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE)\r
241   {\r
242     assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold));\r
243     assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst));\r
244     assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst));\r
245   }\r
246 \r
247   /* Change DMA peripheral state */\r
248   hdma->State = HAL_DMA_STATE_BUSY;\r
249 \r
250   /* Get the CR register value */\r
251   tmp = hdma->Instance->CR;\r
252 \r
253   /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */\r
254   tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \\r
255                       DMA_SxCR_PL    | DMA_SxCR_MSIZE  | DMA_SxCR_PSIZE  | \\r
256                       DMA_SxCR_MINC  | DMA_SxCR_PINC   | DMA_SxCR_CIRC   | \\r
257                       DMA_SxCR_DIR   | DMA_SxCR_CT     | DMA_SxCR_DBM));\r
258 \r
259   /* Prepare the DMA Stream configuration */\r
260   tmp |=  hdma->Init.Channel             | hdma->Init.Direction        |\r
261           hdma->Init.PeriphInc           | hdma->Init.MemInc           |\r
262           hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |\r
263           hdma->Init.Mode                | hdma->Init.Priority;\r
264 \r
265   /* the Memory burst and peripheral burst are not used when the FIFO is disabled */\r
266   if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)\r
267   {\r
268     /* Get memory burst and peripheral burst */\r
269     tmp |=  hdma->Init.MemBurst | hdma->Init.PeriphBurst;\r
270   }\r
271   \r
272   /* Write to DMA Stream CR register */\r
273   hdma->Instance->CR = tmp;  \r
274 \r
275   /* Get the FCR register value */\r
276   tmp = hdma->Instance->FCR;\r
277 \r
278   /* Clear Direct mode and FIFO threshold bits */\r
279   tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);\r
280 \r
281   /* Prepare the DMA Stream FIFO configuration */\r
282   tmp |= hdma->Init.FIFOMode;\r
283 \r
284   /* the FIFO threshold is not used when the FIFO mode is disabled */\r
285   if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)\r
286   {\r
287     /* Get the FIFO threshold */\r
288     tmp |= hdma->Init.FIFOThreshold;\r
289   }\r
290   \r
291   /* Write to DMA Stream FCR */\r
292   hdma->Instance->FCR = tmp;\r
293 \r
294   /* Initialize the error code */\r
295   hdma->ErrorCode = HAL_DMA_ERROR_NONE;\r
296 \r
297   /* Initialize the DMA state */\r
298   hdma->State = HAL_DMA_STATE_READY;\r
299 \r
300   return HAL_OK;\r
301 }\r
302 \r
303 /**\r
304   * @brief  DeInitializes the DMA peripheral \r
305   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains\r
306   *               the configuration information for the specified DMA Stream.  \r
307   * @retval HAL status\r
308   */\r
309 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)\r
310 {\r
311   /* Check the DMA peripheral state */\r
312   if(hdma == NULL)\r
313   {\r
314     return HAL_ERROR;\r
315   }\r
316   \r
317   /* Check the DMA peripheral state */\r
318   if(hdma->State == HAL_DMA_STATE_BUSY)\r
319   {\r
320      return HAL_ERROR;\r
321   }\r
322 \r
323   /* Disable the selected DMA Streamx */\r
324   __HAL_DMA_DISABLE(hdma);\r
325 \r
326   /* Reset DMA Streamx control register */\r
327   hdma->Instance->CR   = 0;\r
328 \r
329   /* Reset DMA Streamx number of data to transfer register */\r
330   hdma->Instance->NDTR = 0;\r
331 \r
332   /* Reset DMA Streamx peripheral address register */\r
333   hdma->Instance->PAR  = 0;\r
334 \r
335   /* Reset DMA Streamx memory 0 address register */\r
336   hdma->Instance->M0AR = 0;\r
337 \r
338   /* Reset DMA Streamx memory 1 address register */\r
339   hdma->Instance->M1AR = 0;\r
340 \r
341   /* Reset DMA Streamx FIFO control register */\r
342   hdma->Instance->FCR  = (uint32_t)0x00000021;\r
343 \r
344   /* Clear all flags */\r
345   __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));\r
346   __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));\r
347   __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));\r
348   __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));\r
349   __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
350 \r
351   /* Initialize the error code */\r
352   hdma->ErrorCode = HAL_DMA_ERROR_NONE;\r
353 \r
354   /* Initialize the DMA state */\r
355   hdma->State = HAL_DMA_STATE_RESET;\r
356 \r
357   /* Release Lock */\r
358   __HAL_UNLOCK(hdma);\r
359 \r
360   return HAL_OK;\r
361 }\r
362 \r
363 /**\r
364   * @}\r
365   */\r
366 \r
367 /** @addtogroup DMA_Exported_Functions_Group2\r
368   *\r
369 @verbatim   \r
370  ===============================================================================\r
371                       #####  IO operation functions  #####\r
372  ===============================================================================  \r
373     [..]  This section provides functions allowing to:\r
374       (+) Configure the source, destination address and data length and Start DMA transfer\r
375       (+) Configure the source, destination address and data length and \r
376           Start DMA transfer with interrupt\r
377       (+) Abort DMA transfer\r
378       (+) Poll for transfer complete\r
379       (+) Handle DMA interrupt request  \r
380 \r
381 @endverbatim\r
382   * @{\r
383   */\r
384 \r
385 /**\r
386   * @brief  Starts the DMA Transfer.\r
387   * @param  hdma      : pointer to a DMA_HandleTypeDef structure that contains\r
388   *                     the configuration information for the specified DMA Stream.  \r
389   * @param  SrcAddress: The source memory Buffer address\r
390   * @param  DstAddress: The destination memory Buffer address\r
391   * @param  DataLength: The length of data to be transferred from source to destination\r
392   * @retval HAL status\r
393   */\r
394 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)\r
395 {\r
396   /* Process locked */\r
397   __HAL_LOCK(hdma);\r
398 \r
399   /* Change DMA peripheral state */\r
400   hdma->State = HAL_DMA_STATE_BUSY;\r
401 \r
402    /* Check the parameters */\r
403   assert_param(IS_DMA_BUFFER_SIZE(DataLength));\r
404 \r
405   /* Disable the peripheral */\r
406   __HAL_DMA_DISABLE(hdma);\r
407 \r
408   /* Configure the source, destination address and the data length */\r
409   DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);\r
410 \r
411   /* Enable the Peripheral */\r
412   __HAL_DMA_ENABLE(hdma);\r
413 \r
414   return HAL_OK; \r
415 }\r
416 \r
417 /**\r
418   * @brief  Start the DMA Transfer with interrupt enabled.\r
419   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains\r
420   *                     the configuration information for the specified DMA Stream.  \r
421   * @param  SrcAddress: The source memory Buffer address\r
422   * @param  DstAddress: The destination memory Buffer address\r
423   * @param  DataLength: The length of data to be transferred from source to destination\r
424   * @retval HAL status\r
425   */\r
426 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)\r
427 {\r
428   /* Process locked */\r
429   __HAL_LOCK(hdma);\r
430 \r
431   /* Change DMA peripheral state */\r
432   hdma->State = HAL_DMA_STATE_BUSY;\r
433 \r
434    /* Check the parameters */\r
435   assert_param(IS_DMA_BUFFER_SIZE(DataLength));\r
436 \r
437   /* Disable the peripheral */\r
438   __HAL_DMA_DISABLE(hdma);\r
439 \r
440   /* Configure the source, destination address and the data length */\r
441   DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);\r
442 \r
443   /* Enable the transfer complete interrupt */\r
444   __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC);\r
445 \r
446   /* Enable the Half transfer complete interrupt */\r
447   __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);  \r
448 \r
449   /* Enable the transfer Error interrupt */\r
450   __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE);\r
451 \r
452   /* Enable the FIFO Error interrupt */\r
453   __HAL_DMA_ENABLE_IT(hdma, DMA_IT_FE);\r
454 \r
455   /* Enable the direct mode Error interrupt */\r
456   __HAL_DMA_ENABLE_IT(hdma, DMA_IT_DME);\r
457 \r
458    /* Enable the Peripheral */\r
459   __HAL_DMA_ENABLE(hdma);\r
460 \r
461   return HAL_OK;\r
462\r
463 \r
464 /**\r
465   * @brief  Aborts the DMA Transfer.\r
466   * @param  hdma  : pointer to a DMA_HandleTypeDef structure that contains\r
467   *                 the configuration information for the specified DMA Stream.\r
468   *                   \r
469   * @note  After disabling a DMA Stream, a check for wait until the DMA Stream is \r
470   *        effectively disabled is added. If a Stream is disabled \r
471   *        while a data transfer is ongoing, the current data will be transferred\r
472   *        and the Stream will be effectively disabled only after the transfer of\r
473   *        this single data is finished.  \r
474   * @retval HAL status\r
475   */\r
476 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)\r
477 {\r
478   uint32_t tickstart = 0;\r
479 \r
480   /* Disable the stream */\r
481   __HAL_DMA_DISABLE(hdma);\r
482 \r
483   /* Get tick */\r
484   tickstart = HAL_GetTick();\r
485 \r
486   /* Check if the DMA Stream is effectively disabled */\r
487   while((hdma->Instance->CR & DMA_SxCR_EN) != 0)\r
488   {\r
489     /* Check for the Timeout */\r
490     if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)\r
491     {\r
492       /* Update error code */\r
493       hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;\r
494       \r
495       /* Process Unlocked */\r
496       __HAL_UNLOCK(hdma);\r
497       \r
498       /* Change the DMA state */\r
499       hdma->State = HAL_DMA_STATE_TIMEOUT;\r
500       \r
501       return HAL_TIMEOUT;\r
502     }\r
503   }\r
504   /* Process Unlocked */\r
505   __HAL_UNLOCK(hdma);\r
506 \r
507   /* Change the DMA state*/\r
508   hdma->State = HAL_DMA_STATE_READY;\r
509 \r
510   return HAL_OK;\r
511 }\r
512 \r
513 /**\r
514   * @brief  Polling for transfer complete.\r
515   * @param  hdma:          pointer to a DMA_HandleTypeDef structure that contains\r
516   *                        the configuration information for the specified DMA Stream.\r
517   * @param  CompleteLevel: Specifies the DMA level complete.  \r
518   * @param  Timeout:       Timeout duration.\r
519   * @retval HAL status\r
520   */\r
521 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)\r
522 {\r
523   uint32_t temp, tmp, tmp1, tmp2;\r
524   uint32_t tickstart = 0; \r
525 \r
526   /* Get the level transfer complete flag */\r
527   if(CompleteLevel == HAL_DMA_FULL_TRANSFER)\r
528   {\r
529     /* Transfer Complete flag */\r
530     temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);\r
531   }\r
532   else\r
533   {\r
534     /* Half Transfer Complete flag */\r
535     temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);\r
536   }\r
537 \r
538   /* Get tick */\r
539   tickstart = HAL_GetTick();\r
540 \r
541   while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)\r
542   {\r
543     tmp  = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));\r
544     tmp1 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));\r
545     tmp2 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));\r
546     if((tmp != RESET) || (tmp1 != RESET) || (tmp2 != RESET))\r
547     {\r
548       if(tmp != RESET)\r
549       {\r
550         /* Update error code */\r
551         hdma->ErrorCode |= HAL_DMA_ERROR_TE;\r
552 \r
553         /* Clear the transfer error flag */\r
554         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));\r
555       }\r
556       if(tmp1 != RESET)\r
557       {\r
558         /* Update error code */\r
559         hdma->ErrorCode |= HAL_DMA_ERROR_FE;\r
560  \r
561         /* Clear the FIFO error flag */\r
562         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));\r
563       }\r
564       if(tmp2 != RESET)\r
565       {\r
566         /* Update error code */\r
567         hdma->ErrorCode |= HAL_DMA_ERROR_DME;\r
568 \r
569         /* Clear the Direct Mode error flag */\r
570         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));\r
571       }\r
572       /* Change the DMA state */\r
573       hdma->State= HAL_DMA_STATE_ERROR;\r
574       \r
575       /* Process Unlocked */\r
576       __HAL_UNLOCK(hdma);\r
577 \r
578       return HAL_ERROR;\r
579     }  \r
580     /* Check for the Timeout */\r
581     if(Timeout != HAL_MAX_DELAY)\r
582     {\r
583       if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))\r
584       {\r
585         /* Update error code */\r
586         hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;\r
587 \r
588         /* Change the DMA state */\r
589         hdma->State = HAL_DMA_STATE_TIMEOUT;\r
590 \r
591         /* Process Unlocked */\r
592         __HAL_UNLOCK(hdma);\r
593         \r
594         return HAL_TIMEOUT;\r
595       }\r
596     }\r
597   }\r
598 \r
599   if(CompleteLevel == HAL_DMA_FULL_TRANSFER)\r
600   {\r
601     /* Multi_Buffering mode enabled */\r
602     if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)\r
603     {\r
604       /* Clear the half transfer complete flag */\r
605       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
606       /* Clear the transfer complete flag */\r
607       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));\r
608 \r
609       /* Current memory buffer used is Memory 0 */\r
610       if((hdma->Instance->CR & DMA_SxCR_CT) == 0)\r
611       {\r
612         /* Change DMA peripheral state */\r
613         hdma->State = HAL_DMA_STATE_READY_MEM0;\r
614       }\r
615       /* Current memory buffer used is Memory 1 */\r
616       else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)\r
617       {\r
618         /* Change DMA peripheral state */\r
619         hdma->State = HAL_DMA_STATE_READY_MEM1;\r
620       }\r
621     }\r
622     else\r
623     {\r
624       /* Clear the half transfer complete flag */\r
625       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
626       /* Clear the transfer complete flag */\r
627       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); \r
628 \r
629       /* The selected Streamx EN bit is cleared (DMA is disabled and all transfers\r
630          are complete) */\r
631       hdma->State = HAL_DMA_STATE_READY_MEM0;\r
632     }\r
633     /* Process Unlocked */\r
634     __HAL_UNLOCK(hdma);\r
635   }\r
636   else\r
637   { \r
638     /* Multi_Buffering mode enabled */\r
639     if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)\r
640     {\r
641       /* Clear the half transfer complete flag */\r
642       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
643 \r
644       /* Current memory buffer used is Memory 0 */\r
645       if((hdma->Instance->CR & DMA_SxCR_CT) == 0)\r
646       {\r
647         /* Change DMA peripheral state */\r
648         hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;\r
649       }\r
650       /* Current memory buffer used is Memory 1 */\r
651       else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)\r
652       {\r
653         /* Change DMA peripheral state */\r
654         hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;\r
655       }\r
656     }\r
657     else\r
658     {\r
659       /* Clear the half transfer complete flag */\r
660       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
661 \r
662       /* Change DMA peripheral state */\r
663       hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;\r
664     }\r
665   }\r
666   return HAL_OK;\r
667 }\r
668 \r
669 /**\r
670   * @brief  Handles DMA interrupt request.\r
671   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains\r
672   *               the configuration information for the specified DMA Stream.  \r
673   * @retval None\r
674   */\r
675 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)\r
676 {\r
677   /* Transfer Error Interrupt management ***************************************/\r
678   if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)\r
679   {\r
680     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)\r
681     {\r
682       /* Disable the transfer error interrupt */\r
683       __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);\r
684 \r
685       /* Clear the transfer error flag */\r
686       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));\r
687 \r
688       /* Update error code */\r
689       hdma->ErrorCode |= HAL_DMA_ERROR_TE;\r
690 \r
691       /* Change the DMA state */\r
692       hdma->State = HAL_DMA_STATE_ERROR;\r
693 \r
694       /* Process Unlocked */\r
695       __HAL_UNLOCK(hdma); \r
696 \r
697       if(hdma->XferErrorCallback != NULL)\r
698       {\r
699         /* Transfer error callback */\r
700         hdma->XferErrorCallback(hdma);\r
701       }\r
702     }\r
703   }\r
704   /* FIFO Error Interrupt management ******************************************/\r
705   if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)) != RESET)\r
706   {\r
707     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)\r
708     {\r
709       /* Disable the FIFO Error interrupt */\r
710       __HAL_DMA_DISABLE_IT(hdma, DMA_IT_FE);\r
711 \r
712       /* Clear the FIFO error flag */\r
713       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));\r
714 \r
715       /* Update error code */\r
716       hdma->ErrorCode |= HAL_DMA_ERROR_FE;\r
717 \r
718       /* Change the DMA state */\r
719       hdma->State = HAL_DMA_STATE_ERROR;\r
720 \r
721       /* Process Unlocked */\r
722       __HAL_UNLOCK(hdma);\r
723 \r
724       if(hdma->XferErrorCallback != NULL)\r
725       {\r
726         /* Transfer error callback */\r
727         hdma->XferErrorCallback(hdma);\r
728       }\r
729     }\r
730   }\r
731   /* Direct Mode Error Interrupt management ***********************************/\r
732   if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)) != RESET)\r
733   {\r
734     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)\r
735     {\r
736       /* Disable the direct mode Error interrupt */\r
737       __HAL_DMA_DISABLE_IT(hdma, DMA_IT_DME);\r
738 \r
739       /* Clear the direct mode error flag */\r
740       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));\r
741 \r
742       /* Update error code */\r
743       hdma->ErrorCode |= HAL_DMA_ERROR_DME;\r
744 \r
745       /* Change the DMA state */\r
746       hdma->State = HAL_DMA_STATE_ERROR;\r
747 \r
748       /* Process Unlocked */\r
749       __HAL_UNLOCK(hdma);\r
750 \r
751       if(hdma->XferErrorCallback != NULL)\r
752       {\r
753         /* Transfer error callback */\r
754         hdma->XferErrorCallback(hdma);\r
755       }\r
756     }\r
757   }\r
758   /* Half Transfer Complete Interrupt management ******************************/\r
759   if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)\r
760   {\r
761     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)\r
762     { \r
763       /* Multi_Buffering mode enabled */\r
764       if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)\r
765       {\r
766         /* Clear the half transfer complete flag */\r
767         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
768 \r
769         /* Current memory buffer used is Memory 0 */\r
770         if((hdma->Instance->CR & DMA_SxCR_CT) == 0)\r
771         {\r
772           /* Change DMA peripheral state */\r
773           hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;\r
774         }\r
775         /* Current memory buffer used is Memory 1 */\r
776         else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)\r
777         {\r
778           /* Change DMA peripheral state */\r
779           hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;\r
780         }\r
781       }\r
782       else\r
783       {\r
784         /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */\r
785         if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)\r
786         {\r
787           /* Disable the half transfer interrupt */\r
788           __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);\r
789         }\r
790         /* Clear the half transfer complete flag */\r
791         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));\r
792 \r
793         /* Change DMA peripheral state */\r
794         hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;\r
795       }\r
796 \r
797       if(hdma->XferHalfCpltCallback != NULL)\r
798       {\r
799         /* Half transfer callback */\r
800         hdma->XferHalfCpltCallback(hdma);\r
801       }\r
802     }\r
803   }\r
804   /* Transfer Complete Interrupt management ***********************************/\r
805   if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)\r
806   {\r
807     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)\r
808     {\r
809       if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)\r
810       {\r
811         /* Clear the transfer complete flag */\r
812         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));\r
813 \r
814         /* Current memory buffer used is Memory 1 */\r
815         if((hdma->Instance->CR & DMA_SxCR_CT) == 0)\r
816         {\r
817           if(hdma->XferM1CpltCallback != NULL)\r
818           {\r
819             /* Transfer complete Callback for memory1 */\r
820             hdma->XferM1CpltCallback(hdma);\r
821           }\r
822         }\r
823         /* Current memory buffer used is Memory 0 */\r
824         else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) \r
825         {\r
826           if(hdma->XferCpltCallback != NULL)\r
827           {\r
828             /* Transfer complete Callback for memory0 */\r
829             hdma->XferCpltCallback(hdma);\r
830           }\r
831         }\r
832       }\r
833       /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */\r
834       else\r
835       {\r
836         if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)\r
837         {\r
838           /* Disable the transfer complete interrupt */\r
839           __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);\r
840         }\r
841         /* Clear the transfer complete flag */\r
842         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));\r
843 \r
844         /* Update error code */\r
845         hdma->ErrorCode |= HAL_DMA_ERROR_NONE;\r
846 \r
847         /* Change the DMA state */\r
848         hdma->State = HAL_DMA_STATE_READY_MEM0;\r
849 \r
850         /* Process Unlocked */\r
851         __HAL_UNLOCK(hdma);      \r
852 \r
853         if(hdma->XferCpltCallback != NULL)\r
854         {\r
855           /* Transfer complete callback */\r
856           hdma->XferCpltCallback(hdma);\r
857         }\r
858       }\r
859     }\r
860   }\r
861 }\r
862 \r
863 /**\r
864   * @}\r
865   */\r
866 \r
867 /** @addtogroup DMA_Exported_Functions_Group3\r
868   *\r
869 @verbatim\r
870  ===============================================================================\r
871                     ##### State and Errors functions #####\r
872  ===============================================================================\r
873     [..]\r
874     This subsection provides functions allowing to\r
875       (+) Check the DMA state\r
876       (+) Get error code\r
877 \r
878 @endverbatim\r
879   * @{\r
880   */\r
881 \r
882 /**\r
883   * @brief  Returns the DMA state.\r
884   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains\r
885   *               the configuration information for the specified DMA Stream.\r
886   * @retval HAL state\r
887   */\r
888 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)\r
889 {\r
890   return hdma->State;\r
891 }\r
892 \r
893 /**\r
894   * @brief  Return the DMA error code\r
895   * @param  hdma : pointer to a DMA_HandleTypeDef structure that contains\r
896   *              the configuration information for the specified DMA Stream.\r
897   * @retval DMA Error Code\r
898   */\r
899 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)\r
900 {\r
901   return hdma->ErrorCode;\r
902 }\r
903 \r
904 /**\r
905   * @}\r
906   */\r
907 \r
908 /**\r
909   * @}\r
910   */\r
911 \r
912 #endif /* HAL_DMA_MODULE_ENABLED */\r
913 /**\r
914   * @}\r
915   */\r
916 \r
917 /**\r
918   * @}\r
919   */\r
920 \r
921 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r