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