1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_hal_dma.c
4   * @author  MCD Application Team
5   * @brief   DMA HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Direct Memory Access (DMA) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral State and errors functions
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2019 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   @verbatim
24   ==============================================================================
25                         ##### How to use this driver #####
26   ==============================================================================
27   [..]
28    (#) Enable and configure the peripheral to be connected to the DMA Channel
29        (except for internal SRAM / FLASH memories: no initialization is
30        necessary). Please refer to the Reference manual for connection between peripherals
31        and DMA requests.
32 
33    (#) For a given Channel, program the required configuration through the following parameters:
34        Channel request, Transfer Direction, Source and Destination data formats,
35        Circular or Normal mode, Channel Priority level, Source and Destination Increment mode
36        using HAL_DMA_Init() function.
37 
38        Prior to HAL_DMA_Init the peripheral clock shall be enabled for both DMA & DMAMUX
39        thanks to:
40       (##) DMA1 or DMA2: __HAL_RCC_DMA1_CLK_ENABLE() or  __HAL_RCC_DMA2_CLK_ENABLE() ;
41       (##) DMAMUX1:      __HAL_RCC_DMAMUX1_CLK_ENABLE();
42 
43    (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
44        detection.
45 
46    (#) Use HAL_DMA_Abort() function to abort the current transfer
47 
48      -@-   In Memory-to-Memory transfer mode, Circular mode is not allowed.
49 
50      *** Polling mode IO operation ***
51      =================================
52      [..]
53        (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
54            address and destination address and the Length of data to be transferred
55        (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
56            case a fixed Timeout can be configured by User depending from his application.
57 
58      *** Interrupt mode IO operation ***
59      ===================================
60      [..]
61        (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
62        (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
63        (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
64            Source address and destination address and the Length of data to be transferred.
65            In this case the DMA interrupt is configured
66        (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
67        (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
68               add his own function to register callbacks with HAL_DMA_RegisterCallback().
69 
70      *** DMA HAL driver macros list ***
71      =============================================
72      [..]
73        Below the list of macros in DMA HAL driver.
74 
75        (+) __HAL_DMA_ENABLE: Enable the specified DMA Channel.
76        (+) __HAL_DMA_DISABLE: Disable the specified DMA Channel.
77        (+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags.
78        (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
79        (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
80        (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
81        (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt is enabled or not.
82 
83      [..]
84       (@) You can refer to the DMA HAL driver header file for more useful macros
85 
86   @endverbatim
87   ******************************************************************************
88   */
89 
90 /* Includes ------------------------------------------------------------------*/
91 #include "stm32l5xx_hal.h"
92 
93 /** @addtogroup STM32L5xx_HAL_Driver
94   * @{
95   */
96 
97 /** @defgroup DMA DMA
98   * @brief DMA HAL module driver
99   * @{
100   */
101 
102 #ifdef HAL_DMA_MODULE_ENABLED
103 
104 /* Private typedef -----------------------------------------------------------*/
105 /* Private define ------------------------------------------------------------*/
106 /* Private macro -------------------------------------------------------------*/
107 /* Private variables ---------------------------------------------------------*/
108 /* Private function prototypes -----------------------------------------------*/
109 /** @defgroup DMA_Private_Functions DMA Private Functions
110   * @{
111   */
112 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
113 static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma);
114 static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma);
115 /**
116   * @}
117   */
118 
119 /* Exported functions ---------------------------------------------------------*/
120 
121 /** @defgroup DMA_Exported_Functions DMA Exported Functions
122   * @{
123   */
124 
125 /** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
126  *  @brief   Initialization and de-initialization functions
127  *
128 @verbatim
129  ===============================================================================
130              ##### Initialization and de-initialization functions  #####
131  ===============================================================================
132     [..]
133     This section provides functions allowing to initialize the DMA Channel source
134     and destination addresses, incrementation and data sizes, transfer direction,
135     circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
136     [..]
137     The HAL_DMA_Init() function follows the DMA configuration procedures as described in
138     reference manual.
139 
140 @endverbatim
141   * @{
142   */
143 
144 /**
145   * @brief  Initialize the DMA according to the specified
146   *         parameters in the DMA_InitTypeDef and initialize the associated handle.
147   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
148   *              the configuration information for the specified DMA Channel.
149   * @retval HAL status
150   */
HAL_DMA_Init(DMA_HandleTypeDef * hdma)151 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
152 {
153   uint32_t tmp;
154 
155   /* Check the DMA handle allocation */
156   if(hdma == NULL)
157   {
158     return HAL_ERROR;
159   }
160 
161   /* Check the parameters */
162   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
163   assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
164   assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
165   assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
166   assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
167   assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
168   assert_param(IS_DMA_MODE(hdma->Init.Mode));
169   assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
170 
171   assert_param(IS_DMA_ALL_REQUEST(hdma->Init.Request));
172 
173   /* Compute the channel index */
174   if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
175   {
176     /* DMA1 */
177     hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U;
178     hdma->DmaBaseAddress = DMA1;
179   }
180   else
181   {
182     /* DMA2 */
183     hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2U;
184     hdma->DmaBaseAddress = DMA2;
185   }
186 
187   /* Change DMA peripheral state */
188   hdma->State = HAL_DMA_STATE_BUSY;
189 
190   /* Get the CR register value */
191   tmp = hdma->Instance->CCR;
192 
193   /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, MEM2MEM, CT and DBM bits */
194   tmp &= ((uint32_t)~(DMA_CCR_PL    | DMA_CCR_MSIZE   | DMA_CCR_PSIZE  |
195                       DMA_CCR_MINC  | DMA_CCR_PINC    | DMA_CCR_CIRC   |
196                       DMA_CCR_DIR   | DMA_CCR_MEM2MEM | DMA_CCR_CT     |
197                       DMA_CCR_DBM));
198 
199   /* Prepare the DMA Channel configuration */
200   tmp |=  hdma->Init.Direction        |
201           hdma->Init.PeriphInc           | hdma->Init.MemInc           |
202           hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
203           hdma->Init.Mode                | hdma->Init.Priority;
204 
205   /* Write to DMA Channel CR register */
206   hdma->Instance->CCR = tmp;
207 
208   /* Initialize parameters for DMAMUX channel :
209      DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask
210   */
211   DMA_CalcDMAMUXChannelBaseAndMask(hdma);
212 
213   if(hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
214   {
215     /* if memory to memory force the request to 0*/
216     hdma->Init.Request = DMA_REQUEST_MEM2MEM;
217   }
218 
219   /* Set peripheral request  to DMAMUX channel */
220   hdma->DMAmuxChannel->CCR = (hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID);
221 
222   /* Clear the DMAMUX synchro overrun flag */
223   hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
224 
225   if(((hdma->Init.Request > 0U) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR3)))
226   {
227     /* Initialize parameters for DMAMUX request generator :
228        DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask
229     */
230     DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
231 
232     /* Reset the DMAMUX request generator register*/
233     hdma->DMAmuxRequestGen->RGCR = 0U;
234 
235     /* Clear the DMAMUX request generator overrun flag */
236     hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
237   }
238   else
239   {
240     hdma->DMAmuxRequestGen = 0U;
241     hdma->DMAmuxRequestGenStatus = 0U;
242     hdma->DMAmuxRequestGenStatusMask = 0U;
243   }
244 
245   /* Initialise the error code */
246   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
247 
248   /* Initialize the DMA state*/
249   hdma->State = HAL_DMA_STATE_READY;
250 
251   /* Allocate lock resource and initialize it */
252   hdma->Lock = HAL_UNLOCKED;
253 
254   return HAL_OK;
255 }
256 
257 /**
258   * @brief  DeInitialize the DMA peripheral.
259   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
260   *               the configuration information for the specified DMA Channel.
261   * @retval HAL status
262   */
HAL_DMA_DeInit(DMA_HandleTypeDef * hdma)263 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
264 {
265 
266   /* Check the DMA handle allocation */
267   if (NULL == hdma )
268   {
269     return HAL_ERROR;
270   }
271 
272   /* Check the parameters */
273   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
274 
275   /* Disable the selected DMA Channelx */
276   __HAL_DMA_DISABLE(hdma);
277 
278   /* Compute the channel index */
279   if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
280   {
281     /* DMA1 */
282     hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U;
283     hdma->DmaBaseAddress = DMA1;
284   }
285   else
286   {
287     /* DMA2 */
288     hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2U;
289     hdma->DmaBaseAddress = DMA2;
290   }
291 
292   /* Reset DMA Channel control register */
293   hdma->Instance->CCR = 0U;
294 
295   /* Clear all flags */
296   hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
297 
298   /* Initialize parameters for DMAMUX channel :
299      DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask */
300 
301   DMA_CalcDMAMUXChannelBaseAndMask(hdma);
302 
303   /* Reset the DMAMUX channel that corresponds to the DMA channel */
304   hdma->DMAmuxChannel->CCR = 0U;
305 
306   /* Clear the DMAMUX synchro overrun flag */
307   hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
308 
309   /* Reset Request generator parameters if any */
310   if(((hdma->Init.Request >  0U) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR3)))
311   {
312     /* Initialize parameters for DMAMUX request generator :
313        DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask
314     */
315     DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
316 
317     /* Reset the DMAMUX request generator register*/
318     hdma->DMAmuxRequestGen->RGCR = 0U;
319 
320     /* Clear the DMAMUX request generator overrun flag */
321     hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
322   }
323 
324   hdma->DMAmuxRequestGen = 0U;
325   hdma->DMAmuxRequestGenStatus = 0U;
326   hdma->DMAmuxRequestGenStatusMask = 0U;
327 
328   /* Clean callbacks */
329   hdma->XferCpltCallback = NULL;
330   hdma->XferHalfCpltCallback = NULL;
331   hdma->XferM1CpltCallback = NULL;
332   hdma->XferM1HalfCpltCallback = NULL;
333   hdma->XferErrorCallback = NULL;
334   hdma->XferAbortCallback = NULL;
335 
336   /* Initialise the error code */
337   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
338 
339   /* Initialize the DMA state */
340   hdma->State = HAL_DMA_STATE_RESET;
341 
342   /* Release Lock */
343   __HAL_UNLOCK(hdma);
344 
345   return HAL_OK;
346 }
347 
348 /**
349   * @}
350   */
351 
352 /** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
353  *  @brief   Input and Output operation functions
354  *
355 @verbatim
356  ===============================================================================
357                       #####  IO operation functions  #####
358  ===============================================================================
359     [..]  This section provides functions allowing to:
360       (+) Configure the source, destination address and data length and Start DMA transfer
361       (+) Configure the source, destination address and data length and
362           Start DMA transfer with interrupt
363       (+) Abort DMA transfer
364       (+) Poll for transfer complete
365       (+) Handle DMA interrupt request
366 
367 @endverbatim
368   * @{
369   */
370 
371 /**
372   * @brief  Start the DMA Transfer.
373   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
374   *               the configuration information for the specified DMA Channel.
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   */
HAL_DMA_Start(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)380 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
381 {
382   HAL_StatusTypeDef status = HAL_OK;
383 
384   /* Check the parameters */
385   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
386 
387   /* Process locked */
388   __HAL_LOCK(hdma);
389 
390   if(HAL_DMA_STATE_READY == hdma->State)
391   {
392     /* Change DMA peripheral state */
393     hdma->State = HAL_DMA_STATE_BUSY;
394     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
395 
396     /* Disable the peripheral */
397     __HAL_DMA_DISABLE(hdma);
398 
399     /* Configure the source, destination address and the data length & clear flags*/
400     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
401 
402     /* Enable the Peripheral */
403     __HAL_DMA_ENABLE(hdma);
404   }
405   else
406   {
407     /* Process Unlocked */
408     __HAL_UNLOCK(hdma);
409     status = HAL_BUSY;
410   }
411   return status;
412 }
413 
414 /**
415   * @brief  Start the DMA Transfer with interrupt enabled.
416   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
417   *               the configuration information for the specified DMA Channel.
418   * @param  SrcAddress The source memory Buffer address
419   * @param  DstAddress The destination memory Buffer address
420   * @param  DataLength The length of data to be transferred from source to destination
421   * @retval HAL status
422   */
HAL_DMA_Start_IT(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)423 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
424 {
425   HAL_StatusTypeDef status = HAL_OK;
426 
427   /* Check the parameters */
428   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
429 
430   /* Process locked */
431   __HAL_LOCK(hdma);
432 
433   if(HAL_DMA_STATE_READY == hdma->State)
434   {
435     /* Change DMA peripheral state */
436     hdma->State = HAL_DMA_STATE_BUSY;
437     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
438 
439     /* Disable the peripheral */
440     __HAL_DMA_DISABLE(hdma);
441 
442     /* Configure the source, destination address and the data length & clear flags*/
443     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
444 
445     /* Enable the transfer complete interrupt */
446     /* Enable the transfer Error interrupt */
447     if(NULL != hdma->XferHalfCpltCallback )
448     {
449       /* Enable the Half transfer complete interrupt as well */
450       __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
451     }
452     else
453     {
454       __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
455       __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
456     }
457 
458     /* Check if DMAMUX Synchronization is enabled*/
459     if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
460     {
461       /* Enable DMAMUX sync overrun IT*/
462       hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
463     }
464 
465     if(hdma->DMAmuxRequestGen != 0U)
466     {
467       /* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/
468       /* enable the request gen overrun IT*/
469       hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
470     }
471 
472     /* Enable the Peripheral */
473     __HAL_DMA_ENABLE(hdma);
474   }
475   else
476   {
477     /* Process Unlocked */
478     __HAL_UNLOCK(hdma);
479 
480     /* Remain BUSY */
481     status = HAL_BUSY;
482   }
483   return status;
484 }
485 
486 /**
487   * @brief  Abort the DMA Transfer.
488   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
489   *               the configuration information for the specified DMA Channel.
490     * @retval HAL status
491   */
HAL_DMA_Abort(DMA_HandleTypeDef * hdma)492 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
493 {
494   HAL_StatusTypeDef status = HAL_OK;
495 
496   /* Check the DMA peripheral state */
497   if(hdma->State != HAL_DMA_STATE_BUSY)
498   {
499     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
500 
501     /* Process Unlocked */
502     __HAL_UNLOCK(hdma);
503 
504     return HAL_ERROR;
505   }
506   else
507   {
508     /* Disable DMA IT */
509     __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
510 
511     /* disable the DMAMUX sync overrun IT*/
512     hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
513 
514     /* Disable the channel */
515     __HAL_DMA_DISABLE(hdma);
516 
517     /* Clear all flags */
518     hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
519 
520     /* Clear the DMAMUX synchro overrun flag */
521     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
522 
523     if(hdma->DMAmuxRequestGen != 0U)
524     {
525       /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
526       /* disable the request gen overrun IT*/
527       hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
528 
529       /* Clear the DMAMUX request generator overrun flag */
530       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
531     }
532 
533     /* Change the DMA state */
534     hdma->State = HAL_DMA_STATE_READY;
535 
536     /* Process Unlocked */
537     __HAL_UNLOCK(hdma);
538 
539     return status;
540   }
541 }
542 
543 /**
544   * @brief  Aborts the DMA Transfer in Interrupt mode.
545   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
546   *                 the configuration information for the specified DMA Channel.
547   * @retval HAL status
548   */
HAL_DMA_Abort_IT(DMA_HandleTypeDef * hdma)549 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
550 {
551   HAL_StatusTypeDef status = HAL_OK;
552 
553   if(HAL_DMA_STATE_BUSY != hdma->State)
554   {
555     /* no transfer ongoing */
556     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
557 
558     status = HAL_ERROR;
559   }
560   else
561   {
562     /* Disable DMA IT */
563     __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
564 
565     /* Disable the channel */
566     __HAL_DMA_DISABLE(hdma);
567 
568     /* disable the DMAMUX sync overrun IT*/
569     hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
570 
571     /* Clear all flags */
572     hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
573 
574     /* Clear the DMAMUX synchro overrun flag */
575     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
576 
577     if(hdma->DMAmuxRequestGen != 0U)
578     {
579       /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
580       /* disable the request gen overrun IT*/
581       hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
582 
583       /* Clear the DMAMUX request generator overrun flag */
584       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
585     }
586 
587     /* Change the DMA state */
588     hdma->State = HAL_DMA_STATE_READY;
589 
590     /* Process Unlocked */
591     __HAL_UNLOCK(hdma);
592 
593     /* Call User Abort callback */
594     if(hdma->XferAbortCallback != NULL)
595     {
596       hdma->XferAbortCallback(hdma);
597     }
598   }
599   return status;
600 }
601 
602 /**
603   * @brief  Polling for transfer complete.
604   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
605   *                  the configuration information for the specified DMA Channel.
606   * @param  CompleteLevel Specifies the DMA level complete.
607   * @param  Timeout       Timeout duration.
608   * @retval HAL status
609   */
HAL_DMA_PollForTransfer(DMA_HandleTypeDef * hdma,HAL_DMA_LevelCompleteTypeDef CompleteLevel,uint32_t Timeout)610 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
611 {
612   uint32_t temp;
613   uint32_t tickstart;
614 
615   if(HAL_DMA_STATE_BUSY != hdma->State)
616   {
617     /* no transfer ongoing */
618     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
619     __HAL_UNLOCK(hdma);
620     return HAL_ERROR;
621   }
622 
623   /* Polling mode not supported in circular mode */
624   if ((hdma->Instance->CCR & DMA_CCR_CIRC) != 0U)
625   {
626     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
627     return HAL_ERROR;
628   }
629 
630   /* Get the level transfer complete flag */
631   if (HAL_DMA_FULL_TRANSFER == CompleteLevel)
632   {
633     /* Transfer Complete flag */
634     temp = DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1CU);
635   }
636   else
637   {
638     /* Half Transfer Complete flag */
639     temp = DMA_FLAG_HT1 << (hdma->ChannelIndex & 0x1CU);
640   }
641 
642   /* Get tick */
643   tickstart = HAL_GetTick();
644 
645   while((hdma->DmaBaseAddress->ISR & temp) == 0U)
646   {
647     if((hdma->DmaBaseAddress->ISR & (DMA_FLAG_TE1 << (hdma->ChannelIndex& 0x1CU))) != 0U)
648     {
649       /* When a DMA transfer error occurs */
650       /* A hardware clear of its EN bits is performed */
651       /* Clear all flags */
652       hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
653 
654       /* Update error code */
655       hdma->ErrorCode = HAL_DMA_ERROR_TE;
656 
657       /* Change the DMA state */
658       hdma->State= HAL_DMA_STATE_READY;
659 
660       /* Process Unlocked */
661       __HAL_UNLOCK(hdma);
662 
663       return HAL_ERROR;
664     }
665     /* Check for the Timeout */
666     if(Timeout != HAL_MAX_DELAY)
667     {
668       if(((HAL_GetTick() - tickstart) > Timeout) ||  (Timeout == 0U))
669       {
670         /* Update error code */
671         hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
672 
673         /* Change the DMA state */
674         hdma->State = HAL_DMA_STATE_READY;
675 
676         /* Process Unlocked */
677         __HAL_UNLOCK(hdma);
678 
679         return HAL_ERROR;
680       }
681     }
682   }
683 
684   /*Check for DMAMUX Request generator (if used) overrun status */
685   if(hdma->DMAmuxRequestGen != 0U)
686   {
687     /* if using DMAMUX request generator Check for DMAMUX request generator overrun */
688     if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
689     {
690       /* Disable the request gen overrun interrupt */
691       hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
692 
693       /* Clear the DMAMUX request generator overrun flag */
694       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
695 
696       /* Update error code */
697       hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
698     }
699   }
700 
701   /* Check for DMAMUX Synchronization overrun */
702   if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
703   {
704     /* Clear the DMAMUX synchro overrun flag */
705     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
706 
707     /* Update error code */
708     hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
709   }
710 
711   if(HAL_DMA_FULL_TRANSFER == CompleteLevel)
712   {
713     /* Clear the transfer complete flag */
714     hdma->DmaBaseAddress->IFCR = (DMA_FLAG_TC1 << (hdma->ChannelIndex& 0x1CU));
715 
716     /* Process unlocked */
717     __HAL_UNLOCK(hdma);
718 
719     /* The selected Channelx EN bit is cleared (DMA is disabled and
720     all transfers are complete) */
721     hdma->State = HAL_DMA_STATE_READY;
722   }
723   else
724   {
725     /* Clear the half transfer complete flag */
726     hdma->DmaBaseAddress->IFCR = (DMA_FLAG_HT1 << (hdma->ChannelIndex & 0x1CU));
727   }
728 
729   return HAL_OK;
730 }
731 
732 /**
733   * @brief  Handle DMA interrupt request.
734   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
735   *               the configuration information for the specified DMA Channel.
736   * @retval None
737   */
HAL_DMA_IRQHandler(DMA_HandleTypeDef * hdma)738 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
739 {
740   uint32_t flag_it = hdma->DmaBaseAddress->ISR;
741   uint32_t source_it = hdma->Instance->CCR;
742 
743   /* Half Transfer Complete Interrupt management ******************************/
744   if (((flag_it & (DMA_FLAG_HT1 << (hdma->ChannelIndex & 0x1CU))) != 0U) && ((source_it & DMA_IT_HT) != 0U))
745   {
746     /* Multi_Buffering mode enabled */
747     if(((hdma->Instance->CCR) & (uint32_t)(DMA_CCR_DBM)) != 0U)
748     {
749       /* Clear the half transfer complete flag */
750       hdma->DmaBaseAddress->IFCR = DMA_ISR_HTIF1 << (hdma->ChannelIndex & 0x1CU);
751 
752       /* Current memory buffer used is Memory 0 */
753       if((hdma->Instance->CCR & DMA_CCR_CT) == 0U)
754       {
755         if(hdma->XferHalfCpltCallback != NULL)
756         {
757           /* Half transfer callback */
758           hdma->XferHalfCpltCallback(hdma);
759         }
760       }
761       /* Current memory buffer used is Memory 1 */
762       else
763       {
764         if(hdma->XferM1HalfCpltCallback != NULL)
765         {
766           /* Half transfer callback */
767           hdma->XferM1HalfCpltCallback(hdma);
768         }
769       }
770     }
771     else
772     {
773       /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
774       if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
775       {
776         /* Disable the half transfer interrupt */
777         __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
778       }
779       /* Clear the half transfer complete flag */
780       hdma->DmaBaseAddress->IFCR = DMA_ISR_HTIF1 << (hdma->ChannelIndex & 0x1CU);
781 
782       /* DMA peripheral state is not updated in Half Transfer */
783       /* but in Transfer Complete case */
784 
785       if(hdma->XferHalfCpltCallback != NULL)
786       {
787         /* Half transfer callback */
788         hdma->XferHalfCpltCallback(hdma);
789       }
790     }
791   }
792 
793   /* Transfer Complete Interrupt management ***********************************/
794   else if (((flag_it & (DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1CU))) != 0U) && ((source_it & DMA_IT_TC) != 0U))
795   {
796     if(((hdma->Instance->CCR) & (uint32_t)(DMA_CCR_DBM)) != 0U)
797     {
798       /* Current memory buffer used is Memory 0 */
799       if((hdma->Instance->CCR & DMA_CCR_CT) == 0U)
800       {
801         if(hdma->XferM1CpltCallback != NULL)
802         {
803           /* Transfer complete Callback for memory1 */
804           hdma->XferM1CpltCallback(hdma);
805         }
806       }
807       /* Current memory buffer used is Memory 1 */
808       else
809       {
810         if(hdma->XferCpltCallback != NULL)
811         {
812           /* Transfer complete Callback for memory0 */
813           hdma->XferCpltCallback(hdma);
814         }
815       }
816     }
817     else
818     {
819       if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
820       {
821         /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
822         /* Disable the transfer complete and error interrupt */
823         /* if the DMA mode is not CIRCULAR  */
824         __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
825 
826         /* Change the DMA state */
827         hdma->State = HAL_DMA_STATE_READY;
828       }
829       /* Clear the transfer complete flag */
830       hdma->DmaBaseAddress->IFCR = (DMA_ISR_TCIF1 << (hdma->ChannelIndex & 0x1CU));
831 
832       /* Process Unlocked */
833       __HAL_UNLOCK(hdma);
834 
835       if(hdma->XferCpltCallback != NULL)
836       {
837         /* Transfer complete callback */
838         hdma->XferCpltCallback(hdma);
839       }
840     }
841   }
842 
843   /* Transfer Error Interrupt management **************************************/
844   else if (((flag_it & (DMA_FLAG_TE1 << (hdma->ChannelIndex & 0x1CU))) != 0U) && ((source_it & DMA_IT_TE) !=  0U))
845   {
846     /* When a DMA transfer error occurs */
847     /* A hardware clear of its EN bits is performed */
848     /* Disable ALL DMA IT */
849     __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
850 
851     /* Clear all flags */
852     hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
853 
854     /* Update error code */
855     hdma->ErrorCode = HAL_DMA_ERROR_TE;
856 
857     /* Change the DMA state */
858     hdma->State = HAL_DMA_STATE_READY;
859 
860     /* Process Unlocked */
861     __HAL_UNLOCK(hdma);
862 
863     if (hdma->XferErrorCallback != NULL)
864     {
865       /* Transfer error callback */
866       hdma->XferErrorCallback(hdma);
867     }
868   }
869   else
870   {
871     /* Nothing To Do */
872   }
873   return;
874 }
875 
876 /**
877   * @brief  Register callbacks
878   * @param  hdma                 pointer to a DMA_HandleTypeDef structure that contains
879   *                               the configuration information for the specified DMA Channel.
880   * @param  CallbackID           User Callback identifier
881   *                               a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
882   * @param  pCallback            pointer to private callbacsk function which has pointer to
883   *                               a DMA_HandleTypeDef structure as parameter.
884   * @retval HAL status
885   */
HAL_DMA_RegisterCallback(DMA_HandleTypeDef * hdma,HAL_DMA_CallbackIDTypeDef CallbackID,void (* pCallback)(DMA_HandleTypeDef * _hdma))886 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma))
887 {
888   HAL_StatusTypeDef status = HAL_OK;
889 
890   /* Process locked */
891   __HAL_LOCK(hdma);
892 
893   if(HAL_DMA_STATE_READY == hdma->State)
894   {
895     switch (CallbackID)
896     {
897      case  HAL_DMA_XFER_CPLT_CB_ID:
898            hdma->XferCpltCallback = pCallback;
899            break;
900 
901      case  HAL_DMA_XFER_HALFCPLT_CB_ID:
902            hdma->XferHalfCpltCallback = pCallback;
903            break;
904 
905      case  HAL_DMA_XFER_M1CPLT_CB_ID:
906            hdma->XferM1CpltCallback = pCallback;
907            break;
908 
909      case  HAL_DMA_XFER_M1HALFCPLT_CB_ID:
910            hdma->XferM1HalfCpltCallback = pCallback;
911            break;
912 
913      case  HAL_DMA_XFER_ERROR_CB_ID:
914            hdma->XferErrorCallback = pCallback;
915            break;
916 
917      case  HAL_DMA_XFER_ABORT_CB_ID:
918            hdma->XferAbortCallback = pCallback;
919            break;
920 
921      default:
922            status = HAL_ERROR;
923            break;
924     }
925   }
926   else
927   {
928     status = HAL_ERROR;
929   }
930 
931   /* Release Lock */
932   __HAL_UNLOCK(hdma);
933 
934   return status;
935 }
936 
937 /**
938   * @brief  UnRegister callbacks
939   * @param  hdma                 pointer to a DMA_HandleTypeDef structure that contains
940   *                               the configuration information for the specified DMA Channel.
941   * @param  CallbackID           User Callback identifier
942   *                               a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
943   * @retval HAL status
944   */
HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef * hdma,HAL_DMA_CallbackIDTypeDef CallbackID)945 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
946 {
947   HAL_StatusTypeDef status = HAL_OK;
948 
949     /* Process locked */
950   __HAL_LOCK(hdma);
951 
952   if(HAL_DMA_STATE_READY == hdma->State)
953   {
954     switch (CallbackID)
955     {
956      case  HAL_DMA_XFER_CPLT_CB_ID:
957            hdma->XferCpltCallback = NULL;
958            break;
959 
960      case  HAL_DMA_XFER_HALFCPLT_CB_ID:
961            hdma->XferHalfCpltCallback = NULL;
962            break;
963 
964      case  HAL_DMA_XFER_M1CPLT_CB_ID:
965            hdma->XferM1CpltCallback = NULL;
966            break;
967 
968      case  HAL_DMA_XFER_M1HALFCPLT_CB_ID:
969            hdma->XferM1HalfCpltCallback = NULL;
970            break;
971 
972      case  HAL_DMA_XFER_ERROR_CB_ID:
973            hdma->XferErrorCallback = NULL;
974            break;
975 
976      case  HAL_DMA_XFER_ABORT_CB_ID:
977            hdma->XferAbortCallback = NULL;
978            break;
979 
980     case   HAL_DMA_XFER_ALL_CB_ID:
981            hdma->XferCpltCallback = NULL;
982            hdma->XferHalfCpltCallback = NULL;
983            hdma->XferM1CpltCallback = NULL;
984            hdma->XferM1HalfCpltCallback = NULL;
985            hdma->XferErrorCallback = NULL;
986            hdma->XferAbortCallback = NULL;
987            break;
988 
989     default:
990            status = HAL_ERROR;
991            break;
992     }
993   }
994   else
995   {
996     status = HAL_ERROR;
997   }
998 
999   /* Release Lock */
1000   __HAL_UNLOCK(hdma);
1001 
1002   return status;
1003 }
1004 
1005 /**
1006   * @}
1007   */
1008 
1009 
1010 
1011 /** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions
1012  *  @brief    Peripheral State and Errors functions
1013  *
1014 @verbatim
1015  ===============================================================================
1016             ##### Peripheral State and Errors functions #####
1017  ===============================================================================
1018     [..]
1019     This subsection provides functions allowing to
1020       (+) Check the DMA state
1021       (+) Get error code
1022 
1023 @endverbatim
1024   * @{
1025   */
1026 
1027 /**
1028   * @brief  Return the DMA handle state.
1029   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1030   *               the configuration information for the specified DMA Channel.
1031   * @retval HAL state
1032   */
HAL_DMA_GetState(DMA_HandleTypeDef * hdma)1033 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
1034 {
1035   /* Return DMA handle state */
1036   return hdma->State;
1037 }
1038 
1039 /**
1040   * @brief  Return the DMA error code.
1041   * @param  hdma : pointer to a DMA_HandleTypeDef structure that contains
1042   *              the configuration information for the specified DMA Channel.
1043   * @retval DMA Error Code
1044   */
HAL_DMA_GetError(DMA_HandleTypeDef * hdma)1045 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
1046 {
1047   return hdma->ErrorCode;
1048 }
1049 
1050 /**
1051   * @}
1052   */
1053 
1054 /**
1055   * @}
1056   */
1057 
1058 /** @defgroup DMA_Exported_Functions_Group4 Attributes management functions
1059  *  @brief    Attributes management functions
1060  *
1061 @verbatim
1062  ===============================================================================
1063             ##### Attributes management functions #####
1064  ===============================================================================
1065     [..]
1066     This subsection provides functions allowing to
1067       (+) Configure the DMA channel(s) privilege and non-privilege attributes
1068       (+) Configure the DMA channel(s) secure and non-secure attributes from
1069           secure world when when the system implements the security (TZEN=1)
1070       (+) Get the DMA channel(s) attributes
1071 
1072 @endverbatim
1073   * @{
1074   */
1075 
1076 /**
1077   * @brief  Configure the DMA channel attribute(s).
1078   * @note   Available attributes are security and privilege protection.
1079   *         Each field can be set independently. Not allowed configurations
1080   *         are not taken into account & HAL_ERROR returned.
1081   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1082   *              the configuration information for the specified DMA Channel.
1083   * @param  ChannelAttributes specifies the DMA channel secure/privilege attributes.
1084   *         This parameter can be a one or a combination of @ref DMA_Channel_Attributes
1085   * @retval HAL Status
1086   */
HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef * hdma,uint32_t ChannelAttributes)1087 HAL_StatusTypeDef HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef *hdma, uint32_t ChannelAttributes)
1088 {
1089   HAL_StatusTypeDef status = HAL_OK;
1090   uint32_t ccr;
1091 
1092 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1093   uint32_t ccr_SECM;
1094 #endif
1095 
1096   /* Check the DMA peripheral handle */
1097   if(hdma == NULL)
1098   {
1099     status = HAL_ERROR;
1100     return status;
1101   }
1102 
1103   /* Check the parameters */
1104   assert_param(IS_DMA_ATTRIBUTES(ChannelAttributes));
1105 
1106   /* Read CCR register */
1107   ccr = READ_REG(hdma->Instance->CCR);
1108 
1109   /* Apply any requested privilege/non-privilege attributes */
1110   if ((ChannelAttributes & DMA_CHANNEL_ATTR_PRIV_MASK) != 0U)
1111   {
1112     if((ChannelAttributes & DMA_CCR_PRIV) != 0U)
1113     {
1114       SET_BIT(ccr, DMA_CCR_PRIV);
1115     }
1116     else
1117     {
1118       CLEAR_BIT(ccr, DMA_CCR_PRIV);
1119     }
1120   }
1121 
1122 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1123   /* Channel */
1124   /* Check what is the current SECM status */
1125   if ((hdma->Instance->CCR & DMA_CCR_SECM) == DMA_CCR_SECM)
1126   {
1127     /* Channel is currently secure */
1128     ccr_SECM = DMA_CCR_SECM;
1129   }
1130   else
1131   {
1132     /* Channel is currently non-secure */
1133     ccr_SECM = 0U;
1134   }
1135 
1136   if((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_MASK) != 0U)
1137   {
1138     if((ChannelAttributes & DMA_CCR_SECM) != 0U)
1139     {
1140       SET_BIT(ccr, DMA_CCR_SECM);
1141       /* Channel changed to secure */
1142       ccr_SECM = DMA_CCR_SECM;
1143     }
1144     else
1145     {
1146       CLEAR_BIT(ccr, DMA_CCR_SECM);
1147       /* Channel changed to non-secure */
1148       ccr_SECM = 0U;
1149     }
1150   }
1151 
1152   /* Channel source */
1153   if((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_SRC_MASK) != 0U)
1154   {
1155     /* Configure Source security attributes */
1156     if ((ChannelAttributes & DMA_CCR_SSEC) != 0x0U)
1157     {
1158       /* SSEC can only be set if channel is secure */
1159       /* Otherwise configuration is not taken into account */
1160       if (ccr_SECM == 0U)
1161       {
1162         /* DSEC can not be secure */
1163         /* Source channel is non secure */
1164          status = HAL_ERROR;
1165       }
1166       else
1167       {
1168         SET_BIT(ccr, DMA_CCR_SSEC);
1169       }
1170     }
1171     else
1172     {
1173       CLEAR_BIT(ccr, DMA_CCR_SSEC);
1174     }
1175   }
1176 
1177   /* Channel destination */
1178   if((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_DEST_MASK) != 0U)
1179   {
1180     /* Configure Destination security attributes */
1181     if((ChannelAttributes & DMA_CCR_DSEC) != 0U)
1182     {
1183       if (ccr_SECM == 0U)
1184       {
1185         /* DSEC can only be set if channel is secure */
1186         /* Destination channel is non secure */
1187          status = HAL_ERROR;
1188       }
1189       else
1190       {
1191         SET_BIT(ccr, DMA_CCR_DSEC);
1192       }
1193     }
1194     else
1195     {
1196       CLEAR_BIT(ccr, DMA_CCR_DSEC);
1197     }
1198   }
1199 
1200 #endif /* __ARM_FEATURE_CMSE */
1201 
1202   /* Update CCR Register: PRIV, SECM, SCEC, DSEC bits */
1203   WRITE_REG(hdma->Instance->CCR, ccr);
1204 
1205   return status;
1206 }
1207 
1208 /**
1209   * @brief  Get the attribute of a DMA channel.
1210   * @note   Secure and non-secure attributes are only available from secure state
1211   *         when the system implements the security (TZEN=1)
1212   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1213   *              the configuration information for the specified DMA Channel.
1214   * @param  ChannelAttributes pointer to return the attributes.
1215   * @retval HAL Status.
1216   */
HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef * hdma,uint32_t * ChannelAttributes)1217 HAL_StatusTypeDef HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef *hdma, uint32_t *ChannelAttributes)
1218 {
1219   uint32_t read_attributes;
1220   uint32_t attributes;
1221 
1222   /* Check the DMA peripheral handle and pointer to returned value */
1223   if((hdma == NULL) || (ChannelAttributes == NULL))
1224   {
1225     return HAL_ERROR;
1226   }
1227 
1228 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1229   /* Get secure or non-secure attributes */
1230   read_attributes = READ_BIT(hdma->Instance->CCR, DMA_CCR_PRIV | DMA_CCR_SECM | DMA_CCR_SSEC | DMA_CCR_DSEC);
1231 
1232   /* Get secure or non-secure attributes */
1233   attributes = ((read_attributes & DMA_CCR_PRIV) == 0U) ? DMA_CHANNEL_NPRIV : DMA_CHANNEL_PRIV;
1234 
1235   /* Get security attributes */
1236   attributes |= ((read_attributes & DMA_CCR_SECM) == 0U) ? DMA_CHANNEL_NSEC : DMA_CHANNEL_SEC;
1237 
1238   /* Get security attributes of the source */
1239   attributes |= ((read_attributes & DMA_CCR_SSEC) == 0U) ? DMA_CHANNEL_SRC_NSEC : DMA_CHANNEL_SRC_SEC;
1240 
1241   /* Get security attributes of the destination */
1242   attributes |= ((read_attributes & DMA_CCR_DSEC) == 0U) ? DMA_CHANNEL_DEST_NSEC : DMA_CHANNEL_DEST_SEC;
1243 
1244 #else
1245   /* Get secure or non-secure attributes */
1246   read_attributes = READ_BIT(hdma->Instance->CCR, DMA_CCR_PRIV);
1247 
1248   attributes = ((read_attributes & DMA_CCR_PRIV) == 0U) ? DMA_CHANNEL_NPRIV : DMA_CHANNEL_PRIV;
1249 #endif /* __ARM_FEATURE_CMSE */
1250 
1251   /* return value */
1252   *ChannelAttributes = attributes;
1253 
1254   return HAL_OK;
1255 }
1256 
1257 /** @addtogroup DMA_Private_Functions
1258   * @{
1259   */
1260 
1261 /**
1262   * @brief  Sets the DMA Transfer parameter.
1263   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
1264   *                     the configuration information for the specified DMA Channel.
1265   * @param  SrcAddress The source memory Buffer address
1266   * @param  DstAddress The destination memory Buffer address
1267   * @param  DataLength The length of data to be transferred from source to destination
1268   * @retval HAL status
1269   */
DMA_SetConfig(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)1270 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
1271 {
1272   /* Clear the DMAMUX synchro overrun flag */
1273   hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
1274 
1275   if(hdma->DMAmuxRequestGen != 0U)
1276   {
1277     /* Clear the DMAMUX request generator overrun flag */
1278     hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
1279   }
1280 
1281   /* Clear all flags */
1282   hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
1283 
1284   /* Configure DMA Channel data length */
1285   hdma->Instance->CNDTR = DataLength;
1286 
1287   /* Memory to Peripheral */
1288   if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1289   {
1290     /* Configure DMA Channel destination address */
1291     hdma->Instance->CPAR = DstAddress;
1292 
1293     /* Configure DMA Channel source address */
1294     hdma->Instance->CM0AR = SrcAddress;
1295   }
1296   /* Peripheral to Memory */
1297   else
1298   {
1299     /* Configure DMA Channel source address */
1300     hdma->Instance->CPAR = SrcAddress;
1301 
1302     /* Configure DMA Channel destination address */
1303     hdma->Instance->CM0AR = DstAddress;
1304   }
1305 }
1306 
1307 /**
1308   * @brief  Updates the DMA handle with the DMAMUX  channel and status mask depending on channel number
1309   * @param  hdma        pointer to a DMA_HandleTypeDef structure that contains
1310   *                     the configuration information for the specified DMA Channel.
1311   * @retval None
1312   */
DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef * hdma)1313 static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma)
1314 {
1315   uint32_t channel_number;
1316 
1317   /* check if instance is not outside the DMA channel range */
1318   if ((uint32_t)hdma->Instance < (uint32_t)DMA2_Channel1)
1319   {
1320     /* DMA1 */
1321     hdma->DMAmuxChannel = (DMAMUX1_Channel0 + (hdma->ChannelIndex >> 2U));
1322   }
1323   else
1324   {
1325     /* DMA2 */
1326     hdma->DMAmuxChannel = (DMAMUX1_Channel8 + (hdma->ChannelIndex >> 2U));
1327   }
1328 
1329   channel_number = (((uint32_t)hdma->Instance & 0xFFU) - 8U) / 20U;
1330   hdma->DMAmuxChannelStatus = DMAMUX1_ChannelStatus;
1331   hdma->DMAmuxChannelStatusMask = 1UL << (channel_number & 0x1FU);
1332 }
1333 
1334 /**
1335   * @brief  Updates the DMA handle with the DMAMUX  request generator params
1336   * @param  hdma        pointer to a DMA_HandleTypeDef structure that contains
1337   *                     the configuration information for the specified DMA Channel.
1338   * @retval None
1339   */
1340 
DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef * hdma)1341 static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma)
1342 {
1343   uint32_t request =  hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID;
1344 
1345   /* DMA Channels are connected to DMAMUX1 request generator blocks*/
1346   hdma->DMAmuxRequestGen = (DMAMUX_RequestGen_TypeDef *)((uint32_t)(((uint32_t)DMAMUX1_RequestGenerator0) + ((request - 1U) * 4U)));
1347 
1348   hdma->DMAmuxRequestGenStatus = DMAMUX1_RequestGenStatus;
1349 
1350   /* here "Request" is either DMA_REQUEST_GENERATOR0 to DMA_REQUEST_GENERATOR3, i.e. <= 4*/
1351   hdma->DMAmuxRequestGenStatusMask = 1UL << ((request - 1U) & 0x3U);
1352 }
1353 
1354 /**
1355   * @}
1356   */
1357 
1358 /**
1359   * @}
1360   */
1361 
1362 #endif /* HAL_DMA_MODULE_ENABLED */
1363 /**
1364   * @}
1365   */
1366 
1367 /**
1368   * @}
1369   */
1370 
1371