STM32H735xx HAL User Manual
stm32h7xx_hal_dma_ex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32h7xx_hal_dma_ex.c
00004   * @author  MCD Application Team
00005   * @brief   DMA Extension HAL module driver
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the DMA Extension peripheral:
00008   *           + Extended features functions
00009   *
00010   @verbatim
00011   ==============================================================================
00012                         ##### How to use this driver #####
00013   ==============================================================================
00014   [..]
00015   The DMA Extension HAL driver can be used as follows:
00016    (+) Start a multi buffer transfer using the HAL_DMA_MultiBufferStart() function
00017        for polling mode or HAL_DMA_MultiBufferStart_IT() for interrupt mode.
00018 
00019    (+) Configure the DMA_MUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
00020    (+) Configure the DMA_MUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function.
00021        Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used
00022        to respectively enable/disable the request generator.
00023 
00024    (+) To handle the DMAMUX Interrupts, the function  HAL_DMAEx_MUX_IRQHandler should be called from
00025        the DMAMUX IRQ handler i.e DMAMUX1_OVR_IRQHandler or DMAMUX2_OVR_IRQHandler .
00026        As only one interrupt line is available for all DMAMUX channels and request generators , HAL_DMA_MUX_IRQHandler should be
00027        called with, as parameter, the appropriate DMA handle as many as used DMAs in the user project
00028       (exception done if a given DMA is not using the DMAMUX SYNC block neither a request generator)
00029 
00030      -@-  In Memory-to-Memory transfer mode, Multi (Double) Buffer mode is not allowed.
00031      -@-  When Multi (Double) Buffer mode is enabled, the transfer is circular by default.
00032      -@-  In Multi (Double) buffer mode, it is possible to update the base address for
00033           the AHB memory port on the fly (DMA_SxM0AR or DMA_SxM1AR) when the stream is enabled.
00034      -@-  Multi (Double) buffer mode is possible with DMA and BDMA instances.
00035 
00036   @endverbatim
00037   ******************************************************************************
00038   * @attention
00039   *
00040   * Copyright (c) 2017 STMicroelectronics.
00041   * All rights reserved.
00042   *
00043   * This software is licensed under terms that can be found in the LICENSE file
00044   * in the root directory of this software component.
00045   * If no LICENSE file comes with this software, it is provided AS-IS.
00046   *
00047   ******************************************************************************
00048   */
00049 
00050 /* Includes ------------------------------------------------------------------*/
00051 #include "stm32h7xx_hal.h"
00052 
00053 /** @addtogroup STM32H7xx_HAL_Driver
00054   * @{
00055   */
00056 
00057 /** @defgroup DMAEx DMAEx
00058   * @brief DMA Extended HAL module driver
00059   * @{
00060   */
00061 
00062 #ifdef HAL_DMA_MODULE_ENABLED
00063 
00064 /* Private types -------------------------------------------------------------*/
00065 /* Private variables ---------------------------------------------------------*/
00066 /* Private Constants ---------------------------------------------------------*/
00067 /* Private macros ------------------------------------------------------------*/
00068 /* Private functions ---------------------------------------------------------*/
00069 /** @addtogroup DMAEx_Private_Functions
00070   * @{
00071   */
00072 
00073 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
00074 
00075 /**
00076   * @}
00077   */
00078 
00079 /* Exported functions ---------------------------------------------------------*/
00080 
00081 /** @addtogroup DMAEx_Exported_Functions
00082   * @{
00083   */
00084 
00085 
00086 /** @addtogroup DMAEx_Exported_Functions_Group1
00087   *
00088 @verbatim
00089  ===============================================================================
00090                 #####  Extended features functions  #####
00091  ===============================================================================
00092     [..]  This section provides functions allowing to:
00093       (+) Configure the source, destination address and data length and
00094           Start MultiBuffer DMA transfer
00095       (+) Configure the source, destination address and data length and
00096           Start MultiBuffer DMA transfer with interrupt
00097       (+) Change on the fly the memory0 or memory1 address.
00098       (+) Configure the DMA_MUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
00099       (+) Configure the DMA_MUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function.
00100       (+) Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used
00101           to respectively enable/disable the request generator.
00102       (+) Handle DMAMUX interrupts using HAL_DMAEx_MUX_IRQHandler : should be called from
00103           the DMAMUX IRQ handler i.e DMAMUX1_OVR_IRQHandler or DMAMUX2_OVR_IRQHandler
00104 
00105 @endverbatim
00106   * @{
00107   */
00108 
00109 
00110 /**
00111   * @brief  Starts the multi_buffer DMA Transfer.
00112   * @param  hdma      : pointer to a DMA_HandleTypeDef structure that contains
00113   *                     the configuration information for the specified DMA Stream.
00114   * @param  SrcAddress: The source memory Buffer address
00115   * @param  DstAddress: The destination memory Buffer address
00116   * @param  SecondMemAddress: The second memory Buffer address in case of multi buffer Transfer
00117   * @param  DataLength: The length of data to be transferred from source to destination
00118   * @retval HAL status
00119   */
00120 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
00121 {
00122   HAL_StatusTypeDef status = HAL_OK;
00123   __IO uint32_t *ifcRegister_Base; /* DMA Stream Interrupt Clear register */
00124 
00125   /* Check the parameters */
00126   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
00127   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
00128 
00129   /* Memory-to-memory transfer not supported in double buffering mode */
00130   if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
00131   {
00132     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
00133     status = HAL_ERROR;
00134   }
00135   else
00136   {
00137     /* Process Locked */
00138     __HAL_LOCK(hdma);
00139 
00140     if(HAL_DMA_STATE_READY == hdma->State)
00141     {
00142       /* Change DMA peripheral state */
00143       hdma->State = HAL_DMA_STATE_BUSY;
00144 
00145       /* Initialize the error code */
00146       hdma->ErrorCode = HAL_DMA_ERROR_NONE;
00147 
00148       if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
00149       {
00150         /* Enable the Double buffer mode */
00151         ((DMA_Stream_TypeDef   *)hdma->Instance)->CR |= DMA_SxCR_DBM;
00152 
00153         /* Configure DMA Stream destination address */
00154         ((DMA_Stream_TypeDef   *)hdma->Instance)->M1AR = SecondMemAddress;
00155 
00156         /* Calculate the interrupt clear flag register (IFCR) base address  */
00157         ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 8U));
00158 
00159         /* Clear all flags */
00160         *ifcRegister_Base = 0x3FUL << (hdma->StreamIndex & 0x1FU);
00161       }
00162       else /* BDMA instance(s) */
00163       {
00164         /* Enable the Double buffer mode */
00165         ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR |= (BDMA_CCR_DBM | BDMA_CCR_CIRC);
00166 
00167         /* Configure DMA Stream destination address */
00168         ((BDMA_Channel_TypeDef   *)hdma->Instance)->CM1AR = SecondMemAddress;
00169 
00170         /* Calculate the interrupt clear flag register (IFCR) base address  */
00171         ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 4U));
00172 
00173         /* Clear all flags */
00174         *ifcRegister_Base = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
00175       }
00176 
00177       if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
00178       {
00179         /* Configure the source, destination address and the data length */
00180         DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
00181 
00182         /* Clear the DMAMUX synchro overrun flag */
00183         hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
00184 
00185         if(hdma->DMAmuxRequestGen != 0U)
00186         {
00187           /* Clear the DMAMUX request generator overrun flag */
00188           hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
00189         }
00190       }
00191 
00192       /* Enable the peripheral */
00193       __HAL_DMA_ENABLE(hdma);
00194     }
00195     else
00196     {
00197       /* Set the error code to busy */
00198       hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
00199 
00200       /* Return error status */
00201       status = HAL_ERROR;
00202     }
00203   }
00204   return status;
00205 }
00206 
00207 /**
00208   * @brief  Starts the multi_buffer DMA Transfer with interrupt enabled.
00209   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
00210   *                     the configuration information for the specified DMA Stream.
00211   * @param  SrcAddress: The source memory Buffer address
00212   * @param  DstAddress: The destination memory Buffer address
00213   * @param  SecondMemAddress: The second memory Buffer address in case of multi buffer Transfer
00214   * @param  DataLength: The length of data to be transferred from source to destination
00215   * @retval HAL status
00216   */
00217 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
00218 {
00219   HAL_StatusTypeDef status = HAL_OK;
00220   __IO uint32_t *ifcRegister_Base; /* DMA Stream Interrupt Clear register */
00221 
00222   /* Check the parameters */
00223   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
00224   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
00225 
00226   /* Memory-to-memory transfer not supported in double buffering mode */
00227   if(hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
00228   {
00229     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
00230     return HAL_ERROR;
00231   }
00232 
00233   /* Process locked */
00234   __HAL_LOCK(hdma);
00235 
00236   if(HAL_DMA_STATE_READY == hdma->State)
00237   {
00238     /* Change DMA peripheral state */
00239     hdma->State = HAL_DMA_STATE_BUSY;
00240 
00241     /* Initialize the error code */
00242     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
00243 
00244     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
00245     {
00246       /* Enable the Double buffer mode */
00247       ((DMA_Stream_TypeDef   *)hdma->Instance)->CR |= DMA_SxCR_DBM;
00248 
00249       /* Configure DMA Stream destination address */
00250       ((DMA_Stream_TypeDef   *)hdma->Instance)->M1AR = SecondMemAddress;
00251 
00252       /* Calculate the interrupt clear flag register (IFCR) base address  */
00253       ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 8U));
00254 
00255       /* Clear all flags */
00256       *ifcRegister_Base = 0x3FUL << (hdma->StreamIndex & 0x1FU);
00257     }
00258     else /* BDMA instance(s) */
00259     {
00260       /* Enable the Double buffer mode */
00261       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR |= (BDMA_CCR_DBM | BDMA_CCR_CIRC);
00262 
00263       /* Configure DMA Stream destination address */
00264       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CM1AR = SecondMemAddress;
00265 
00266       /* Calculate the interrupt clear flag register (IFCR) base address  */
00267       ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 4U));
00268 
00269       /* Clear all flags */
00270       *ifcRegister_Base = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
00271     }
00272 
00273     /* Configure the source, destination address and the data length */
00274     DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
00275 
00276     if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
00277     {
00278       /* Clear the DMAMUX synchro overrun flag */
00279       hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
00280 
00281       if(hdma->DMAmuxRequestGen != 0U)
00282       {
00283         /* Clear the DMAMUX request generator overrun flag */
00284         hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
00285       }
00286     }
00287 
00288     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
00289     {
00290       /* Enable Common interrupts*/
00291       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));
00292       ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR |= DMA_IT_FE;
00293 
00294       if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
00295       {
00296         /*Enable Half Transfer IT if corresponding Callback is set*/
00297         ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  |= DMA_IT_HT;
00298       }
00299     }
00300     else /* BDMA instance(s) */
00301     {
00302       /* Enable Common interrupts*/
00303       MODIFY_REG(((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR, (BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE), (BDMA_CCR_TCIE | BDMA_CCR_TEIE));
00304 
00305       if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
00306       {
00307         /*Enable Half Transfer IT if corresponding Callback is set*/
00308         ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR  |= BDMA_CCR_HTIE;
00309       }
00310     }
00311 
00312     if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
00313     {
00314       /* Check if DMAMUX Synchronization is enabled*/
00315       if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
00316       {
00317         /* Enable DMAMUX sync overrun IT*/
00318         hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
00319       }
00320 
00321       if(hdma->DMAmuxRequestGen != 0U)
00322       {
00323         /* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/
00324         /* enable the request gen overrun IT*/
00325         hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
00326       }
00327     }
00328 
00329     /* Enable the peripheral */
00330     __HAL_DMA_ENABLE(hdma);
00331   }
00332   else
00333   {
00334     /* Set the error code to busy */
00335     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
00336 
00337     /* Return error status */
00338     status = HAL_ERROR;
00339   }
00340   return status;
00341 }
00342 
00343 /**
00344   * @brief  Change the memory0 or memory1 address on the fly.
00345   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
00346   *                     the configuration information for the specified DMA Stream.
00347   * @param  Address:    The new address
00348   * @param  memory:     the memory to be changed, This parameter can be one of
00349   *                     the following values:
00350   *                      MEMORY0 /
00351   *                      MEMORY1
00352   * @note   The MEMORY0 address can be changed only when the current transfer use
00353   *         MEMORY1 and the MEMORY1 address can be changed only when the current
00354   *         transfer use MEMORY0.
00355   * @retval HAL status
00356   */
00357 HAL_StatusTypeDef HAL_DMAEx_ChangeMemory(DMA_HandleTypeDef *hdma, uint32_t Address, HAL_DMA_MemoryTypeDef memory)
00358 {
00359   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
00360   {
00361     if(memory == MEMORY0)
00362     {
00363       /* change the memory0 address */
00364       ((DMA_Stream_TypeDef   *)hdma->Instance)->M0AR = Address;
00365     }
00366     else
00367     {
00368       /* change the memory1 address */
00369       ((DMA_Stream_TypeDef   *)hdma->Instance)->M1AR = Address;
00370     }
00371   }
00372   else /* BDMA instance(s) */
00373   {
00374     if(memory == MEMORY0)
00375     {
00376       /* change the memory0 address */
00377       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CM0AR = Address;
00378     }
00379     else
00380     {
00381       /* change the memory1 address */
00382       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CM1AR = Address;
00383     }
00384   }
00385 
00386   return HAL_OK;
00387 }
00388 
00389 /**
00390   * @brief  Configure the DMAMUX synchronization parameters for a given DMA stream (instance).
00391   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
00392   *                     the configuration information for the specified DMA Stream.
00393   * @param  pSyncConfig : pointer to HAL_DMA_MuxSyncConfigTypeDef : contains the DMAMUX synchronization parameters
00394   * @retval HAL status
00395   */
00396 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxSync(DMA_HandleTypeDef *hdma, HAL_DMA_MuxSyncConfigTypeDef *pSyncConfig)
00397 {
00398   uint32_t syncSignalID = 0;
00399   uint32_t syncPolarity = 0;
00400 
00401   /* Check the parameters */
00402   assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance));
00403   assert_param(IS_DMAMUX_SYNC_STATE(pSyncConfig->SyncEnable));
00404   assert_param(IS_DMAMUX_SYNC_EVENT(pSyncConfig->EventEnable));
00405   assert_param(IS_DMAMUX_SYNC_REQUEST_NUMBER(pSyncConfig->RequestNumber));
00406 
00407   if(pSyncConfig->SyncEnable == ENABLE)
00408   {
00409     assert_param(IS_DMAMUX_SYNC_POLARITY(pSyncConfig->SyncPolarity));
00410 
00411     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
00412     {
00413       assert_param(IS_DMA_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID));
00414     }
00415     else
00416     {
00417       assert_param(IS_BDMA_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID));
00418     }
00419     syncSignalID = pSyncConfig->SyncSignalID;
00420     syncPolarity = pSyncConfig->SyncPolarity;
00421   }
00422 
00423   /*Check if the DMA state is ready */
00424   if(hdma->State == HAL_DMA_STATE_READY)
00425   {
00426     /* Process Locked */
00427     __HAL_LOCK(hdma);
00428 
00429     /* Disable the synchronization and event generation before applying a new config */
00430     CLEAR_BIT(hdma->DMAmuxChannel->CCR,(DMAMUX_CxCR_SE | DMAMUX_CxCR_EGE));
00431 
00432     /* Set the new synchronization parameters (and keep the request ID filled during the Init)*/
00433     MODIFY_REG( hdma->DMAmuxChannel->CCR, \
00434                (~DMAMUX_CxCR_DMAREQ_ID) , \
00435                (syncSignalID << DMAMUX_CxCR_SYNC_ID_Pos)       | \
00436                ((pSyncConfig->RequestNumber - 1U) << DMAMUX_CxCR_NBREQ_Pos) | \
00437                syncPolarity | ((uint32_t)pSyncConfig->SyncEnable << DMAMUX_CxCR_SE_Pos)    | \
00438                ((uint32_t)pSyncConfig->EventEnable << DMAMUX_CxCR_EGE_Pos));
00439 
00440       /* Process Locked */
00441     __HAL_UNLOCK(hdma);
00442 
00443     return HAL_OK;
00444   }
00445   else
00446   {
00447     /* Set the error code to busy */
00448     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
00449 
00450     /* Return error status */
00451     return HAL_ERROR;
00452   }
00453 }
00454 
00455 /**
00456   * @brief  Configure the DMAMUX request generator block used by the given DMA stream (instance).
00457   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
00458   *                     the configuration information for the specified DMA Stream.
00459   * @param  pRequestGeneratorConfig : pointer to HAL_DMA_MuxRequestGeneratorConfigTypeDef :
00460   *         contains the request generator parameters.
00461   *
00462   * @retval HAL status
00463   */
00464 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxRequestGenerator (DMA_HandleTypeDef *hdma, HAL_DMA_MuxRequestGeneratorConfigTypeDef *pRequestGeneratorConfig)
00465 {
00466   HAL_StatusTypeDef status;
00467   HAL_DMA_StateTypeDef temp_state = hdma->State;
00468 
00469   /* Check the parameters */
00470   assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance));
00471 
00472   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
00473   {
00474     assert_param(IS_DMA_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
00475   }
00476   else
00477   {
00478     assert_param(IS_BDMA_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
00479   }
00480 
00481 
00482   assert_param(IS_DMAMUX_REQUEST_GEN_POLARITY(pRequestGeneratorConfig->Polarity));
00483   assert_param(IS_DMAMUX_REQUEST_GEN_REQUEST_NUMBER(pRequestGeneratorConfig->RequestNumber));
00484 
00485   /* check if the DMA state is ready
00486      and DMA is using a DMAMUX request generator block
00487   */
00488   if(hdma->DMAmuxRequestGen == 0U)
00489   {
00490     /* Set the error code to busy */
00491     hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
00492 
00493     /* error status */
00494     status = HAL_ERROR;
00495   }
00496   else if(((hdma->DMAmuxRequestGen->RGCR & DMAMUX_RGxCR_GE) == 0U) && (temp_state == HAL_DMA_STATE_READY))
00497   {
00498     /* RequestGenerator must be disable prior to the configuration i.e GE bit is 0 */
00499 
00500     /* Process Locked */
00501     __HAL_LOCK(hdma);
00502 
00503     /* Set the request generator new parameters */
00504     hdma->DMAmuxRequestGen->RGCR = pRequestGeneratorConfig->SignalID | \
00505                                   ((pRequestGeneratorConfig->RequestNumber - 1U) << DMAMUX_RGxCR_GNBREQ_Pos)| \
00506                                   pRequestGeneratorConfig->Polarity;
00507     /* Process Locked */
00508     __HAL_UNLOCK(hdma);
00509 
00510     return HAL_OK;
00511   }
00512   else
00513   {
00514     /* Set the error code to busy */
00515     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
00516 
00517     /* error status */
00518     status = HAL_ERROR;
00519   }
00520 
00521   return status;
00522 }
00523 
00524 /**
00525   * @brief  Enable the DMAMUX request generator block used by the given DMA stream (instance).
00526   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
00527   *                     the configuration information for the specified DMA Stream.
00528   * @retval HAL status
00529   */
00530 HAL_StatusTypeDef HAL_DMAEx_EnableMuxRequestGenerator (DMA_HandleTypeDef *hdma)
00531 {
00532   /* Check the parameters */
00533   assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance));
00534 
00535   /* check if the DMA state is ready
00536      and DMA is using a DMAMUX request generator block */
00537   if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0U))
00538   {
00539     /* Enable the request generator*/
00540     hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_GE;
00541 
00542    return HAL_OK;
00543  }
00544  else
00545  {
00546    return HAL_ERROR;
00547  }
00548 }
00549 
00550 /**
00551   * @brief  Disable the DMAMUX request generator block used by the given DMA stream (instance).
00552   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
00553   *                     the configuration information for the specified DMA Stream.
00554   * @retval HAL status
00555   */
00556 HAL_StatusTypeDef HAL_DMAEx_DisableMuxRequestGenerator (DMA_HandleTypeDef *hdma)
00557 {
00558   /* Check the parameters */
00559   assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance));
00560 
00561   /* check if the DMA state is ready
00562      and DMA is using a DMAMUX request generator block */
00563   if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0U))
00564   {
00565     /* Disable the request generator*/
00566     hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_GE;
00567 
00568    return HAL_OK;
00569  }
00570  else
00571  {
00572    return HAL_ERROR;
00573  }
00574 }
00575 
00576 /**
00577   * @brief  Handles DMAMUX interrupt request.
00578   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
00579   *               the configuration information for the specified DMA Stream.
00580   * @retval None
00581   */
00582 void HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef *hdma)
00583 {
00584   /* Check for DMAMUX Synchronization overrun */
00585   if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
00586   {
00587     /* Disable the synchro overrun interrupt */
00588     hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
00589 
00590     /* Clear the DMAMUX synchro overrun flag */
00591     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
00592 
00593     /* Update error code */
00594     hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
00595 
00596     if(hdma->XferErrorCallback != NULL)
00597     {
00598       /* Transfer error callback */
00599       hdma->XferErrorCallback(hdma);
00600     }
00601   }
00602 
00603   if(hdma->DMAmuxRequestGen != 0)
00604   {
00605    /* if using a DMAMUX request generator block Check for DMAMUX request generator overrun */
00606     if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
00607     {
00608       /* Disable the request gen overrun interrupt */
00609       hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
00610 
00611       /* Clear the DMAMUX request generator overrun flag */
00612       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
00613 
00614       /* Update error code */
00615       hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
00616 
00617       if(hdma->XferErrorCallback != NULL)
00618       {
00619         /* Transfer error callback */
00620         hdma->XferErrorCallback(hdma);
00621       }
00622     }
00623   }
00624 }
00625 
00626 
00627 /**
00628   * @}
00629   */
00630 
00631 /**
00632   * @}
00633   */
00634 
00635 /** @addtogroup DMAEx_Private_Functions
00636   * @{
00637   */
00638 
00639 /**
00640   * @brief  Set the DMA Transfer parameter.
00641   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
00642   *                     the configuration information for the specified DMA Stream.
00643   * @param  SrcAddress: The source memory Buffer address
00644   * @param  DstAddress: The destination memory Buffer address
00645   * @param  DataLength: The length of data to be transferred from source to destination
00646   * @retval HAL status
00647   */
00648 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
00649 {
00650   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
00651   {
00652     /* Configure DMA Stream data length */
00653     ((DMA_Stream_TypeDef   *)hdma->Instance)->NDTR = DataLength;
00654 
00655     /* Peripheral to Memory */
00656     if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
00657     {
00658       /* Configure DMA Stream destination address */
00659       ((DMA_Stream_TypeDef   *)hdma->Instance)->PAR = DstAddress;
00660 
00661       /* Configure DMA Stream source address */
00662       ((DMA_Stream_TypeDef   *)hdma->Instance)->M0AR = SrcAddress;
00663     }
00664     /* Memory to Peripheral */
00665     else
00666     {
00667       /* Configure DMA Stream source address */
00668       ((DMA_Stream_TypeDef   *)hdma->Instance)->PAR = SrcAddress;
00669 
00670       /* Configure DMA Stream destination address */
00671       ((DMA_Stream_TypeDef   *)hdma->Instance)->M0AR = DstAddress;
00672     }
00673   }
00674   else /* BDMA instance(s) */
00675   {
00676     /* Configure DMA Stream data length */
00677     ((BDMA_Channel_TypeDef   *)hdma->Instance)->CNDTR = DataLength;
00678 
00679     /* Peripheral to Memory */
00680     if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
00681     {
00682       /* Configure DMA Stream destination address */
00683       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CPAR = DstAddress;
00684 
00685       /* Configure DMA Stream source address */
00686       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CM0AR = SrcAddress;
00687     }
00688     /* Memory to Peripheral */
00689     else
00690     {
00691       /* Configure DMA Stream source address */
00692       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CPAR = SrcAddress;
00693 
00694       /* Configure DMA Stream destination address */
00695       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CM0AR = DstAddress;
00696     }
00697   }
00698 }
00699 
00700 /**
00701   * @}
00702   */
00703 
00704 #endif /* HAL_DMA_MODULE_ENABLED */
00705 /**
00706   * @}
00707   */
00708 
00709 /**
00710   * @}
00711   */
00712