summaryrefslogtreecommitdiffstats
path: root/bsps/arm/stm32h7/hal/stm32h7xx_hal_mdma.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/arm/stm32h7/hal/stm32h7xx_hal_mdma.c')
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_mdma.c3800
1 files changed, 1899 insertions, 1901 deletions
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_mdma.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_mdma.c
index 8dd757acf6..e1f36fdd24 100644
--- a/bsps/arm/stm32h7/hal/stm32h7xx_hal_mdma.c
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_mdma.c
@@ -1,1902 +1,1900 @@
-/**
- ******************************************************************************
- * @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
- @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
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32h7xx_hal.h"
-
-/** @addtogroup STM32H7xx_HAL_Driver
- * @{
- */
-
-/** @defgroup MDMA MDMA
+/**
+ ******************************************************************************
+ * @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
* @ingroup RTEMSBSPsARMSTM32H7
- * @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, 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) retrun 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 retrun 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(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(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 transfered
- * @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 */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+ * @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, 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(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(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 */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+