1 /**
2   ******************************************************************************
3   * @file    stm32mp1xx_hal_dma_ex.c
4   * @author  MCD Application Team
5   * @brief   DMA Extension HAL module driver
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the DMA Extension peripheral:
8   *           + Extended features functions
9   *
10   ******************************************************************************
11   * @attention
12   *
13   * Copyright (c) 2019 STMicroelectronics.
14   * All rights reserved.
15   *
16   * This software is licensed under terms that can be found in the LICENSE file
17   * in the root directory of this software component.
18   * If no LICENSE file comes with this software, it is provided AS-IS.
19   *
20   ******************************************************************************
21   @verbatim
22   ==============================================================================
23                         ##### How to use this driver #####
24   ==============================================================================
25   [..]
26   The DMA Extension HAL driver can be used as follows:
27    (+) Start a multi buffer transfer using the HAL_DMA_MultiBufferStart() function
28        for polling mode or HAL_DMA_MultiBufferStart_IT() for interrupt mode.
29 
30    (+) Configure the DMA_MUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
31    (+) Configure the DMA_MUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function.
32        Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used
33        to respectively enable/disable the request generator.
34 
35    (+) To handle the DMAMUX Interrupts, the function  HAL_DMAEx_MUX_IRQHandler should be called from
36        the DMAMUX IRQ handler i.e DMAMUX1_OVR_IRQHandler or DMAMUX2_OVR_IRQHandler .
37        As only one interrupt line is available for all DMAMUX channels and request generators , HAL_DMA_MUX_IRQHandler should be
38        called with, as parameter, the appropriate DMA handle as many as used DMAs in the user project
39       (exception done if a given DMA is not using the DMAMUX SYNC block neither a request generator)
40 
41      -@-  In Memory-to-Memory transfer mode, Multi (Double) Buffer mode is not allowed.
42      -@-  When Multi (Double) Buffer mode is enabled, the transfer is circular by default.
43      -@-  In Multi (Double) buffer mode, it is possible to update the base address for
44           the AHB memory port on the fly (DMA_SxM0AR or DMA_SxM1AR) when the stream is enabled.
45      -@-  Multi (Double) buffer mode is only possible with D2 DMAs i.e DMA1 or DMA2. not BDMA.
46           Multi (Double) buffer mode is not possible with D3 BDMA.
47 
48   @endverbatim
49   ******************************************************************************
50   */
51 
52 /* Includes ------------------------------------------------------------------*/
53 #include "stm32mp1xx_hal.h"
54 
55 /** @addtogroup STM32MP1xx_HAL_Driver
56   * @{
57   */
58 
59 /** @defgroup DMAEx DMAEx
60   * @brief DMA Extended HAL module driver
61   * @{
62   */
63 
64 #ifdef HAL_DMA_MODULE_ENABLED
65 
66 /* Private types -------------------------------------------------------------*/
67 /* Private variables ---------------------------------------------------------*/
68 /* Private Constants ---------------------------------------------------------*/
69 /* Private macros ------------------------------------------------------------*/
70 /* Private functions ---------------------------------------------------------*/
71 /** @addtogroup DMAEx_Private_Functions
72   * @{
73   */
74 
75 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
76 
77 /**
78   * @}
79   */
80 
81 /* Exported functions ---------------------------------------------------------*/
82 
83 /** @addtogroup DMAEx_Exported_Functions
84   * @{
85   */
86 
87 
88 /** @addtogroup DMAEx_Exported_Functions_Group1
89   *
90 @verbatim
91  ===============================================================================
92                 #####  Extended features functions  #####
93  ===============================================================================
94     [..]  This section provides functions allowing to:
95       (+) Configure the source, destination address and data length and
96           Start MultiBuffer DMA transfer
97       (+) Configure the source, destination address and data length and
98           Start MultiBuffer DMA transfer with interrupt
99       (+) Change on the fly the memory0 or memory1 address.
100       (+) Configure the DMA_MUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
101       (+) Configure the DMA_MUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function.
102       (+) Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used
103           to respectively enable/disable the request generator.
104       (+) Handle DMAMUX interrupts using HAL_DMAEx_MUX_IRQHandler : should be called from
105           the DMAMUX IRQ handler i.e DMAMUX1_OVR_IRQHandler or DMAMUX2_OVR_IRQHandler
106 
107 @endverbatim
108   * @{
109   */
110 
111 
112 /**
113   * @brief  Starts the multi_buffer DMA Transfer.
114   * @param  hdma      : pointer to a DMA_HandleTypeDef structure that contains
115   *                     the configuration information for the specified DMA Stream.
116   * @param  SrcAddress: The source memory Buffer address
117   * @param  DstAddress: The destination memory Buffer address
118   * @param  SecondMemAddress: The second memory Buffer address in case of multi buffer Transfer
119   * @param  DataLength: The length of data to be transferred from source to destination
120   * @retval HAL status
121   */
HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t SecondMemAddress,uint32_t DataLength)122 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
123 {
124   HAL_StatusTypeDef status = HAL_OK;
125   __IO uint32_t *ifcRegister_Base; /* DMA Stream Interrupt Clear register */
126 
127   /* Check the parameters */
128   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
129   assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
130 
131   /* Memory-to-memory transfer not supported in double buffering mode */
132   if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
133   {
134     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
135     status = HAL_ERROR;
136   }
137   else
138   {
139     /* Process Locked */
140     __HAL_LOCK(hdma);
141 
142     if (HAL_DMA_STATE_READY == hdma->State)
143     {
144       /* Change DMA peripheral state */
145       hdma->State = HAL_DMA_STATE_BUSY;
146 
147       /* Initialize the error code */
148       hdma->ErrorCode = HAL_DMA_ERROR_NONE;
149 
150       /* Enable the Double buffer mode */
151       ((DMA_Stream_TypeDef *)hdma->Instance)->CR |= (uint32_t)DMA_SxCR_DBM;
152 
153       /* Configure DMA Stream destination address */
154       ((DMA_Stream_TypeDef *)hdma->Instance)->M1AR = SecondMemAddress;
155 
156       /* Configure the source, destination address and the data length */
157       DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
158 
159       /* Calculate the interrupt clear flag register (IFCR) base address  */
160       ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 8U));
161 
162       /* Clear all flags */
163       *ifcRegister_Base = 0x3FUL << (hdma->StreamIndex & 0x1FU);
164 
165       /* Clear the DMAMUX synchro overrun flag */
166       hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
167 
168       if(hdma->DMAmuxRequestGen != 0U)
169       {
170         /* Clear the DMAMUX request generator overrun flag */
171         hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
172       }
173 
174       /* Enable the peripheral */
175       __HAL_DMA_ENABLE(hdma);
176     }
177     else
178     {
179       /* Set the error code to busy */
180       hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
181 
182       /* Return error status */
183       status = HAL_ERROR;
184     }
185   }
186   return status;
187 }
188 
189 /**
190   * @brief  Starts the multi_buffer DMA Transfer with interrupt enabled.
191   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
192   *                     the configuration information for the specified DMA Stream.
193   * @param  SrcAddress: The source memory Buffer address
194   * @param  DstAddress: The destination memory Buffer address
195   * @param  SecondMemAddress: The second memory Buffer address in case of multi buffer Transfer
196   * @param  DataLength: The length of data to be transferred from source to destination
197   * @retval HAL status
198   */
HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t SecondMemAddress,uint32_t DataLength)199 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
200 {
201   HAL_StatusTypeDef status = HAL_OK;
202   __IO uint32_t *ifcRegister_Base; /* DMA Stream Interrupt Clear register */
203 
204   /* Check the parameters */
205   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
206   assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
207 
208   /* Memory-to-memory transfer not supported in double buffering mode */
209   if(hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
210   {
211     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
212     return HAL_ERROR;
213   }
214 
215   /* Process locked */
216   __HAL_LOCK(hdma);
217 
218   if (HAL_DMA_STATE_READY == hdma->State)
219   {
220     /* Change DMA peripheral state */
221     hdma->State = HAL_DMA_STATE_BUSY;
222 
223     /* Initialize the error code */
224     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
225 
226     /* Enable the Double buffer mode */
227     ((DMA_Stream_TypeDef *)hdma->Instance)->CR |= (uint32_t)DMA_SxCR_DBM;
228 
229     /* Configure DMA Stream destination address */
230     ((DMA_Stream_TypeDef *)hdma->Instance)->M1AR = SecondMemAddress;
231 
232     /* Configure the source, destination address and the data length */
233     DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
234 
235     /* Calculate the interrupt clear flag register (IFCR) base address  */
236     ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 8U));
237 
238     /* Clear all flags */
239     *ifcRegister_Base = 0x3FUL << (hdma->StreamIndex & 0x1FU);
240 
241     /* Clear the DMAMUX synchro overrun flag */
242     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
243 
244     if(hdma->DMAmuxRequestGen != 0U)
245     {
246       /* Clear the DMAMUX request generator overrun flag */
247       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
248     }
249 
250     /* Enable Common interrupts*/
251     MODIFY_REG(((DMA_Stream_TypeDef *)hdma->Instance)->CR, (DMA_IT_TC | DMA_IT_TE | DMA_IT_DME | DMA_IT_HT), (DMA_IT_TC | DMA_IT_TE | DMA_IT_DME));
252     ((DMA_Stream_TypeDef *)hdma->Instance)->FCR |= DMA_IT_FE;
253 
254       if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
255     {
256       /*Enable Half Transfer IT if corresponding Callback is set*/
257       ((DMA_Stream_TypeDef *)hdma->Instance)->CR  |= DMA_IT_HT;
258     }
259 
260     /* Check if DMAMUX Synchronization is enabled*/
261     if ((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
262     {
263       /* Enable DMAMUX sync overrun IT*/
264       hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
265     }
266 
267     if(hdma->DMAmuxRequestGen != 0U)
268     {
269       /* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/
270       /* enable the request gen overrun IT*/
271       hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
272     }
273 
274     /* Enable the peripheral */
275     __HAL_DMA_ENABLE(hdma);
276   }
277   else
278   {
279     /* Set the error code to busy */
280     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
281 
282     /* Return error status */
283     status = HAL_ERROR;
284   }
285   return status;
286 }
287 
288 /**
289   * @brief  Change the memory0 or memory1 address on the fly.
290   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
291   *                     the configuration information for the specified DMA Stream.
292   * @param  Address:    The new address
293   * @param  memory:     the memory to be changed, This parameter can be one of
294   *                     the following values:
295   *                      MEMORY0 /
296   *                      MEMORY1
297   * @note   The MEMORY0 address can be changed only when the current transfer use
298   *         MEMORY1 and the MEMORY1 address can be changed only when the current
299   *         transfer use MEMORY0.
300   * @retval HAL status
301   */
HAL_DMAEx_ChangeMemory(DMA_HandleTypeDef * hdma,uint32_t Address,HAL_DMA_MemoryTypeDef memory)302 HAL_StatusTypeDef HAL_DMAEx_ChangeMemory(DMA_HandleTypeDef *hdma, uint32_t Address, HAL_DMA_MemoryTypeDef memory)
303 {
304   if (memory == MEMORY0)
305   {
306     /* change the memory0 address */
307     ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = Address;
308   }
309   else
310   {
311     /* change the memory1 address */
312     ((DMA_Stream_TypeDef *)hdma->Instance)->M1AR = Address;
313   }
314 
315   return HAL_OK;
316 }
317 
318 /**
319   * @brief  Configure the DMAMUX synchronization parameters for a given DMA stream (instance).
320   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
321   *                     the configuration information for the specified DMA Stream.
322   * @param  pSyncConfig : pointer to HAL_DMA_MuxSyncConfigTypeDef : contains the DMAMUX synchronization parameters
323   * @retval HAL status
324   */
HAL_DMAEx_ConfigMuxSync(DMA_HandleTypeDef * hdma,HAL_DMA_MuxSyncConfigTypeDef * pSyncConfig)325 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxSync(DMA_HandleTypeDef *hdma, HAL_DMA_MuxSyncConfigTypeDef *pSyncConfig)
326 {
327   uint32_t syncSignalID = 0;
328   uint32_t syncPolarity = 0;
329 
330   /* Check the parameters */
331   assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
332   assert_param(IS_DMAMUX_SYNC_STATE(pSyncConfig->SyncEnable));
333   assert_param(IS_DMAMUX_SYNC_EVENT(pSyncConfig->EventEnable));
334   assert_param(IS_DMAMUX_SYNC_REQUEST_NUMBER(pSyncConfig->RequestNumber));
335 
336   if (pSyncConfig->SyncEnable == ENABLE)
337   {
338     assert_param(IS_DMAMUX_SYNC_POLARITY(pSyncConfig->SyncPolarity));
339     assert_param(IS_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID));
340     syncSignalID = pSyncConfig->SyncSignalID;
341     syncPolarity = pSyncConfig->SyncPolarity;
342   }
343 
344   /*Check if the DMA state is ready */
345   if (hdma->State == HAL_DMA_STATE_READY)
346   {
347     /* Process Locked */
348     __HAL_LOCK(hdma);
349 
350     /* Disable the synchronization and event generation before applying a new config */
351     CLEAR_BIT(hdma->DMAmuxChannel->CCR, (DMAMUX_CxCR_SE | DMAMUX_CxCR_EGE));
352 
353     /* Set the new synchronization parameters (and keep the request ID filled during the Init)*/
354     MODIFY_REG(hdma->DMAmuxChannel->CCR, \
355                (~DMAMUX_CxCR_DMAREQ_ID), \
356                (syncSignalID << DMAMUX_CxCR_SYNC_ID_Pos)       | \
357                ((pSyncConfig->RequestNumber - 1U) << DMAMUX_CxCR_NBREQ_Pos) | \
358                syncPolarity | ((uint32_t)pSyncConfig->SyncEnable << DMAMUX_CxCR_SE_Pos)    | \
359                ((uint32_t)pSyncConfig->EventEnable << DMAMUX_CxCR_EGE_Pos));
360 
361     /* Process Locked */
362     __HAL_UNLOCK(hdma);
363 
364     return HAL_OK;
365   }
366   else
367   {
368     /* Set the error code to busy */
369     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
370 
371     /* Return error status */
372     return HAL_ERROR;
373   }
374 }
375 
376 /**
377   * @brief  Configure the DMAMUX request generator block used by the given DMA stream (instance).
378   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
379   *                     the configuration information for the specified DMA Stream.
380   * @param  pRequestGeneratorConfig : pointer to HAL_DMA_MuxRequestGeneratorConfigTypeDef :
381   *         contains the request generator parameters.
382   *
383   * @retval HAL status
384   */
HAL_DMAEx_ConfigMuxRequestGenerator(DMA_HandleTypeDef * hdma,HAL_DMA_MuxRequestGeneratorConfigTypeDef * pRequestGeneratorConfig)385 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxRequestGenerator(DMA_HandleTypeDef *hdma, HAL_DMA_MuxRequestGeneratorConfigTypeDef *pRequestGeneratorConfig)
386 {
387   HAL_StatusTypeDef status;
388   HAL_DMA_StateTypeDef temp_state = hdma->State;
389 
390   /* Check the parameters */
391   assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
392 
393   assert_param(IS_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
394 
395   assert_param(IS_DMAMUX_REQUEST_GEN_POLARITY(pRequestGeneratorConfig->Polarity));
396   assert_param(IS_DMAMUX_REQUEST_GEN_REQUEST_NUMBER(pRequestGeneratorConfig->RequestNumber));
397 
398   /* check if the DMA state is ready
399      and DMA is using a DMAMUX request generator block
400   */
401   if(hdma->DMAmuxRequestGen == 0U)
402   {
403     /* Set the error code to busy */
404     hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
405 
406     /* error status */
407     status = HAL_ERROR;
408   }
409   else if(((hdma->DMAmuxRequestGen->RGCR & DMAMUX_RGxCR_GE) == 0U) && (temp_state == HAL_DMA_STATE_READY))
410   {
411     /* RequestGenerator must be disable prior to the configuration i.e GE bit is 0 */
412 
413     /* Process Locked */
414     __HAL_LOCK(hdma);
415 
416     /* Set the request generator new parameters*/
417     hdma->DMAmuxRequestGen->RGCR = pRequestGeneratorConfig->SignalID | \
418                                   ((pRequestGeneratorConfig->RequestNumber - 1U) << DMAMUX_RGxCR_GNBREQ_Pos)| \
419                                    pRequestGeneratorConfig->Polarity;
420     /* Process Locked */
421     __HAL_UNLOCK(hdma);
422 
423     return HAL_OK;
424   }
425   else
426   {
427     /* Set the error code to busy */
428     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
429 
430     /* error status */
431     status = HAL_ERROR;
432   }
433 
434   return status;
435 }
436 
437 /**
438   * @brief  Enable the DMAMUX request generator block used by the given DMA stream (instance).
439   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
440   *                     the configuration information for the specified DMA Stream.
441   * @retval HAL status
442   */
HAL_DMAEx_EnableMuxRequestGenerator(DMA_HandleTypeDef * hdma)443 HAL_StatusTypeDef HAL_DMAEx_EnableMuxRequestGenerator(DMA_HandleTypeDef *hdma)
444 {
445   /* Check the parameters */
446   assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
447 
448   /* check if the DMA state is ready
449      and DMA is using a DMAMUX request generator block */
450   if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0U))
451   {
452 
453     /* Enable the request generator*/
454     hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_GE;
455 
456     return HAL_OK;
457   }
458   else
459   {
460     return HAL_ERROR;
461   }
462 }
463 
464 /**
465   * @brief  Disable the DMAMUX request generator block used by the given DMA stream (instance).
466   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
467   *                     the configuration information for the specified DMA Stream.
468   * @retval HAL status
469   */
HAL_DMAEx_DisableMuxRequestGenerator(DMA_HandleTypeDef * hdma)470 HAL_StatusTypeDef HAL_DMAEx_DisableMuxRequestGenerator(DMA_HandleTypeDef *hdma)
471 {
472   /* Check the parameters */
473   assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
474 
475   /* check if the DMA state is ready
476      and DMA is using a DMAMUX request generator block */
477   if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0U))
478   {
479 
480     /* Disable the request generator*/
481     hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_GE;
482 
483     return HAL_OK;
484   }
485   else
486   {
487     return HAL_ERROR;
488   }
489 }
490 
491 /**
492   * @brief  Handles DMAMUX interrupt request.
493   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
494   *               the configuration information for the specified DMA Stream.
495   * @retval None
496   */
HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef * hdma)497 void HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef *hdma)
498 {
499   /* Check for DMAMUX Synchronization overrun */
500   if ((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
501   {
502     /* Disable the synchro overrun interrupt */
503     hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
504 
505     /* Clear the DMAMUX synchro overrun flag */
506     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
507 
508     /* Update error code */
509     hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
510 
511     if (hdma->XferErrorCallback != NULL)
512     {
513       /* Transfer error callback */
514       hdma->XferErrorCallback(hdma);
515     }
516   }
517 
518   if(hdma->DMAmuxRequestGen != 0)
519   {
520     /* if using a DMAMUX request generator block Check for DMAMUX request generator overrun */
521     if ((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
522     {
523       /* Disable the request gen overrun interrupt */
524       hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
525 
526       /* Clear the DMAMUX request generator overrun flag */
527       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
528 
529       /* Update error code */
530       hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
531 
532       if (hdma->XferErrorCallback != NULL)
533       {
534         /* Transfer error callback */
535         hdma->XferErrorCallback(hdma);
536       }
537     }
538   }
539 }
540 
541 
542 /**
543   * @}
544   */
545 
546 /**
547   * @}
548   */
549 
550 /** @addtogroup DMAEx_Private_Functions
551   * @{
552   */
553 
554 /**
555   * @brief  Set the DMA Transfer parameter.
556   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
557   *                     the configuration information for the specified DMA Stream.
558   * @param  SrcAddress: The source memory Buffer address
559   * @param  DstAddress: The destination memory Buffer address
560   * @param  DataLength: The length of data to be transferred from source to destination
561   * @retval HAL status
562   */
DMA_MultiBufferSetConfig(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)563 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
564 {
565   assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
566 
567   /* Configure DMA Stream data length */
568   ((DMA_Stream_TypeDef *)hdma->Instance)->NDTR = DataLength;
569 
570   /* Peripheral to Memory */
571   if ((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
572   {
573     /* Configure DMA Stream destination address */
574     ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = DstAddress;
575 
576     /* Configure DMA Stream source address */
577     ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = SrcAddress;
578   }
579   /* Memory to Peripheral */
580   else
581   {
582     /* Configure DMA Stream source address */
583     ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = SrcAddress;
584 
585     /* Configure DMA Stream destination address */
586     ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = DstAddress;
587   }
588 }
589 
590 /**
591   * @}
592   */
593 
594 #endif /* HAL_DMA_MODULE_ENABLED */
595 /**
596   * @}
597   */
598 
599 /**
600   * @}
601   */
602