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