Index: ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c	(revision 75)
+++ ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c	(revision 75)
@@ -0,0 +1,1899 @@
+/**
+  ******************************************************************************
+  * @file    stm32h7xx_hal_mdma.c
+  * @author  MCD Application Team
+  * @brief  This file provides firmware functions to manage the following
+  *         functionalities of the Master Direct Memory Access (MDMA) peripheral:
+  *           + Initialization/de-initialization functions
+  *           + I/O operation functions
+  *           + Peripheral State and errors functions
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2017 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  @verbatim
+  ==============================================================================
+                        ##### How to use this driver #####
+  ==============================================================================
+  [..]
+   (#) Enable and configure the peripheral to be connected to the MDMA Channel
+       (except for internal SRAM/FLASH memories: no initialization is
+       necessary) please refer to Reference manual for connection between peripherals
+       and MDMA requests.
+
+   (#)
+       For a given Channel use HAL_MDMA_Init function to program the required configuration through the following parameters:
+       transfer request , channel priority, data endianness, Source increment, destination increment ,
+       source data size, destination data size, data alignment, source Burst, destination Burst ,
+       buffer Transfer Length, Transfer Trigger Mode (buffer transfer, block transfer, repeated block transfer
+       or full transfer) source and destination block address offset, mask address and data.
+
+       If using the MDMA in linked list mode then use function HAL_MDMA_LinkedList_CreateNode to fill a transfer node.
+       Note that parameters given to the function HAL_MDMA_Init corresponds always to the node zero.
+       Use function HAL_MDMA_LinkedList_AddNode to connect the created node to the linked list at a given position.
+       User can make a linked list circular using function HAL_MDMA_LinkedList_EnableCircularMode , this function will automatically connect the
+       last node of the list to the first one in order to make the list circular.
+       In this case the linked list will loop on node 1 : first node connected after the initial transfer defined by the HAL_MDMA_Init
+
+      -@-   The initial transfer itself (node 0 corresponding to the Init).
+            User can disable the circular mode using function HAL_MDMA_LinkedList_DisableCircularMode, this function will then remove
+            the connection between last node and first one.
+
+       Function HAL_MDMA_LinkedList_RemoveNode can be used to remove (disconnect) a node from the transfer linked list.
+       When a linked list is circular (last node connected to first one), if removing node1  (node where the linked list loops),
+       the linked list remains circular and node 2 becomes the first one.
+       Note that if the linked list is made circular the transfer will loop infinitely (or until aborted by the user).
+
+    [..]
+       (+) User can select the transfer trigger mode (parameter TransferTriggerMode) to define the amount of data to be
+           transfer upon a request :
+             (++) MDMA_BUFFER_TRANSFER : each request triggers a transfer of BufferTransferLength data
+               with BufferTransferLength defined within the HAL_MDMA_Init.
+             (++) MDMA_BLOCK_TRANSFER : each request triggers a transfer of a block
+               with block size defined within the function HAL_MDMA_Start/HAL_MDMA_Start_IT
+               or within the current linked list node parameters.
+             (++) MDMA_REPEAT_BLOCK_TRANSFER : each request triggers a transfer of a number of blocks
+               with block size and number of blocks defined within the function HAL_MDMA_Start/HAL_MDMA_Start_IT
+               or within the current linked list node parameters.
+             (++) MDMA_FULL_TRANSFER : each request triggers a full transfer
+              all blocks and all nodes(if a linked list has been created using HAL_MDMA_LinkedList_CreateNode \ HAL_MDMA_LinkedList_AddNode).
+
+     *** Polling mode IO operation ***
+     =================================
+    [..]
+          (+) Use HAL_MDMA_Start() to start MDMA transfer after the configuration of Source
+              address and destination address and the Length of data to be transferred.
+          (+) Use HAL_MDMA_PollForTransfer() to poll for the end of current transfer or a transfer level
+             In this case a fixed Timeout can be configured by User depending from his application.
+          (+) Use HAL_MDMA_Abort() function to abort the current transfer : blocking method this API returns
+              when the abort ends or timeout (should not be called from an interrupt service routine).
+
+     *** Interrupt mode IO operation ***
+     ===================================
+    [..]
+          (+) Configure the MDMA interrupt priority using HAL_NVIC_SetPriority()
+          (+) Enable the MDMA IRQ handler using HAL_NVIC_EnableIRQ()
+          (+) Use HAL_MDMA_Start_IT() to start MDMA transfer after the configuration of
+              Source address and destination address and the Length of data to be transferred. In this
+              case the MDMA interrupt is configured.
+          (+) Use HAL_MDMA_IRQHandler() called under MDMA_IRQHandler() Interrupt subroutine
+          (+) At the end of data transfer HAL_MDMA_IRQHandler() function is executed and user can
+              add his own function by customization of function pointer XferCpltCallback and
+              XferErrorCallback (i.e a member of MDMA handle structure).
+
+          (+) Use HAL_MDMA_Abort_IT() function to abort the current transfer : non-blocking method. This API will finish the execution immediately
+              then the callback XferAbortCallback (if specified  by the user) is asserted once the MDMA channel has effectively aborted.
+              (could be called from an interrupt service routine).
+
+          (+) Use functions HAL_MDMA_RegisterCallback and HAL_MDMA_UnRegisterCallback respectevely to register unregister user callbacks
+              from the following list :
+              (++) XferCpltCallback            : transfer complete callback.
+              (++) XferBufferCpltCallback      : buffer transfer complete callback.
+              (++) XferBlockCpltCallback       : block transfer complete callback.
+              (++) XferRepeatBlockCpltCallback : repeated block transfer complete callback.
+              (++) XferErrorCallback           : transfer error callback.
+              (++) XferAbortCallback           : transfer abort complete callback.
+
+    [..]
+         (+)  If the transfer Request corresponds to SW request (MDMA_REQUEST_SW) User can use function HAL_MDMA_GenerateSWRequest to
+              trigger requests manually. Function HAL_MDMA_GenerateSWRequest must be used with the following precautions:
+              (++) This function returns an error if used while the Transfer has ended or not started.
+              (++) If used while the current request has not been served yet (current request transfer on going)
+                this function returns an error and the new request is ignored.
+
+              Generally this function should be used in conjunctions with the MDMA callbacks:
+              (++) example 1:
+                 (+++) Configure a transfer with request set to MDMA_REQUEST_SW and trigger mode set to MDMA_BUFFER_TRANSFER
+                 (+++) Register a callback for buffer transfer complete (using callback ID set to HAL_MDMA_XFER_BUFFERCPLT_CB_ID)
+                 (+++) After calling HAL_MDMA_Start_IT the MDMA will issue the transfer of a first BufferTransferLength data.
+                 (+++) When the buffer transfer complete callback is asserted first buffer has been transferred and user can ask for a new buffer transfer
+                   request using HAL_MDMA_GenerateSWRequest.
+
+              (++) example 2:
+                 (+++) Configure a transfer with request set to MDMA_REQUEST_SW and trigger mode set to MDMA_BLOCK_TRANSFER
+                 (+++) Register a callback for block transfer complete (using callback ID HAL_MDMA_XFER_BLOCKCPLT_CB_ID)
+                 (+++) After calling HAL_MDMA_Start_IT the MDMA will issue the transfer of a first block of data.
+                 (+++) When the block transfer complete callback is asserted the first block has been transferred and user can ask
+                   for a new block transfer request using HAL_MDMA_GenerateSWRequest.
+
+    [..]  Use HAL_MDMA_GetState() function to return the MDMA state and HAL_MDMA_GetError() in case of error detection.
+
+     *** MDMA HAL driver macros list ***
+     =============================================
+     [..]
+       Below the list of most used macros in MDMA HAL driver.
+
+      (+) __HAL_MDMA_ENABLE: Enable the specified MDMA Channel.
+      (+) __HAL_MDMA_DISABLE: Disable the specified MDMA Channel.
+      (+) __HAL_MDMA_GET_FLAG: Get the MDMA Channel pending flags.
+      (+) __HAL_MDMA_CLEAR_FLAG: Clear the MDMA Channel pending flags.
+      (+) __HAL_MDMA_ENABLE_IT: Enable the specified MDMA Channel interrupts.
+      (+) __HAL_MDMA_DISABLE_IT: Disable the specified MDMA Channel interrupts.
+      (+) __HAL_MDMA_GET_IT_SOURCE: Check whether the specified MDMA Channel interrupt has occurred or not.
+
+     [..]
+      (@) You can refer to the header file of the MDMA HAL driver for more useful macros.
+
+    [..]
+
+  @endverbatim
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+  * @{
+  */
+
+/** @defgroup MDMA  MDMA
+  * @brief MDMA HAL module driver
+  * @{
+  */
+
+#ifdef HAL_MDMA_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @addtogroup MDMA_Private_Constants
+ * @{
+ */
+#define HAL_TIMEOUT_MDMA_ABORT    5U    /* 5 ms */
+#define HAL_MDMA_CHANNEL_SIZE     0x40U /* an MDMA instance channel size is 64 byte  */
+/**
+  * @}
+  */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup MDMA_Private_Functions_Prototypes
+  * @{
+  */
+static void MDMA_SetConfig(MDMA_HandleTypeDef *hmdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t BlockDataLength, uint32_t BlockCount);
+static void MDMA_Init(MDMA_HandleTypeDef *hmdma);
+
+/**
+  * @}
+  */
+
+/** @addtogroup MDMA_Exported_Functions MDMA Exported Functions
+  * @{
+  */
+
+/** @addtogroup MDMA_Exported_Functions_Group1
+  *
+@verbatim
+ ===============================================================================
+             ##### Initialization and de-initialization functions  #####
+ ===============================================================================
+    [..]
+    This section provides functions allowing to :
+      Initialize and de-initialize the MDMA channel.
+      Register and Unregister MDMA callbacks
+    [..]
+    The HAL_MDMA_Init() function follows the MDMA channel configuration procedures as described in
+    reference manual.
+    The HAL_MDMA_DeInit function allows to deinitialize the MDMA channel.
+    HAL_MDMA_RegisterCallback and  HAL_MDMA_UnRegisterCallback functions allows
+    respectevely to register/unregister an MDMA callback function.
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Initializes the MDMA according to the specified
+  *         parameters in the MDMA_InitTypeDef and create the associated handle.
+  * @param  hmdma: Pointer to a MDMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified MDMA Channel.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_Init(MDMA_HandleTypeDef *hmdma)
+{
+  uint32_t tickstart = HAL_GetTick();
+
+  /* Check the MDMA peripheral handle */
+  if(hmdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Check the parameters */
+  assert_param(IS_MDMA_STREAM_ALL_INSTANCE(hmdma->Instance));
+  assert_param(IS_MDMA_PRIORITY(hmdma->Init.Priority));
+  assert_param(IS_MDMA_ENDIANNESS_MODE(hmdma->Init.Endianness));
+  assert_param(IS_MDMA_REQUEST(hmdma->Init.Request));
+  assert_param(IS_MDMA_SOURCE_INC(hmdma->Init.SourceInc));
+  assert_param(IS_MDMA_DESTINATION_INC(hmdma->Init.DestinationInc));
+  assert_param(IS_MDMA_SOURCE_DATASIZE(hmdma->Init.SourceDataSize));
+  assert_param(IS_MDMA_DESTINATION_DATASIZE(hmdma->Init.DestDataSize));
+  assert_param(IS_MDMA_DATA_ALIGNMENT(hmdma->Init.DataAlignment));
+  assert_param(IS_MDMA_SOURCE_BURST(hmdma->Init.SourceBurst));
+  assert_param(IS_MDMA_DESTINATION_BURST(hmdma->Init.DestBurst));
+  assert_param(IS_MDMA_BUFFER_TRANSFER_LENGTH(hmdma->Init.BufferTransferLength));
+  assert_param(IS_MDMA_TRANSFER_TRIGGER_MODE(hmdma->Init.TransferTriggerMode));
+  assert_param(IS_MDMA_BLOCK_ADDR_OFFSET(hmdma->Init.SourceBlockAddressOffset));
+  assert_param(IS_MDMA_BLOCK_ADDR_OFFSET(hmdma->Init.DestBlockAddressOffset));
+
+
+  /* Allocate lock resource */
+  __HAL_UNLOCK(hmdma);
+
+  /* Change MDMA peripheral state */
+  hmdma->State = HAL_MDMA_STATE_BUSY;
+
+  /* Disable the MDMA channel */
+  __HAL_MDMA_DISABLE(hmdma);
+
+  /* Check if the MDMA channel is effectively disabled */
+  while((hmdma->Instance->CCR & MDMA_CCR_EN) != 0U)
+  {
+    /* Check for the Timeout */
+    if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_MDMA_ABORT)
+    {
+      /* Update error code */
+      hmdma->ErrorCode = HAL_MDMA_ERROR_TIMEOUT;
+
+      /* Change the MDMA state */
+      hmdma->State = HAL_MDMA_STATE_ERROR;
+
+      return HAL_ERROR;
+    }
+  }
+
+  /* Initialize the MDMA channel registers */
+  MDMA_Init(hmdma);
+
+  /* Reset the MDMA first/last linkedlist node addresses and node counter */
+  hmdma->FirstLinkedListNodeAddress  = 0;
+  hmdma->LastLinkedListNodeAddress   = 0;
+  hmdma->LinkedListNodeCounter  = 0;
+
+  /* Initialize the error code */
+  hmdma->ErrorCode = HAL_MDMA_ERROR_NONE;
+
+  /* Initialize the MDMA state */
+  hmdma->State = HAL_MDMA_STATE_READY;
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  DeInitializes the MDMA peripheral
+  * @param  hmdma: pointer to a MDMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified MDMA Channel.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_DeInit(MDMA_HandleTypeDef *hmdma)
+{
+
+  /* Check the MDMA peripheral handle */
+  if(hmdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Disable the selected MDMA Channelx */
+  __HAL_MDMA_DISABLE(hmdma);
+
+  /* Reset MDMA Channel control register */
+  hmdma->Instance->CCR  = 0;
+  hmdma->Instance->CTCR = 0;
+  hmdma->Instance->CBNDTR = 0;
+  hmdma->Instance->CSAR = 0;
+  hmdma->Instance->CDAR = 0;
+  hmdma->Instance->CBRUR = 0;
+  hmdma->Instance->CLAR = 0;
+  hmdma->Instance->CTBR = 0;
+  hmdma->Instance->CMAR = 0;
+  hmdma->Instance->CMDR = 0;
+
+  /* Clear all flags */
+  __HAL_MDMA_CLEAR_FLAG(hmdma,(MDMA_FLAG_TE | MDMA_FLAG_CTC | MDMA_FLAG_BRT | MDMA_FLAG_BT | MDMA_FLAG_BFTC));
+
+  /* Reset the  MDMA first/last linkedlist node addresses and node counter */
+  hmdma->FirstLinkedListNodeAddress  = 0;
+  hmdma->LastLinkedListNodeAddress   = 0;
+  hmdma->LinkedListNodeCounter  = 0;
+
+  /* Initialize the error code */
+  hmdma->ErrorCode = HAL_MDMA_ERROR_NONE;
+
+  /* Initialize the MDMA state */
+  hmdma->State = HAL_MDMA_STATE_RESET;
+
+  /* Release Lock */
+  __HAL_UNLOCK(hmdma);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Config the Post request Mask address and Mask data
+  * @param  hmdma      : pointer to a MDMA_HandleTypeDef structure that contains
+  *                               the configuration information for the specified MDMA Channel.
+  * @param  MaskAddress: specifies the address to be updated (written) with MaskData after a request is served.
+  * @param  MaskData:    specifies the value to be written to MaskAddress after a request is served.
+  *                      MaskAddress and MaskData could be used to automatically clear a peripheral flag when the request is served.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_ConfigPostRequestMask(MDMA_HandleTypeDef *hmdma, uint32_t MaskAddress, uint32_t MaskData)
+{
+  HAL_StatusTypeDef  status = HAL_OK;
+
+  /* Check the MDMA peripheral handle */
+  if(hmdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hmdma);
+
+  if(HAL_MDMA_STATE_READY == hmdma->State)
+  {
+    /* if HW request set Post Request MaskAddress and MaskData,  */
+    if((hmdma->Instance->CTCR & MDMA_CTCR_SWRM) == 0U)
+    {
+      /* Set the HW request clear Mask and Data */
+      hmdma->Instance->CMAR = MaskAddress;
+      hmdma->Instance->CMDR = MaskData;
+
+      /*
+      -If the request is done by SW : BWM could be set to 1 or 0.
+      -If the request is done by a peripheral :
+         If mask address not set (0) => BWM must be set to 0
+         If mask address set (different than 0) => BWM could be set to 1 or 0
+      */
+      if(MaskAddress == 0U)
+      {
+        hmdma->Instance->CTCR &=  ~MDMA_CTCR_BWM;
+      }
+      else
+      {
+        hmdma->Instance->CTCR |=  MDMA_CTCR_BWM;
+      }
+    }
+    else
+    {
+      /* Return error status */
+      status =  HAL_ERROR;
+    }
+  }
+  else
+  {
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+  /* Release Lock */
+  __HAL_UNLOCK(hmdma);
+
+  return status;
+}
+
+/**
+  * @brief  Register callbacks
+  * @param  hmdma:                pointer to a MDMA_HandleTypeDef structure that contains
+  *                               the configuration information for the specified MDMA Channel.
+  * @param  CallbackID:           User Callback identifier
+  * @param  pCallback:            pointer to callbacsk function.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_RegisterCallback(MDMA_HandleTypeDef *hmdma, HAL_MDMA_CallbackIDTypeDef CallbackID, void (* pCallback)(MDMA_HandleTypeDef *_hmdma))
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  /* Check the MDMA peripheral handle */
+  if(hmdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hmdma);
+
+  if(HAL_MDMA_STATE_READY == hmdma->State)
+  {
+    switch (CallbackID)
+    {
+    case  HAL_MDMA_XFER_CPLT_CB_ID:
+      hmdma->XferCpltCallback = pCallback;
+      break;
+
+    case  HAL_MDMA_XFER_BUFFERCPLT_CB_ID:
+      hmdma->XferBufferCpltCallback = pCallback;
+      break;
+
+    case  HAL_MDMA_XFER_BLOCKCPLT_CB_ID:
+      hmdma->XferBlockCpltCallback = pCallback;
+      break;
+
+    case  HAL_MDMA_XFER_REPBLOCKCPLT_CB_ID:
+      hmdma->XferRepeatBlockCpltCallback = pCallback;
+      break;
+
+    case  HAL_MDMA_XFER_ERROR_CB_ID:
+      hmdma->XferErrorCallback = pCallback;
+      break;
+
+    case  HAL_MDMA_XFER_ABORT_CB_ID:
+      hmdma->XferAbortCallback = pCallback;
+      break;
+
+    default:
+      break;
+    }
+  }
+  else
+  {
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hmdma);
+
+  return status;
+}
+
+/**
+  * @brief  UnRegister callbacks
+  * @param  hmdma:                 pointer to a MDMA_HandleTypeDef structure that contains
+  *                               the configuration information for the specified MDMA Channel.
+  * @param  CallbackID:           User Callback identifier
+  *                               a HAL_MDMA_CallbackIDTypeDef ENUM as parameter.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_UnRegisterCallback(MDMA_HandleTypeDef *hmdma, HAL_MDMA_CallbackIDTypeDef CallbackID)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  /* Check the MDMA peripheral handle */
+  if(hmdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hmdma);
+
+  if(HAL_MDMA_STATE_READY == hmdma->State)
+  {
+    switch (CallbackID)
+    {
+    case  HAL_MDMA_XFER_CPLT_CB_ID:
+      hmdma->XferCpltCallback = NULL;
+      break;
+
+    case  HAL_MDMA_XFER_BUFFERCPLT_CB_ID:
+      hmdma->XferBufferCpltCallback = NULL;
+      break;
+
+    case  HAL_MDMA_XFER_BLOCKCPLT_CB_ID:
+      hmdma->XferBlockCpltCallback = NULL;
+      break;
+
+    case  HAL_MDMA_XFER_REPBLOCKCPLT_CB_ID:
+      hmdma->XferRepeatBlockCpltCallback = NULL;
+      break;
+
+    case  HAL_MDMA_XFER_ERROR_CB_ID:
+      hmdma->XferErrorCallback = NULL;
+      break;
+
+    case  HAL_MDMA_XFER_ABORT_CB_ID:
+      hmdma->XferAbortCallback = NULL;
+      break;
+
+    case   HAL_MDMA_XFER_ALL_CB_ID:
+      hmdma->XferCpltCallback = NULL;
+      hmdma->XferBufferCpltCallback = NULL;
+      hmdma->XferBlockCpltCallback = NULL;
+      hmdma->XferRepeatBlockCpltCallback = NULL;
+      hmdma->XferErrorCallback = NULL;
+      hmdma->XferAbortCallback = NULL;
+      break;
+
+    default:
+      status = HAL_ERROR;
+      break;
+    }
+  }
+  else
+  {
+    status = HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hmdma);
+
+  return status;
+}
+
+/**
+  * @}
+  */
+
+/** @addtogroup MDMA_Exported_Functions_Group2
+ *
+@verbatim
+ ===============================================================================
+                      #####  Linked list operation functions  #####
+ ===============================================================================
+    [..]  This section provides functions allowing to:
+      (+) Create a linked list node
+      (+) Add a node to the MDMA linked list
+      (+) Remove a node from the MDMA linked list
+      (+) Enable/Disable linked list circular mode
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Initializes an MDMA Link Node according to the specified
+  *         parameters in the pMDMA_LinkedListNodeConfig .
+  * @param  pNode: Pointer to a MDMA_LinkNodeTypeDef structure that contains Linked list node
+  *         registers configurations.
+  * @param  pNodeConfig: Pointer to a MDMA_LinkNodeConfTypeDef structure that contains
+  *               the configuration information for the specified MDMA Linked List Node.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_LinkedList_CreateNode(MDMA_LinkNodeTypeDef *pNode, MDMA_LinkNodeConfTypeDef *pNodeConfig)
+{
+  uint32_t addressMask;
+  uint32_t blockoffset;
+
+  /* Check the MDMA peripheral state */
+  if((pNode == NULL) || (pNodeConfig == NULL))
+  {
+    return HAL_ERROR;
+  }
+
+  /* Check the parameters */
+  assert_param(IS_MDMA_PRIORITY(pNodeConfig->Init.Priority));
+  assert_param(IS_MDMA_ENDIANNESS_MODE(pNodeConfig->Init.Endianness));
+  assert_param(IS_MDMA_REQUEST(pNodeConfig->Init.Request));
+  assert_param(IS_MDMA_SOURCE_INC(pNodeConfig->Init.SourceInc));
+  assert_param(IS_MDMA_DESTINATION_INC(pNodeConfig->Init.DestinationInc));
+  assert_param(IS_MDMA_SOURCE_DATASIZE(pNodeConfig->Init.SourceDataSize));
+  assert_param(IS_MDMA_DESTINATION_DATASIZE(pNodeConfig->Init.DestDataSize));
+  assert_param(IS_MDMA_DATA_ALIGNMENT(pNodeConfig->Init.DataAlignment));
+  assert_param(IS_MDMA_SOURCE_BURST(pNodeConfig->Init.SourceBurst));
+  assert_param(IS_MDMA_DESTINATION_BURST(pNodeConfig->Init.DestBurst));
+  assert_param(IS_MDMA_BUFFER_TRANSFER_LENGTH(pNodeConfig->Init.BufferTransferLength));
+  assert_param(IS_MDMA_TRANSFER_TRIGGER_MODE(pNodeConfig->Init.TransferTriggerMode));
+  assert_param(IS_MDMA_BLOCK_ADDR_OFFSET(pNodeConfig->Init.SourceBlockAddressOffset));
+  assert_param(IS_MDMA_BLOCK_ADDR_OFFSET(pNodeConfig->Init.DestBlockAddressOffset));
+
+  assert_param(IS_MDMA_TRANSFER_LENGTH(pNodeConfig->BlockDataLength));
+  assert_param(IS_MDMA_BLOCK_COUNT(pNodeConfig->BlockCount));
+
+
+  /* Configure next Link node Address Register to zero */
+  pNode->CLAR =  0;
+
+  /* Configure the Link Node registers*/
+  pNode->CTBR   = 0;
+  pNode->CMAR   = 0;
+  pNode->CMDR   = 0;
+  pNode->Reserved = 0;
+
+  /* Write new CTCR Register value */
+  pNode->CTCR =  pNodeConfig->Init.SourceInc | pNodeConfig->Init.DestinationInc | \
+    pNodeConfig->Init.SourceDataSize | pNodeConfig->Init.DestDataSize           | \
+      pNodeConfig->Init.DataAlignment| pNodeConfig->Init.SourceBurst            | \
+        pNodeConfig->Init.DestBurst                                             | \
+          ((pNodeConfig->Init.BufferTransferLength - 1U) << MDMA_CTCR_TLEN_Pos) | \
+            pNodeConfig->Init.TransferTriggerMode;
+
+  /* If SW request set the CTCR register to SW Request Mode*/
+  if(pNodeConfig->Init.Request == MDMA_REQUEST_SW)
+  {
+    pNode->CTCR |= MDMA_CTCR_SWRM;
+  }
+
+  /*
+  -If the request is done by SW : BWM could be set to 1 or 0.
+  -If the request is done by a peripheral :
+     If mask address not set (0) => BWM must be set to 0
+     If mask address set (different than 0) => BWM could be set to 1 or 0
+  */
+  if((pNodeConfig->Init.Request == MDMA_REQUEST_SW) || (pNodeConfig->PostRequestMaskAddress != 0U))
+  {
+    pNode->CTCR |=  MDMA_CTCR_BWM;
+  }
+
+  /* Set the new CBNDTR Register value */
+  pNode->CBNDTR = ((pNodeConfig->BlockCount - 1U) << MDMA_CBNDTR_BRC_Pos) & MDMA_CBNDTR_BRC;
+
+  /* if block source address offset is negative set the Block Repeat Source address Update Mode to decrement */
+  if(pNodeConfig->Init.SourceBlockAddressOffset < 0)
+  {
+    pNode->CBNDTR |= MDMA_CBNDTR_BRSUM;
+    /*write new CBRUR Register value : source repeat block offset */
+    blockoffset = (uint32_t)(- pNodeConfig->Init.SourceBlockAddressOffset);
+    pNode->CBRUR = blockoffset & 0x0000FFFFU;
+  }
+  else
+  {
+    /*write new CBRUR Register value : source repeat block offset */
+    pNode->CBRUR = (((uint32_t) pNodeConfig->Init.SourceBlockAddressOffset) & 0x0000FFFFU);
+  }
+
+  /* if block destination address offset is negative set the Block Repeat destination address Update Mode to decrement */
+  if(pNodeConfig->Init.DestBlockAddressOffset < 0)
+  {
+    pNode->CBNDTR |= MDMA_CBNDTR_BRDUM;
+    /*write new CBRUR Register value : destination repeat block offset */
+    blockoffset = (uint32_t)(- pNodeConfig->Init.DestBlockAddressOffset);
+    pNode->CBRUR |= ((blockoffset & 0x0000FFFFU) << MDMA_CBRUR_DUV_Pos);
+  }
+  else
+  {
+    /*write new CBRUR Register value : destination repeat block offset */
+    pNode->CBRUR |= ((((uint32_t)pNodeConfig->Init.DestBlockAddressOffset) & 0x0000FFFFU) << MDMA_CBRUR_DUV_Pos);
+  }
+
+  /* Configure MDMA Link Node data length */
+  pNode->CBNDTR |=  pNodeConfig->BlockDataLength;
+
+  /* Configure MDMA Link Node destination address */
+  pNode->CDAR = pNodeConfig->DstAddress;
+
+  /* Configure MDMA Link Node Source address */
+  pNode->CSAR = pNodeConfig->SrcAddress;
+
+  /* if HW request set the HW request and the requet CleraMask and ClearData MaskData,  */
+  if(pNodeConfig->Init.Request != MDMA_REQUEST_SW)
+  {
+    /* Set the HW request in CTBR register  */
+    pNode->CTBR = pNodeConfig->Init.Request & MDMA_CTBR_TSEL;
+    /* Set the HW request clear Mask and Data */
+    pNode->CMAR = pNodeConfig->PostRequestMaskAddress;
+    pNode->CMDR = pNodeConfig->PostRequestMaskData;
+  }
+
+  addressMask = pNodeConfig->SrcAddress & 0xFF000000U;
+  if((addressMask == 0x20000000U) || (addressMask == 0x00000000U))
+  {
+    /*The AHBSbus is used as source (read operation) on channel x */
+    pNode->CTBR |= MDMA_CTBR_SBUS;
+  }
+
+  addressMask = pNodeConfig->DstAddress & 0xFF000000U;
+  if((addressMask == 0x20000000U) || (addressMask == 0x00000000U))
+  {
+    /*The AHB bus is used as destination (write operation) on channel x */
+    pNode->CTBR |= MDMA_CTBR_DBUS;
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Connect a node to the linked list.
+  * @param  hmdma    : Pointer to a MDMA_HandleTypeDef structure that contains
+  *                    the configuration information for the specified MDMA Channel.
+  * @param  pNewNode : Pointer to a MDMA_LinkNodeTypeDef structure that contains Linked list node
+  *                    to be add to the list.
+  * @param pPrevNode : Pointer to the new node position in the linked list or zero to insert the new node
+  *                    at the end of the list
+  *
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_LinkedList_AddNode(MDMA_HandleTypeDef *hmdma, MDMA_LinkNodeTypeDef *pNewNode, const MDMA_LinkNodeTypeDef *pPrevNode)
+{
+  MDMA_LinkNodeTypeDef *pNode;
+  uint32_t counter = 0, nodeInserted = 0;
+  HAL_StatusTypeDef hal_status = HAL_OK;
+
+  /* Check the MDMA peripheral handle */
+  if((hmdma == NULL) || (pNewNode == NULL))
+  {
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hmdma);
+
+  if(HAL_MDMA_STATE_READY == hmdma->State)
+  {
+    /* Change MDMA peripheral state */
+    hmdma->State = HAL_MDMA_STATE_BUSY;
+
+    /* Check if this is the first node (after the Inititlization node) */
+    if((uint32_t)hmdma->FirstLinkedListNodeAddress == 0U)
+    {
+      if(pPrevNode == NULL)
+      {
+        /* if this is the first node after the initialization
+        connect this node to the node 0 by updating
+        the MDMA channel CLAR register to this node address */
+        hmdma->Instance->CLAR = (uint32_t)pNewNode;
+        /* Set the MDMA handle First linked List node*/
+        hmdma->FirstLinkedListNodeAddress = pNewNode;
+
+        /*reset New node link */
+        pNewNode->CLAR = 0;
+
+        /* Update the Handle last node address */
+        hmdma->LastLinkedListNodeAddress = pNewNode;
+
+        hmdma->LinkedListNodeCounter = 1;
+      }
+      else
+      {
+        hal_status = HAL_ERROR;
+      }
+    }
+    else if(hmdma->FirstLinkedListNodeAddress != pNewNode)
+    {
+      /* Check if the node to insert already exists*/
+      pNode = hmdma->FirstLinkedListNodeAddress;
+      while((counter < hmdma->LinkedListNodeCounter) && (hal_status == HAL_OK))
+      {
+        if(pNode->CLAR == (uint32_t)pNewNode)
+        {
+          hal_status = HAL_ERROR; /* error this node already exist in the linked list and it is not first node */
+        }
+        pNode = (MDMA_LinkNodeTypeDef *)pNode->CLAR;
+        counter++;
+      }
+
+      if(hal_status == HAL_OK)
+      {
+        /* Check if the previous node is the last one in the current list or zero */
+        if((pPrevNode == hmdma->LastLinkedListNodeAddress) || (pPrevNode == NULL))
+        {
+          /* insert the new node at the end of the list */
+          pNewNode->CLAR = hmdma->LastLinkedListNodeAddress->CLAR;
+          hmdma->LastLinkedListNodeAddress->CLAR = (uint32_t)pNewNode;
+          /* Update the Handle last node address */
+          hmdma->LastLinkedListNodeAddress = pNewNode;
+          /* Increment the linked list node counter */
+          hmdma->LinkedListNodeCounter++;
+        }
+        else
+        {
+          /*insert the new node after the pPreviousNode node */
+          pNode = hmdma->FirstLinkedListNodeAddress;
+          counter = 0;
+          while((counter < hmdma->LinkedListNodeCounter) && (nodeInserted == 0U))
+          {
+            counter++;
+            if(pNode == pPrevNode)
+            {
+              /*Insert the new node after the previous one */
+              pNewNode->CLAR = pNode->CLAR;
+              pNode->CLAR = (uint32_t)pNewNode;
+              /* Increment the linked list node counter */
+              hmdma->LinkedListNodeCounter++;
+              nodeInserted = 1;
+            }
+            else
+            {
+              pNode = (MDMA_LinkNodeTypeDef *)pNode->CLAR;
+            }
+          }
+
+          if(nodeInserted == 0U)
+          {
+            hal_status = HAL_ERROR;
+          }
+        }
+      }
+    }
+    else
+    {
+      hal_status = HAL_ERROR;
+    }
+
+    /* Process unlocked */
+    __HAL_UNLOCK(hmdma);
+
+    hmdma->State = HAL_MDMA_STATE_READY;
+
+    return hal_status;
+  }
+  else
+  {
+    /* Process unlocked */
+    __HAL_UNLOCK(hmdma);
+
+    /* Return error status */
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief  Disconnect/Remove a node from the transfer linked list.
+  * @param  hmdma : Pointer to a MDMA_HandleTypeDef structure that contains
+  *                 the configuration information for the specified MDMA Channel.
+  * @param  pNode : Pointer to a MDMA_LinkNodeTypeDef structure that contains Linked list node
+  *                 to be removed from the list.
+  *
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_LinkedList_RemoveNode(MDMA_HandleTypeDef *hmdma, MDMA_LinkNodeTypeDef *pNode)
+{
+  MDMA_LinkNodeTypeDef *ptmpNode;
+  uint32_t counter = 0, nodeDeleted = 0;
+  HAL_StatusTypeDef hal_status = HAL_OK;
+
+  /* Check the MDMA peripheral handle */
+  if((hmdma == NULL) || (pNode == NULL))
+  {
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hmdma);
+
+  if(HAL_MDMA_STATE_READY == hmdma->State)
+  {
+    /* Change MDMA peripheral state */
+    hmdma->State = HAL_MDMA_STATE_BUSY;
+
+    /* If first and last node are null (no nodes in the list) : return error*/
+    if(((uint32_t)hmdma->FirstLinkedListNodeAddress == 0U) || ((uint32_t)hmdma->LastLinkedListNodeAddress == 0U) || (hmdma->LinkedListNodeCounter == 0U))
+    {
+      hal_status = HAL_ERROR;
+    }
+    else if(hmdma->FirstLinkedListNodeAddress == pNode) /* Deleting first node */
+    {
+      /* Delete 1st node */
+      if(hmdma->LastLinkedListNodeAddress == pNode)
+      {
+        /*if the last node is at the same time the first one (1 single node after the init node 0)
+        then update the last node too */
+
+        hmdma->FirstLinkedListNodeAddress = 0;
+        hmdma->LastLinkedListNodeAddress  = 0;
+        hmdma->LinkedListNodeCounter = 0;
+
+        hmdma->Instance->CLAR = 0;
+      }
+      else
+      {
+        if((uint32_t)hmdma->FirstLinkedListNodeAddress == hmdma->LastLinkedListNodeAddress->CLAR)
+        {
+          /* if last node is looping to first (circular list) one update the last node connection */
+          hmdma->LastLinkedListNodeAddress->CLAR = pNode->CLAR;
+        }
+
+        /* if deleting the first node after the initialization
+        connect the next node to the node 0 by updating
+        the MDMA channel CLAR register to this node address */
+        hmdma->Instance->CLAR = pNode->CLAR;
+        hmdma->FirstLinkedListNodeAddress = (MDMA_LinkNodeTypeDef *)hmdma->Instance->CLAR;
+        /* Update the Handle node counter */
+        hmdma->LinkedListNodeCounter--;
+      }
+    }
+    else /* Deleting any other node */
+    {
+      /*Deleted node is not the first one : find it  */
+      ptmpNode = hmdma->FirstLinkedListNodeAddress;
+      while((counter < hmdma->LinkedListNodeCounter) && (nodeDeleted == 0U))
+      {
+        counter++;
+        if(ptmpNode->CLAR == ((uint32_t)pNode))
+        {
+          /* if deleting the last node */
+          if(pNode == hmdma->LastLinkedListNodeAddress)
+          {
+            /*Update the linked list last node address in the handle*/
+            hmdma->LastLinkedListNodeAddress = ptmpNode;
+          }
+          /* update the next node link after deleting pMDMA_LinkedListNode */
+          ptmpNode->CLAR = pNode->CLAR;
+          nodeDeleted = 1;
+          /* Update the Handle node counter */
+          hmdma->LinkedListNodeCounter--;
+        }
+        else
+        {
+          ptmpNode = (MDMA_LinkNodeTypeDef *)ptmpNode->CLAR;
+        }
+      }
+
+      if(nodeDeleted == 0U)
+      {
+        /* last node reashed without finding the node to delete : return error */
+        hal_status = HAL_ERROR;
+      }
+    }
+
+    /* Process unlocked */
+    __HAL_UNLOCK(hmdma);
+
+    hmdma->State = HAL_MDMA_STATE_READY;
+
+    return hal_status;
+  }
+  else
+  {
+    /* Process unlocked */
+    __HAL_UNLOCK(hmdma);
+
+    /* Return error status */
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief  Make the linked list circular by connecting the last node to the first.
+  * @param  hmdma : Pointer to a MDMA_HandleTypeDef structure that contains
+  *                 the configuration information for the specified MDMA Channel.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_LinkedList_EnableCircularMode(MDMA_HandleTypeDef *hmdma)
+{
+  HAL_StatusTypeDef hal_status = HAL_OK;
+
+  /* Check the MDMA peripheral handle */
+  if(hmdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hmdma);
+
+  if(HAL_MDMA_STATE_READY == hmdma->State)
+  {
+    /* Change MDMA peripheral state */
+    hmdma->State = HAL_MDMA_STATE_BUSY;
+
+    /* If first and last node are null (no nodes in the list) : return error*/
+    if(((uint32_t)hmdma->FirstLinkedListNodeAddress == 0U) || ((uint32_t)hmdma->LastLinkedListNodeAddress == 0U) || (hmdma->LinkedListNodeCounter == 0U))
+    {
+      hal_status = HAL_ERROR;
+    }
+    else
+    {
+      /* to enable circular mode Last Node should be connected to first node */
+      hmdma->LastLinkedListNodeAddress->CLAR = (uint32_t)hmdma->FirstLinkedListNodeAddress;
+    }
+
+  }
+  /* Process unlocked */
+  __HAL_UNLOCK(hmdma);
+
+  hmdma->State = HAL_MDMA_STATE_READY;
+
+  return hal_status;
+}
+
+/**
+  * @brief  Disable the linked list circular mode by setting the last node connection to null
+  * @param  hmdma : Pointer to a MDMA_HandleTypeDef structure that contains
+  *                 the configuration information for the specified MDMA Channel.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_LinkedList_DisableCircularMode(MDMA_HandleTypeDef *hmdma)
+{
+  HAL_StatusTypeDef hal_status = HAL_OK;
+
+  /* Check the MDMA peripheral handle */
+  if(hmdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hmdma);
+
+  if(HAL_MDMA_STATE_READY == hmdma->State)
+  {
+    /* Change MDMA peripheral state */
+    hmdma->State = HAL_MDMA_STATE_BUSY;
+
+    /* If first and last node are null (no nodes in the list) : return error*/
+    if(((uint32_t)hmdma->FirstLinkedListNodeAddress == 0U) || ((uint32_t)hmdma->LastLinkedListNodeAddress == 0U) || (hmdma->LinkedListNodeCounter == 0U))
+    {
+      hal_status = HAL_ERROR;
+    }
+    else
+    {
+      /* to disable circular mode Last Node should be connected to NULL */
+      hmdma->LastLinkedListNodeAddress->CLAR = 0;
+    }
+
+  }
+  /* Process unlocked */
+  __HAL_UNLOCK(hmdma);
+
+  hmdma->State = HAL_MDMA_STATE_READY;
+
+  return hal_status;
+}
+
+/**
+  * @}
+  */
+
+/** @addtogroup MDMA_Exported_Functions_Group3
+ *
+@verbatim
+ ===============================================================================
+                      #####  IO operation functions  #####
+ ===============================================================================
+    [..]  This section provides functions allowing to:
+      (+) Configure the source, destination address and data length and Start MDMA transfer
+      (+) Configure the source, destination address and data length and
+          Start MDMA transfer with interrupt
+      (+) Abort MDMA transfer
+      (+) Poll for transfer complete
+      (+) Generate a SW request (when Request is set to MDMA_REQUEST_SW)
+      (+) Handle MDMA interrupt request
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Starts the MDMA Transfer.
+  * @param  hmdma           : pointer to a MDMA_HandleTypeDef structure that contains
+  *                           the configuration information for the specified MDMA Channel.
+  * @param  SrcAddress      : The source memory Buffer address
+  * @param  DstAddress      : The destination memory Buffer address
+  * @param  BlockDataLength : The length of a block transfer in bytes
+  * @param  BlockCount      : The number of a blocks to be transfer
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_Start(MDMA_HandleTypeDef *hmdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t BlockDataLength, uint32_t BlockCount)
+{
+  /* Check the parameters */
+  assert_param(IS_MDMA_TRANSFER_LENGTH(BlockDataLength));
+  assert_param(IS_MDMA_BLOCK_COUNT(BlockCount));
+
+  /* Check the MDMA peripheral handle */
+  if(hmdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hmdma);
+
+  if(HAL_MDMA_STATE_READY == hmdma->State)
+  {
+    /* Change MDMA peripheral state */
+    hmdma->State = HAL_MDMA_STATE_BUSY;
+
+    /* Initialize the error code */
+    hmdma->ErrorCode = HAL_MDMA_ERROR_NONE;
+
+    /* Disable the peripheral */
+    __HAL_MDMA_DISABLE(hmdma);
+
+    /* Configure the source, destination address and the data length */
+    MDMA_SetConfig(hmdma, SrcAddress, DstAddress, BlockDataLength, BlockCount);
+
+    /* Enable the Peripheral */
+    __HAL_MDMA_ENABLE(hmdma);
+
+    if(hmdma->Init.Request == MDMA_REQUEST_SW)
+    {
+      /* activate If SW request mode*/
+      hmdma->Instance->CCR |=  MDMA_CCR_SWRQ;
+    }
+  }
+  else
+  {
+    /* Process unlocked */
+    __HAL_UNLOCK(hmdma);
+
+    /* Return error status */
+    return HAL_BUSY;
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Starts the MDMA Transfer with interrupts enabled.
+  * @param  hmdma           : pointer to a MDMA_HandleTypeDef structure that contains
+  *                           the configuration information for the specified MDMA Channel.
+  * @param  SrcAddress      : The source memory Buffer address
+  * @param  DstAddress      : The destination memory Buffer address
+  * @param  BlockDataLength : The length of a block transfer in bytes
+  * @param  BlockCount      : The number of a blocks to be transfer
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_Start_IT(MDMA_HandleTypeDef *hmdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t BlockDataLength, uint32_t BlockCount)
+{
+  /* Check the parameters */
+  assert_param(IS_MDMA_TRANSFER_LENGTH(BlockDataLength));
+  assert_param(IS_MDMA_BLOCK_COUNT(BlockCount));
+
+  /* Check the MDMA peripheral handle */
+  if(hmdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hmdma);
+
+  if(HAL_MDMA_STATE_READY == hmdma->State)
+  {
+    /* Change MDMA peripheral state */
+    hmdma->State = HAL_MDMA_STATE_BUSY;
+
+    /* Initialize the error code */
+    hmdma->ErrorCode = HAL_MDMA_ERROR_NONE;
+
+    /* Disable the peripheral */
+    __HAL_MDMA_DISABLE(hmdma);
+
+    /* Configure the source, destination address and the data length */
+    MDMA_SetConfig(hmdma, SrcAddress, DstAddress, BlockDataLength, BlockCount);
+
+    /* Enable Common interrupts i.e Transfer Error IT and Channel Transfer Complete IT*/
+    __HAL_MDMA_ENABLE_IT(hmdma, (MDMA_IT_TE | MDMA_IT_CTC));
+
+    if(hmdma->XferBlockCpltCallback != NULL)
+    {
+      /* if Block transfer complete Callback is set enable the corresponding IT*/
+      __HAL_MDMA_ENABLE_IT(hmdma, MDMA_IT_BT);
+    }
+
+    if(hmdma->XferRepeatBlockCpltCallback != NULL)
+    {
+      /* if Repeated Block transfer complete Callback is set enable the corresponding IT*/
+      __HAL_MDMA_ENABLE_IT(hmdma, MDMA_IT_BRT);
+    }
+
+    if(hmdma->XferBufferCpltCallback != NULL)
+    {
+      /* if buffer transfer complete Callback is set enable the corresponding IT*/
+      __HAL_MDMA_ENABLE_IT(hmdma, MDMA_IT_BFTC);
+    }
+
+    /* Enable the Peripheral */
+    __HAL_MDMA_ENABLE(hmdma);
+
+    if(hmdma->Init.Request == MDMA_REQUEST_SW)
+    {
+      /* activate If SW request mode*/
+      hmdma->Instance->CCR |=  MDMA_CCR_SWRQ;
+    }
+  }
+  else
+  {
+    /* Process unlocked */
+    __HAL_UNLOCK(hmdma);
+
+    /* Return error status */
+    return HAL_BUSY;
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Aborts the MDMA Transfer.
+  * @param  hmdma  : pointer to a MDMA_HandleTypeDef structure that contains
+  *                 the configuration information for the specified MDMA Channel.
+  *
+  * @note  After disabling a MDMA Channel, a check for wait until the MDMA Channel is
+  *        effectively disabled is added. If a Channel is disabled
+  *        while a data transfer is ongoing, the current data will be transferred
+  *        and the Channel will be effectively disabled only after the transfer of
+  *        this single data is finished.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_Abort(MDMA_HandleTypeDef *hmdma)
+{
+  uint32_t tickstart =  HAL_GetTick();
+
+  /* Check the MDMA peripheral handle */
+  if(hmdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  if(HAL_MDMA_STATE_BUSY != hmdma->State)
+  {
+    hmdma->ErrorCode = HAL_MDMA_ERROR_NO_XFER;
+
+    /* Process Unlocked */
+    __HAL_UNLOCK(hmdma);
+
+    return HAL_ERROR;
+  }
+  else
+  {
+    /* Disable all the transfer interrupts */
+    __HAL_MDMA_DISABLE_IT(hmdma, (MDMA_IT_TE | MDMA_IT_CTC | MDMA_IT_BT | MDMA_IT_BRT | MDMA_IT_BFTC));
+
+    /* Disable the channel */
+    __HAL_MDMA_DISABLE(hmdma);
+
+    /* Check if the MDMA Channel is effectively disabled */
+    while((hmdma->Instance->CCR & MDMA_CCR_EN) != 0U)
+    {
+      /* Check for the Timeout */
+      if( (HAL_GetTick()  - tickstart ) > HAL_TIMEOUT_MDMA_ABORT)
+      {
+        /* Update error code */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_TIMEOUT;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(hmdma);
+
+        /* Change the MDMA state */
+        hmdma->State = HAL_MDMA_STATE_ERROR;
+
+        return HAL_ERROR;
+      }
+    }
+
+    /* Clear all interrupt flags */
+    __HAL_MDMA_CLEAR_FLAG(hmdma, (MDMA_FLAG_TE | MDMA_FLAG_CTC | MDMA_FLAG_BT | MDMA_FLAG_BRT | MDMA_FLAG_BFTC));
+
+    /* Process Unlocked */
+    __HAL_UNLOCK(hmdma);
+
+    /* Change the MDMA state*/
+    hmdma->State = HAL_MDMA_STATE_READY;
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Aborts the MDMA Transfer in Interrupt mode.
+  * @param  hmdma  : pointer to a MDMA_HandleTypeDef structure that contains
+  *                 the configuration information for the specified MDMA Channel.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_Abort_IT(MDMA_HandleTypeDef *hmdma)
+{
+  /* Check the MDMA peripheral handle */
+  if(hmdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  if(HAL_MDMA_STATE_BUSY != hmdma->State)
+  {
+    /* No transfer ongoing */
+    hmdma->ErrorCode = HAL_MDMA_ERROR_NO_XFER;
+
+    return HAL_ERROR;
+  }
+  else
+  {
+    /* Set Abort State  */
+    hmdma->State = HAL_MDMA_STATE_ABORT;
+
+    /* Disable the stream */
+    __HAL_MDMA_DISABLE(hmdma);
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Polling for transfer complete.
+  * @param  hmdma:          pointer to a MDMA_HandleTypeDef structure that contains
+  *                        the configuration information for the specified MDMA Channel.
+  * @param  CompleteLevel: Specifies the MDMA level complete.
+  * @param  Timeout:       Timeout duration.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_PollForTransfer(MDMA_HandleTypeDef *hmdma, HAL_MDMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
+{
+  uint32_t levelFlag, errorFlag;
+  uint32_t tickstart;
+
+  /* Check the parameters */
+  assert_param(IS_MDMA_LEVEL_COMPLETE(CompleteLevel));
+
+  /* Check the MDMA peripheral handle */
+  if(hmdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  if(HAL_MDMA_STATE_BUSY != hmdma->State)
+  {
+    /* No transfer ongoing */
+    hmdma->ErrorCode = HAL_MDMA_ERROR_NO_XFER;
+
+    return HAL_ERROR;
+  }
+
+  /* Get the level transfer complete flag */
+  levelFlag = ((CompleteLevel == HAL_MDMA_FULL_TRANSFER)  ? MDMA_FLAG_CTC  : \
+               (CompleteLevel == HAL_MDMA_BUFFER_TRANSFER)? MDMA_FLAG_BFTC : \
+               (CompleteLevel == HAL_MDMA_BLOCK_TRANSFER) ? MDMA_FLAG_BT   : \
+               MDMA_FLAG_BRT);
+
+
+  /* Get timeout */
+  tickstart = HAL_GetTick();
+
+  while(__HAL_MDMA_GET_FLAG(hmdma, levelFlag) == 0U)
+  {
+    if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_TE) != 0U))
+    {
+      /* Get the transfer error source flag */
+      errorFlag = hmdma->Instance->CESR;
+
+      if((errorFlag & MDMA_CESR_TED) == 0U)
+      {
+        /* Update error code : Read Transfer error  */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_READ_XFER;
+      }
+      else
+      {
+        /* Update error code : Write Transfer error */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_WRITE_XFER;
+      }
+
+      if((errorFlag & MDMA_CESR_TEMD) != 0U)
+      {
+        /* Update error code : Error Mask Data */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_MASK_DATA;
+      }
+
+      if((errorFlag & MDMA_CESR_TELD) != 0U)
+      {
+        /* Update error code : Error Linked list */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_LINKED_LIST;
+      }
+
+      if((errorFlag & MDMA_CESR_ASE) != 0U)
+      {
+        /* Update error code : Address/Size alignment error */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_ALIGNMENT;
+      }
+
+      if((errorFlag & MDMA_CESR_BSE) != 0U)
+      {
+        /* Update error code : Block Size error */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_BLOCK_SIZE;
+      }
+
+      (void) HAL_MDMA_Abort(hmdma); /* if error then abort the current transfer */
+
+      /*
+        Note that the Abort function will
+          - Clear all transfer flags
+          - Unlock
+          - Set the State
+      */
+
+      return HAL_ERROR;
+
+    }
+
+    /* Check for the Timeout */
+    if(Timeout != HAL_MAX_DELAY)
+    {
+      if(((HAL_GetTick() - tickstart ) > Timeout) || (Timeout == 0U))
+      {
+        /* Update error code */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_TIMEOUT;
+
+        (void) HAL_MDMA_Abort(hmdma); /* if timeout then abort the current transfer */
+
+        /*
+          Note that the Abort function will
+            - Clear all transfer flags
+            - Unlock
+            - Set the State
+        */
+
+        return HAL_ERROR;
+      }
+    }
+  }
+
+  /* Clear the transfer level flag */
+  if(CompleteLevel == HAL_MDMA_BUFFER_TRANSFER)
+  {
+    __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_BFTC);
+
+  }
+  else if(CompleteLevel == HAL_MDMA_BLOCK_TRANSFER)
+  {
+    __HAL_MDMA_CLEAR_FLAG(hmdma, (MDMA_FLAG_BFTC | MDMA_FLAG_BT));
+
+  }
+  else if(CompleteLevel == HAL_MDMA_REPEAT_BLOCK_TRANSFER)
+  {
+    __HAL_MDMA_CLEAR_FLAG(hmdma, (MDMA_FLAG_BFTC | MDMA_FLAG_BT | MDMA_FLAG_BRT));
+  }
+  else if(CompleteLevel == HAL_MDMA_FULL_TRANSFER)
+  {
+    __HAL_MDMA_CLEAR_FLAG(hmdma, (MDMA_FLAG_BRT | MDMA_FLAG_BT | MDMA_FLAG_BFTC | MDMA_FLAG_CTC));
+
+    /* Process unlocked */
+    __HAL_UNLOCK(hmdma);
+
+    hmdma->State = HAL_MDMA_STATE_READY;
+  }
+  else
+  {
+    return HAL_ERROR;
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Generate an MDMA SW request trigger to activate the request on the given Channel.
+  * @param  hmdma:       pointer to a MDMA_HandleTypeDef structure that contains
+  *                     the configuration information for the specified MDMA Stream.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MDMA_GenerateSWRequest(MDMA_HandleTypeDef *hmdma)
+{
+  uint32_t request_mode;
+
+  /* Check the MDMA peripheral handle */
+  if(hmdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Get the softawre request mode */
+  request_mode = hmdma->Instance->CTCR & MDMA_CTCR_SWRM;
+
+  if((hmdma->Instance->CCR &  MDMA_CCR_EN) == 0U)
+  {
+    /* if no Transfer on going (MDMA enable bit not set) return error */
+    hmdma->ErrorCode = HAL_MDMA_ERROR_NO_XFER;
+
+    return HAL_ERROR;
+  }
+  else if(((hmdma->Instance->CISR &  MDMA_CISR_CRQA) != 0U) || (request_mode == 0U))
+  {
+    /* if an MDMA ongoing request has not yet end or if request mode is not SW request return error */
+    hmdma->ErrorCode = HAL_MDMA_ERROR_BUSY;
+
+    return HAL_ERROR;
+  }
+  else
+  {
+    /* Set the SW request bit to activate the request on the Channel */
+    hmdma->Instance->CCR |= MDMA_CCR_SWRQ;
+
+    return HAL_OK;
+  }
+}
+
+/**
+  * @brief  Handles MDMA interrupt request.
+  * @param  hmdma: pointer to a MDMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified MDMA Channel.
+  * @retval None
+  */
+void HAL_MDMA_IRQHandler(MDMA_HandleTypeDef *hmdma)
+{
+  __IO uint32_t count = 0;
+  uint32_t timeout = SystemCoreClock / 9600U;
+
+  uint32_t generalIntFlag, errorFlag;
+
+  /* General Interrupt Flag management ****************************************/
+  generalIntFlag =  1UL << ((((uint32_t)hmdma->Instance - (uint32_t)(MDMA_Channel0))/HAL_MDMA_CHANNEL_SIZE) & 0x1FU);
+  if((MDMA->GISR0 & generalIntFlag) == 0U)
+  {
+    return; /* the  General interrupt flag for the current channel is down , nothing to do */
+  }
+
+  /* Transfer Error Interrupt management ***************************************/
+  if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_TE) != 0U))
+  {
+    if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_TE) != 0U)
+    {
+      /* Disable the transfer error interrupt */
+      __HAL_MDMA_DISABLE_IT(hmdma, MDMA_IT_TE);
+
+      /* Get the transfer error source flag */
+      errorFlag = hmdma->Instance->CESR;
+
+      if((errorFlag & MDMA_CESR_TED) == 0U)
+      {
+        /* Update error code : Read Transfer error  */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_READ_XFER;
+      }
+      else
+      {
+        /* Update error code : Write Transfer error */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_WRITE_XFER;
+      }
+
+      if((errorFlag & MDMA_CESR_TEMD) != 0U)
+      {
+        /* Update error code : Error Mask Data */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_MASK_DATA;
+      }
+
+      if((errorFlag & MDMA_CESR_TELD) != 0U)
+      {
+        /* Update error code : Error Linked list */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_LINKED_LIST;
+      }
+
+      if((errorFlag & MDMA_CESR_ASE) != 0U)
+      {
+        /* Update error code : Address/Size alignment error */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_ALIGNMENT;
+      }
+
+      if((errorFlag & MDMA_CESR_BSE) != 0U)
+      {
+        /* Update error code : Block Size error error */
+        hmdma->ErrorCode |= HAL_MDMA_ERROR_BLOCK_SIZE;
+      }
+
+      /* Clear the transfer error flags */
+      __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_TE);
+    }
+  }
+
+  /* Buffer Transfer Complete Interrupt management ******************************/
+  if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_BFTC) != 0U))
+  {
+    if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_BFTC) != 0U)
+    {
+      /* Clear the buffer transfer complete flag */
+      __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_BFTC);
+
+      if(hmdma->XferBufferCpltCallback != NULL)
+      {
+        /* Buffer transfer callback */
+        hmdma->XferBufferCpltCallback(hmdma);
+      }
+    }
+  }
+
+  /* Block Transfer Complete Interrupt management ******************************/
+  if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_BT) != 0U))
+  {
+    if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_BT) != 0U)
+    {
+      /* Clear the block transfer complete flag */
+      __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_BT);
+
+      if(hmdma->XferBlockCpltCallback != NULL)
+      {
+        /* Block transfer callback */
+        hmdma->XferBlockCpltCallback(hmdma);
+      }
+    }
+  }
+
+  /* Repeated Block Transfer Complete Interrupt management ******************************/
+  if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_BRT) != 0U))
+  {
+    if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_BRT) != 0U)
+    {
+      /* Clear the repeat block transfer complete flag */
+      __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_BRT);
+
+      if(hmdma->XferRepeatBlockCpltCallback != NULL)
+      {
+        /* Repeated Block transfer callback */
+        hmdma->XferRepeatBlockCpltCallback(hmdma);
+      }
+    }
+  }
+
+  /* Channel Transfer Complete Interrupt management ***********************************/
+  if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_CTC) != 0U))
+  {
+    if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_CTC) != 0U)
+    {
+      /* Disable all the transfer interrupts */
+      __HAL_MDMA_DISABLE_IT(hmdma, (MDMA_IT_TE | MDMA_IT_CTC | MDMA_IT_BT | MDMA_IT_BRT | MDMA_IT_BFTC));
+
+      if(HAL_MDMA_STATE_ABORT == hmdma->State)
+      {
+        /* Process Unlocked */
+        __HAL_UNLOCK(hmdma);
+
+        /* Change the DMA state */
+        hmdma->State = HAL_MDMA_STATE_READY;
+
+        if(hmdma->XferAbortCallback != NULL)
+        {
+          hmdma->XferAbortCallback(hmdma);
+        }
+        return;
+      }
+
+      /* Clear the Channel Transfer Complete flag */
+      __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_CTC);
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(hmdma);
+
+      /* Change MDMA peripheral state */
+      hmdma->State = HAL_MDMA_STATE_READY;
+
+      if(hmdma->XferCpltCallback != NULL)
+      {
+        /* Channel Transfer Complete callback */
+        hmdma->XferCpltCallback(hmdma);
+      }
+    }
+  }
+
+  /* manage error case */
+  if(hmdma->ErrorCode != HAL_MDMA_ERROR_NONE)
+  {
+    hmdma->State = HAL_MDMA_STATE_ABORT;
+
+    /* Disable the channel */
+    __HAL_MDMA_DISABLE(hmdma);
+
+    do
+    {
+      if (++count > timeout)
+      {
+        break;
+      }
+    }
+    while((hmdma->Instance->CCR & MDMA_CCR_EN) != 0U);
+
+    /* Process Unlocked */
+    __HAL_UNLOCK(hmdma);
+
+    if((hmdma->Instance->CCR & MDMA_CCR_EN) != 0U)
+    {
+      /* Change the MDMA state to error if MDMA disable fails */
+      hmdma->State = HAL_MDMA_STATE_ERROR;
+    }
+    else
+    {
+      /* Change the MDMA state to Ready if MDMA disable success */
+      hmdma->State = HAL_MDMA_STATE_READY;
+    }
+
+
+    if (hmdma->XferErrorCallback != NULL)
+    {
+      /* Transfer error callback */
+      hmdma->XferErrorCallback(hmdma);
+    }
+  }
+}
+
+/**
+  * @}
+  */
+
+/** @addtogroup MDMA_Exported_Functions_Group4
+ *
+@verbatim
+ ===============================================================================
+                    ##### State and Errors functions #####
+ ===============================================================================
+    [..]
+    This subsection provides functions allowing to
+      (+) Check the MDMA state
+      (+) Get error code
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Returns the MDMA state.
+  * @param  hmdma: pointer to a MDMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified MDMA Channel.
+  * @retval HAL state
+  */
+HAL_MDMA_StateTypeDef HAL_MDMA_GetState(const MDMA_HandleTypeDef *hmdma)
+{
+  return hmdma->State;
+}
+
+/**
+  * @brief  Return the MDMA error code
+  * @param  hmdma : pointer to a MDMA_HandleTypeDef structure that contains
+  *              the configuration information for the specified MDMA Channel.
+  * @retval MDMA Error Code
+  */
+uint32_t HAL_MDMA_GetError(const MDMA_HandleTypeDef *hmdma)
+{
+  return hmdma->ErrorCode;
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup MDMA_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Sets the MDMA Transfer parameter.
+  * @param  hmdma:       pointer to a MDMA_HandleTypeDef structure that contains
+  *                     the configuration information for the specified MDMA Channel.
+  * @param  SrcAddress: The source memory Buffer address
+  * @param  DstAddress: The destination memory Buffer address
+  * @param  BlockDataLength : The length of a block transfer in bytes
+  * @param  BlockCount: The number of blocks to be transferred
+  * @retval HAL status
+  */
+static void MDMA_SetConfig(MDMA_HandleTypeDef *hmdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t BlockDataLength, uint32_t BlockCount)
+{
+  uint32_t addressMask;
+
+  /* Configure the MDMA Channel data length */
+  MODIFY_REG(hmdma->Instance->CBNDTR ,MDMA_CBNDTR_BNDT, (BlockDataLength & MDMA_CBNDTR_BNDT));
+
+  /* Configure the MDMA block repeat count */
+  MODIFY_REG(hmdma->Instance->CBNDTR , MDMA_CBNDTR_BRC , ((BlockCount - 1U) << MDMA_CBNDTR_BRC_Pos) & MDMA_CBNDTR_BRC);
+
+  /* Clear all interrupt flags */
+  __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_TE | MDMA_FLAG_CTC | MDMA_CISR_BRTIF | MDMA_CISR_BTIF | MDMA_CISR_TCIF);
+
+  /* Configure MDMA Channel destination address */
+  hmdma->Instance->CDAR = DstAddress;
+
+  /* Configure MDMA Channel Source address */
+  hmdma->Instance->CSAR = SrcAddress;
+
+  addressMask = SrcAddress & 0xFF000000U;
+  if((addressMask == 0x20000000U) || (addressMask == 0x00000000U))
+  {
+    /*The AHBSbus is used as source (read operation) on channel x */
+    hmdma->Instance->CTBR |= MDMA_CTBR_SBUS;
+  }
+  else
+  {
+    /*The AXI bus is used as source (read operation) on channel x */
+    hmdma->Instance->CTBR &= (~MDMA_CTBR_SBUS);
+  }
+
+  addressMask = DstAddress & 0xFF000000U;
+  if((addressMask == 0x20000000U) || (addressMask == 0x00000000U))
+  {
+    /*The AHB bus is used as destination (write operation) on channel x */
+    hmdma->Instance->CTBR |= MDMA_CTBR_DBUS;
+  }
+  else
+  {
+    /*The AXI bus is used as destination (write operation) on channel x */
+    hmdma->Instance->CTBR &= (~MDMA_CTBR_DBUS);
+  }
+
+  /* Set the linked list register to the first node of the list */
+  hmdma->Instance->CLAR = (uint32_t)hmdma->FirstLinkedListNodeAddress;
+}
+
+/**
+  * @brief  Initializes the MDMA handle according to the specified
+  *         parameters in the MDMA_InitTypeDef
+  * @param  hmdma:       pointer to a MDMA_HandleTypeDef structure that contains
+  *                     the configuration information for the specified MDMA Channel.
+  * @retval None
+  */
+static void MDMA_Init(MDMA_HandleTypeDef *hmdma)
+{
+  uint32_t blockoffset;
+
+  /* Prepare the MDMA Channel configuration */
+  hmdma->Instance->CCR = hmdma->Init.Priority  | hmdma->Init.Endianness;
+
+  /* Write new CTCR Register value */
+  hmdma->Instance->CTCR =  hmdma->Init.SourceInc      | hmdma->Init.DestinationInc | \
+                           hmdma->Init.SourceDataSize | hmdma->Init.DestDataSize   | \
+                           hmdma->Init.DataAlignment  | hmdma->Init.SourceBurst    | \
+                           hmdma->Init.DestBurst                                   | \
+                           ((hmdma->Init.BufferTransferLength - 1U) << MDMA_CTCR_TLEN_Pos) | \
+                           hmdma->Init.TransferTriggerMode;
+
+  /* If SW request set the CTCR register to SW Request Mode */
+  if(hmdma->Init.Request == MDMA_REQUEST_SW)
+  {
+    /*
+    -If the request is done by SW : BWM could be set to 1 or 0.
+    -If the request is done by a peripheral :
+    If mask address not set (0) => BWM must be set to 0
+    If mask address set (different than 0) => BWM could be set to 1 or 0
+    */
+    hmdma->Instance->CTCR |= (MDMA_CTCR_SWRM | MDMA_CTCR_BWM);
+  }
+
+  /* Reset CBNDTR Register */
+  hmdma->Instance->CBNDTR = 0;
+
+  /* if block source address offset is negative set the Block Repeat Source address Update Mode to decrement */
+  if(hmdma->Init.SourceBlockAddressOffset < 0)
+  {
+    hmdma->Instance->CBNDTR |= MDMA_CBNDTR_BRSUM;
+    /* Write new CBRUR Register value : source repeat block offset */
+    blockoffset = (uint32_t)(- hmdma->Init.SourceBlockAddressOffset);
+    hmdma->Instance->CBRUR = (blockoffset & 0x0000FFFFU);
+  }
+  else
+  {
+    /* Write new CBRUR Register value : source repeat block offset */
+    hmdma->Instance->CBRUR = (((uint32_t)hmdma->Init.SourceBlockAddressOffset) & 0x0000FFFFU);
+  }
+
+  /* If block destination address offset is negative set the Block Repeat destination address Update Mode to decrement */
+  if(hmdma->Init.DestBlockAddressOffset < 0)
+  {
+    hmdma->Instance->CBNDTR |= MDMA_CBNDTR_BRDUM;
+    /* Write new CBRUR Register value : destination repeat block offset */
+    blockoffset = (uint32_t)(- hmdma->Init.DestBlockAddressOffset);
+    hmdma->Instance->CBRUR |= ((blockoffset & 0x0000FFFFU) << MDMA_CBRUR_DUV_Pos);
+  }
+  else
+  {
+    /*write new CBRUR Register value : destination repeat block offset */
+    hmdma->Instance->CBRUR |= ((((uint32_t)hmdma->Init.DestBlockAddressOffset) & 0x0000FFFFU) << MDMA_CBRUR_DUV_Pos);
+  }
+
+  /* if HW request set the HW request and the requet CleraMask and ClearData MaskData, */
+  if(hmdma->Init.Request != MDMA_REQUEST_SW)
+  {
+    /* Set the HW request in CTRB register  */
+    hmdma->Instance->CTBR = hmdma->Init.Request & MDMA_CTBR_TSEL;
+  }
+  else /* SW request : reset the CTBR register */
+  {
+    hmdma->Instance->CTBR = 0;
+  }
+
+  /* Write Link Address Register */
+  hmdma->Instance->CLAR =  0;
+}
+
+/**
+  * @}
+  */
+
+#endif /* HAL_MDMA_MODULE_ENABLED */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
