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