Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:07

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_dma_ex.c
0004   * @author  MCD Application Team
0005   * @brief   DMA Extension HAL module driver
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the DMA Extension peripheral:
0008   *           + Extended features functions
0009   *
0010   @verbatim
0011   ==============================================================================
0012                         ##### How to use this driver #####
0013   ==============================================================================
0014   [..]
0015   The DMA Extension HAL driver can be used as follows:
0016    (+) Start a multi buffer transfer using the HAL_DMA_MultiBufferStart() function
0017        for polling mode or HAL_DMA_MultiBufferStart_IT() for interrupt mode.
0018 
0019    (+) Configure the DMA_MUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
0020    (+) Configure the DMA_MUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function.
0021        Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used
0022        to respectively enable/disable the request generator.
0023 
0024    (+) To handle the DMAMUX Interrupts, the function  HAL_DMAEx_MUX_IRQHandler should be called from
0025        the DMAMUX IRQ handler i.e DMAMUX1_OVR_IRQHandler or DMAMUX2_OVR_IRQHandler .
0026        As only one interrupt line is available for all DMAMUX channels and request generators , HAL_DMA_MUX_IRQHandler should be
0027        called with, as parameter, the appropriate DMA handle as many as used DMAs in the user project
0028       (exception done if a given DMA is not using the DMAMUX SYNC block neither a request generator)
0029 
0030      -@-  In Memory-to-Memory transfer mode, Multi (Double) Buffer mode is not allowed.
0031      -@-  When Multi (Double) Buffer mode is enabled, the transfer is circular by default.
0032      -@-  In Multi (Double) buffer mode, it is possible to update the base address for
0033           the AHB memory port on the fly (DMA_SxM0AR or DMA_SxM1AR) when the stream is enabled.
0034      -@-  Multi (Double) buffer mode is possible with DMA and BDMA instances.
0035 
0036   @endverbatim
0037   ******************************************************************************
0038   * @attention
0039   *
0040   * Copyright (c) 2017 STMicroelectronics.
0041   * All rights reserved.
0042   *
0043   * This software is licensed under terms that can be found in the LICENSE file
0044   * in the root directory of this software component.
0045   * If no LICENSE file comes with this software, it is provided AS-IS.
0046   *
0047   ******************************************************************************
0048   */
0049 
0050 /* Includes ------------------------------------------------------------------*/
0051 #include "stm32h7xx_hal.h"
0052 
0053 /** @addtogroup STM32H7xx_HAL_Driver
0054   * @{
0055   */
0056 
0057 /** @defgroup DMAEx DMAEx
0058   * @ingroup RTEMSBSPsARMSTM32H7
0059   * @brief DMA Extended HAL module driver
0060   * @{
0061   */
0062 
0063 #ifdef HAL_DMA_MODULE_ENABLED
0064 
0065 /* Private types -------------------------------------------------------------*/
0066 /* Private variables ---------------------------------------------------------*/
0067 /* Private Constants ---------------------------------------------------------*/
0068 /* Private macros ------------------------------------------------------------*/
0069 /* Private functions ---------------------------------------------------------*/
0070 /** @addtogroup DMAEx_Private_Functions
0071   * @{
0072   */
0073 
0074 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
0075 
0076 /**
0077   * @}
0078   */
0079 
0080 /* Exported functions ---------------------------------------------------------*/
0081 
0082 /** @addtogroup DMAEx_Exported_Functions
0083   * @{
0084   */
0085 
0086 
0087 /** @addtogroup DMAEx_Exported_Functions_Group1
0088   *
0089 @verbatim
0090  ===============================================================================
0091                 #####  Extended features functions  #####
0092  ===============================================================================
0093     [..]  This section provides functions allowing to:
0094       (+) Configure the source, destination address and data length and
0095           Start MultiBuffer DMA transfer
0096       (+) Configure the source, destination address and data length and
0097           Start MultiBuffer DMA transfer with interrupt
0098       (+) Change on the fly the memory0 or memory1 address.
0099       (+) Configure the DMA_MUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
0100       (+) Configure the DMA_MUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function.
0101       (+) Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used
0102           to respectively enable/disable the request generator.
0103       (+) Handle DMAMUX interrupts using HAL_DMAEx_MUX_IRQHandler : should be called from
0104           the DMAMUX IRQ handler i.e DMAMUX1_OVR_IRQHandler or DMAMUX2_OVR_IRQHandler
0105 
0106 @endverbatim
0107   * @{
0108   */
0109 
0110 
0111 /**
0112   * @brief  Starts the multi_buffer DMA Transfer.
0113   * @param  hdma      : pointer to a DMA_HandleTypeDef structure that contains
0114   *                     the configuration information for the specified DMA Stream.
0115   * @param  SrcAddress: The source memory Buffer address
0116   * @param  DstAddress: The destination memory Buffer address
0117   * @param  SecondMemAddress: The second memory Buffer address in case of multi buffer Transfer
0118   * @param  DataLength: The length of data to be transferred from source to destination
0119   * @retval HAL status
0120   */
0121 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
0122 {
0123   HAL_StatusTypeDef status = HAL_OK;
0124   __IO uint32_t *ifcRegister_Base; /* DMA Stream Interrupt Clear register */
0125 
0126   /* Check the parameters */
0127   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
0128   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
0129 
0130   /* Memory-to-memory transfer not supported in double buffering mode */
0131   if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
0132   {
0133     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
0134     status = HAL_ERROR;
0135   }
0136   else
0137   {
0138     /* Process Locked */
0139     __HAL_LOCK(hdma);
0140 
0141     if(HAL_DMA_STATE_READY == hdma->State)
0142     {
0143       /* Change DMA peripheral state */
0144       hdma->State = HAL_DMA_STATE_BUSY;
0145 
0146       /* Initialize the error code */
0147       hdma->ErrorCode = HAL_DMA_ERROR_NONE;
0148 
0149       if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
0150       {
0151         /* Enable the Double buffer mode */
0152         ((DMA_Stream_TypeDef   *)hdma->Instance)->CR |= DMA_SxCR_DBM;
0153 
0154         /* Configure DMA Stream destination address */
0155         ((DMA_Stream_TypeDef   *)hdma->Instance)->M1AR = SecondMemAddress;
0156 
0157         /* Calculate the interrupt clear flag register (IFCR) base address  */
0158         ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 8U));
0159 
0160         /* Clear all flags */
0161         *ifcRegister_Base = 0x3FUL << (hdma->StreamIndex & 0x1FU);
0162       }
0163       else /* BDMA instance(s) */
0164       {
0165         /* Enable the Double buffer mode */
0166         ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR |= (BDMA_CCR_DBM | BDMA_CCR_CIRC);
0167 
0168         /* Configure DMA Stream destination address */
0169         ((BDMA_Channel_TypeDef   *)hdma->Instance)->CM1AR = SecondMemAddress;
0170 
0171         /* Calculate the interrupt clear flag register (IFCR) base address  */
0172         ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 4U));
0173 
0174         /* Clear all flags */
0175         *ifcRegister_Base = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
0176       }
0177 
0178       if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
0179       {
0180         /* Configure the source, destination address and the data length */
0181         DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
0182 
0183         /* Clear the DMAMUX synchro overrun flag */
0184         hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
0185 
0186         if(hdma->DMAmuxRequestGen != 0U)
0187         {
0188           /* Clear the DMAMUX request generator overrun flag */
0189           hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
0190         }
0191       }
0192 
0193       /* Enable the peripheral */
0194       __HAL_DMA_ENABLE(hdma);
0195     }
0196     else
0197     {
0198       /* Set the error code to busy */
0199       hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
0200 
0201       /* Return error status */
0202       status = HAL_ERROR;
0203     }
0204   }
0205   return status;
0206 }
0207 
0208 /**
0209   * @brief  Starts the multi_buffer DMA Transfer with interrupt enabled.
0210   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
0211   *                     the configuration information for the specified DMA Stream.
0212   * @param  SrcAddress: The source memory Buffer address
0213   * @param  DstAddress: The destination memory Buffer address
0214   * @param  SecondMemAddress: The second memory Buffer address in case of multi buffer Transfer
0215   * @param  DataLength: The length of data to be transferred from source to destination
0216   * @retval HAL status
0217   */
0218 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
0219 {
0220   HAL_StatusTypeDef status = HAL_OK;
0221   __IO uint32_t *ifcRegister_Base; /* DMA Stream Interrupt Clear register */
0222 
0223   /* Check the parameters */
0224   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
0225   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
0226 
0227   /* Memory-to-memory transfer not supported in double buffering mode */
0228   if(hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
0229   {
0230     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
0231     return HAL_ERROR;
0232   }
0233 
0234   /* Process locked */
0235   __HAL_LOCK(hdma);
0236 
0237   if(HAL_DMA_STATE_READY == hdma->State)
0238   {
0239     /* Change DMA peripheral state */
0240     hdma->State = HAL_DMA_STATE_BUSY;
0241 
0242     /* Initialize the error code */
0243     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
0244 
0245     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
0246     {
0247       /* Enable the Double buffer mode */
0248       ((DMA_Stream_TypeDef   *)hdma->Instance)->CR |= DMA_SxCR_DBM;
0249 
0250       /* Configure DMA Stream destination address */
0251       ((DMA_Stream_TypeDef   *)hdma->Instance)->M1AR = SecondMemAddress;
0252 
0253       /* Calculate the interrupt clear flag register (IFCR) base address  */
0254       ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 8U));
0255 
0256       /* Clear all flags */
0257       *ifcRegister_Base = 0x3FUL << (hdma->StreamIndex & 0x1FU);
0258     }
0259     else /* BDMA instance(s) */
0260     {
0261       /* Enable the Double buffer mode */
0262       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR |= (BDMA_CCR_DBM | BDMA_CCR_CIRC);
0263 
0264       /* Configure DMA Stream destination address */
0265       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CM1AR = SecondMemAddress;
0266 
0267       /* Calculate the interrupt clear flag register (IFCR) base address  */
0268       ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 4U));
0269 
0270       /* Clear all flags */
0271       *ifcRegister_Base = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
0272     }
0273 
0274     /* Configure the source, destination address and the data length */
0275     DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
0276 
0277     if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
0278     {
0279       /* Clear the DMAMUX synchro overrun flag */
0280       hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
0281 
0282       if(hdma->DMAmuxRequestGen != 0U)
0283       {
0284         /* Clear the DMAMUX request generator overrun flag */
0285         hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
0286       }
0287     }
0288 
0289     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
0290     {
0291       /* Enable Common interrupts*/
0292       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));
0293       ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR |= DMA_IT_FE;
0294 
0295       if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
0296       {
0297         /*Enable Half Transfer IT if corresponding Callback is set*/
0298         ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  |= DMA_IT_HT;
0299       }
0300     }
0301     else /* BDMA instance(s) */
0302     {
0303       /* Enable Common interrupts*/
0304       MODIFY_REG(((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR, (BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE), (BDMA_CCR_TCIE | BDMA_CCR_TEIE));
0305 
0306       if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
0307       {
0308         /*Enable Half Transfer IT if corresponding Callback is set*/
0309         ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR  |= BDMA_CCR_HTIE;
0310       }
0311     }
0312 
0313     if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
0314     {
0315       /* Check if DMAMUX Synchronization is enabled*/
0316       if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
0317       {
0318         /* Enable DMAMUX sync overrun IT*/
0319         hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
0320       }
0321 
0322       if(hdma->DMAmuxRequestGen != 0U)
0323       {
0324         /* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/
0325         /* enable the request gen overrun IT*/
0326         hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
0327       }
0328     }
0329 
0330     /* Enable the peripheral */
0331     __HAL_DMA_ENABLE(hdma);
0332   }
0333   else
0334   {
0335     /* Set the error code to busy */
0336     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
0337 
0338     /* Return error status */
0339     status = HAL_ERROR;
0340   }
0341   return status;
0342 }
0343 
0344 /**
0345   * @brief  Change the memory0 or memory1 address on the fly.
0346   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
0347   *                     the configuration information for the specified DMA Stream.
0348   * @param  Address:    The new address
0349   * @param  memory:     the memory to be changed, This parameter can be one of
0350   *                     the following values:
0351   *                      MEMORY0 /
0352   *                      MEMORY1
0353   * @note   The MEMORY0 address can be changed only when the current transfer use
0354   *         MEMORY1 and the MEMORY1 address can be changed only when the current
0355   *         transfer use MEMORY0.
0356   * @retval HAL status
0357   */
0358 HAL_StatusTypeDef HAL_DMAEx_ChangeMemory(DMA_HandleTypeDef *hdma, uint32_t Address, HAL_DMA_MemoryTypeDef memory)
0359 {
0360   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
0361   {
0362     if(memory == MEMORY0)
0363     {
0364       /* change the memory0 address */
0365       ((DMA_Stream_TypeDef   *)hdma->Instance)->M0AR = Address;
0366     }
0367     else
0368     {
0369       /* change the memory1 address */
0370       ((DMA_Stream_TypeDef   *)hdma->Instance)->M1AR = Address;
0371     }
0372   }
0373   else /* BDMA instance(s) */
0374   {
0375     if(memory == MEMORY0)
0376     {
0377       /* change the memory0 address */
0378       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CM0AR = Address;
0379     }
0380     else
0381     {
0382       /* change the memory1 address */
0383       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CM1AR = Address;
0384     }
0385   }
0386 
0387   return HAL_OK;
0388 }
0389 
0390 /**
0391   * @brief  Configure the DMAMUX synchronization parameters for a given DMA stream (instance).
0392   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
0393   *                     the configuration information for the specified DMA Stream.
0394   * @param  pSyncConfig : pointer to HAL_DMA_MuxSyncConfigTypeDef : contains the DMAMUX synchronization parameters
0395   * @retval HAL status
0396   */
0397 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxSync(DMA_HandleTypeDef *hdma, HAL_DMA_MuxSyncConfigTypeDef *pSyncConfig)
0398 {
0399   uint32_t syncSignalID = 0;
0400   uint32_t syncPolarity = 0;
0401 
0402   /* Check the parameters */
0403   assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance));
0404   assert_param(IS_DMAMUX_SYNC_STATE(pSyncConfig->SyncEnable));
0405   assert_param(IS_DMAMUX_SYNC_EVENT(pSyncConfig->EventEnable));
0406   assert_param(IS_DMAMUX_SYNC_REQUEST_NUMBER(pSyncConfig->RequestNumber));
0407 
0408   if(pSyncConfig->SyncEnable == ENABLE)
0409   {
0410     assert_param(IS_DMAMUX_SYNC_POLARITY(pSyncConfig->SyncPolarity));
0411 
0412     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
0413     {
0414       assert_param(IS_DMA_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID));
0415     }
0416     else
0417     {
0418       assert_param(IS_BDMA_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID));
0419     }
0420     syncSignalID = pSyncConfig->SyncSignalID;
0421     syncPolarity = pSyncConfig->SyncPolarity;
0422   }
0423 
0424   /*Check if the DMA state is ready */
0425   if(hdma->State == HAL_DMA_STATE_READY)
0426   {
0427     /* Process Locked */
0428     __HAL_LOCK(hdma);
0429 
0430     /* Disable the synchronization and event generation before applying a new config */
0431     CLEAR_BIT(hdma->DMAmuxChannel->CCR,(DMAMUX_CxCR_SE | DMAMUX_CxCR_EGE));
0432 
0433     /* Set the new synchronization parameters (and keep the request ID filled during the Init)*/
0434     MODIFY_REG( hdma->DMAmuxChannel->CCR, \
0435                (~DMAMUX_CxCR_DMAREQ_ID) , \
0436                (syncSignalID << DMAMUX_CxCR_SYNC_ID_Pos)       | \
0437                ((pSyncConfig->RequestNumber - 1U) << DMAMUX_CxCR_NBREQ_Pos) | \
0438                syncPolarity | ((uint32_t)pSyncConfig->SyncEnable << DMAMUX_CxCR_SE_Pos)    | \
0439                ((uint32_t)pSyncConfig->EventEnable << DMAMUX_CxCR_EGE_Pos));
0440 
0441       /* Process Locked */
0442     __HAL_UNLOCK(hdma);
0443 
0444     return HAL_OK;
0445   }
0446   else
0447   {
0448     /* Set the error code to busy */
0449     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
0450 
0451     /* Return error status */
0452     return HAL_ERROR;
0453   }
0454 }
0455 
0456 /**
0457   * @brief  Configure the DMAMUX request generator block used by the given DMA stream (instance).
0458   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
0459   *                     the configuration information for the specified DMA Stream.
0460   * @param  pRequestGeneratorConfig : pointer to HAL_DMA_MuxRequestGeneratorConfigTypeDef :
0461   *         contains the request generator parameters.
0462   *
0463   * @retval HAL status
0464   */
0465 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxRequestGenerator (DMA_HandleTypeDef *hdma, HAL_DMA_MuxRequestGeneratorConfigTypeDef *pRequestGeneratorConfig)
0466 {
0467   HAL_StatusTypeDef status;
0468   HAL_DMA_StateTypeDef temp_state = hdma->State;
0469 
0470   /* Check the parameters */
0471   assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance));
0472 
0473   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
0474   {
0475     assert_param(IS_DMA_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
0476   }
0477   else
0478   {
0479     assert_param(IS_BDMA_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
0480   }
0481 
0482 
0483   assert_param(IS_DMAMUX_REQUEST_GEN_POLARITY(pRequestGeneratorConfig->Polarity));
0484   assert_param(IS_DMAMUX_REQUEST_GEN_REQUEST_NUMBER(pRequestGeneratorConfig->RequestNumber));
0485 
0486   /* check if the DMA state is ready
0487      and DMA is using a DMAMUX request generator block
0488   */
0489   if(hdma->DMAmuxRequestGen == 0U)
0490   {
0491     /* Set the error code to busy */
0492     hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
0493 
0494     /* error status */
0495     status = HAL_ERROR;
0496   }
0497   else if(((hdma->DMAmuxRequestGen->RGCR & DMAMUX_RGxCR_GE) == 0U) && (temp_state == HAL_DMA_STATE_READY))
0498   {
0499     /* RequestGenerator must be disable prior to the configuration i.e GE bit is 0 */
0500 
0501     /* Process Locked */
0502     __HAL_LOCK(hdma);
0503 
0504     /* Set the request generator new parameters */
0505     hdma->DMAmuxRequestGen->RGCR = pRequestGeneratorConfig->SignalID | \
0506                                   ((pRequestGeneratorConfig->RequestNumber - 1U) << DMAMUX_RGxCR_GNBREQ_Pos)| \
0507                                   pRequestGeneratorConfig->Polarity;
0508     /* Process Locked */
0509     __HAL_UNLOCK(hdma);
0510 
0511     return HAL_OK;
0512   }
0513   else
0514   {
0515     /* Set the error code to busy */
0516     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
0517 
0518     /* error status */
0519     status = HAL_ERROR;
0520   }
0521 
0522   return status;
0523 }
0524 
0525 /**
0526   * @brief  Enable the DMAMUX request generator block used by the given DMA stream (instance).
0527   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
0528   *                     the configuration information for the specified DMA Stream.
0529   * @retval HAL status
0530   */
0531 HAL_StatusTypeDef HAL_DMAEx_EnableMuxRequestGenerator (DMA_HandleTypeDef *hdma)
0532 {
0533   /* Check the parameters */
0534   assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance));
0535 
0536   /* check if the DMA state is ready
0537      and DMA is using a DMAMUX request generator block */
0538   if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0U))
0539   {
0540     /* Enable the request generator*/
0541     hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_GE;
0542 
0543    return HAL_OK;
0544  }
0545  else
0546  {
0547    return HAL_ERROR;
0548  }
0549 }
0550 
0551 /**
0552   * @brief  Disable the DMAMUX request generator block used by the given DMA stream (instance).
0553   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
0554   *                     the configuration information for the specified DMA Stream.
0555   * @retval HAL status
0556   */
0557 HAL_StatusTypeDef HAL_DMAEx_DisableMuxRequestGenerator (DMA_HandleTypeDef *hdma)
0558 {
0559   /* Check the parameters */
0560   assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance));
0561 
0562   /* check if the DMA state is ready
0563      and DMA is using a DMAMUX request generator block */
0564   if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0U))
0565   {
0566     /* Disable the request generator*/
0567     hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_GE;
0568 
0569    return HAL_OK;
0570  }
0571  else
0572  {
0573    return HAL_ERROR;
0574  }
0575 }
0576 
0577 /**
0578   * @brief  Handles DMAMUX interrupt request.
0579   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
0580   *               the configuration information for the specified DMA Stream.
0581   * @retval None
0582   */
0583 void HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef *hdma)
0584 {
0585   /* Check for DMAMUX Synchronization overrun */
0586   if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
0587   {
0588     /* Disable the synchro overrun interrupt */
0589     hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
0590 
0591     /* Clear the DMAMUX synchro overrun flag */
0592     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
0593 
0594     /* Update error code */
0595     hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
0596 
0597     if(hdma->XferErrorCallback != NULL)
0598     {
0599       /* Transfer error callback */
0600       hdma->XferErrorCallback(hdma);
0601     }
0602   }
0603 
0604   if(hdma->DMAmuxRequestGen != 0)
0605   {
0606    /* if using a DMAMUX request generator block Check for DMAMUX request generator overrun */
0607     if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
0608     {
0609       /* Disable the request gen overrun interrupt */
0610       hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
0611 
0612       /* Clear the DMAMUX request generator overrun flag */
0613       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
0614 
0615       /* Update error code */
0616       hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
0617 
0618       if(hdma->XferErrorCallback != NULL)
0619       {
0620         /* Transfer error callback */
0621         hdma->XferErrorCallback(hdma);
0622       }
0623     }
0624   }
0625 }
0626 
0627 
0628 /**
0629   * @}
0630   */
0631 
0632 /**
0633   * @}
0634   */
0635 
0636 /** @addtogroup DMAEx_Private_Functions
0637   * @{
0638   */
0639 
0640 /**
0641   * @brief  Set the DMA Transfer parameter.
0642   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
0643   *                     the configuration information for the specified DMA Stream.
0644   * @param  SrcAddress: The source memory Buffer address
0645   * @param  DstAddress: The destination memory Buffer address
0646   * @param  DataLength: The length of data to be transferred from source to destination
0647   * @retval HAL status
0648   */
0649 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
0650 {
0651   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
0652   {
0653     /* Configure DMA Stream data length */
0654     ((DMA_Stream_TypeDef   *)hdma->Instance)->NDTR = DataLength;
0655 
0656     /* Peripheral to Memory */
0657     if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
0658     {
0659       /* Configure DMA Stream destination address */
0660       ((DMA_Stream_TypeDef   *)hdma->Instance)->PAR = DstAddress;
0661 
0662       /* Configure DMA Stream source address */
0663       ((DMA_Stream_TypeDef   *)hdma->Instance)->M0AR = SrcAddress;
0664     }
0665     /* Memory to Peripheral */
0666     else
0667     {
0668       /* Configure DMA Stream source address */
0669       ((DMA_Stream_TypeDef   *)hdma->Instance)->PAR = SrcAddress;
0670 
0671       /* Configure DMA Stream destination address */
0672       ((DMA_Stream_TypeDef   *)hdma->Instance)->M0AR = DstAddress;
0673     }
0674   }
0675   else /* BDMA instance(s) */
0676   {
0677     /* Configure DMA Stream data length */
0678     ((BDMA_Channel_TypeDef   *)hdma->Instance)->CNDTR = DataLength;
0679 
0680     /* Peripheral to Memory */
0681     if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
0682     {
0683       /* Configure DMA Stream destination address */
0684       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CPAR = DstAddress;
0685 
0686       /* Configure DMA Stream source address */
0687       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CM0AR = SrcAddress;
0688     }
0689     /* Memory to Peripheral */
0690     else
0691     {
0692       /* Configure DMA Stream source address */
0693       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CPAR = SrcAddress;
0694 
0695       /* Configure DMA Stream destination address */
0696       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CM0AR = DstAddress;
0697     }
0698   }
0699 }
0700 
0701 /**
0702   * @}
0703   */
0704 
0705 #endif /* HAL_DMA_MODULE_ENABLED */
0706 /**
0707   * @}
0708   */
0709 
0710 /**
0711   * @}
0712   */
0713