STM32H735xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32h7xx_hal_mdma.c 00004 * @author MCD Application Team 00005 * @brief This file provides firmware functions to manage the following 00006 * functionalities of the Master Direct Memory Access (MDMA) peripheral: 00007 * + Initialization/de-initialization functions 00008 * + I/O operation functions 00009 * + Peripheral State and errors functions 00010 ****************************************************************************** 00011 * @attention 00012 * 00013 * Copyright (c) 2017 STMicroelectronics. 00014 * All rights reserved. 00015 * 00016 * This software is licensed under terms that can be found in the LICENSE file 00017 * in the root directory of this software component. 00018 * If no LICENSE file comes with this software, it is provided AS-IS. 00019 * 00020 ****************************************************************************** 00021 @verbatim 00022 ============================================================================== 00023 ##### How to use this driver ##### 00024 ============================================================================== 00025 [..] 00026 (#) Enable and configure the peripheral to be connected to the MDMA Channel 00027 (except for internal SRAM/FLASH memories: no initialization is 00028 necessary) please refer to Reference manual for connection between peripherals 00029 and MDMA requests. 00030 00031 (#) 00032 For a given Channel use HAL_MDMA_Init function to program the required configuration through the following parameters: 00033 transfer request , channel priority, data endianness, Source increment, destination increment , 00034 source data size, destination data size, data alignment, source Burst, destination Burst , 00035 buffer Transfer Length, Transfer Trigger Mode (buffer transfer, block transfer, repeated block transfer 00036 or full transfer) source and destination block address offset, mask address and data. 00037 00038 If using the MDMA in linked list mode then use function HAL_MDMA_LinkedList_CreateNode to fill a transfer node. 00039 Note that parameters given to the function HAL_MDMA_Init corresponds always to the node zero. 00040 Use function HAL_MDMA_LinkedList_AddNode to connect the created node to the linked list at a given position. 00041 User can make a linked list circular using function HAL_MDMA_LinkedList_EnableCircularMode , this function will automatically connect the 00042 last node of the list to the first one in order to make the list circular. 00043 In this case the linked list will loop on node 1 : first node connected after the initial transfer defined by the HAL_MDMA_Init 00044 00045 -@- The initial transfer itself (node 0 corresponding to the Init). 00046 User can disable the circular mode using function HAL_MDMA_LinkedList_DisableCircularMode, this function will then remove 00047 the connection between last node and first one. 00048 00049 Function HAL_MDMA_LinkedList_RemoveNode can be used to remove (disconnect) a node from the transfer linked list. 00050 When a linked list is circular (last node connected to first one), if removing node1 (node where the linked list loops), 00051 the linked list remains circular and node 2 becomes the first one. 00052 Note that if the linked list is made circular the transfer will loop infinitely (or until aborted by the user). 00053 00054 [..] 00055 (+) User can select the transfer trigger mode (parameter TransferTriggerMode) to define the amount of data to be 00056 transfer upon a request : 00057 (++) MDMA_BUFFER_TRANSFER : each request triggers a transfer of BufferTransferLength data 00058 with BufferTransferLength defined within the HAL_MDMA_Init. 00059 (++) MDMA_BLOCK_TRANSFER : each request triggers a transfer of a block 00060 with block size defined within the function HAL_MDMA_Start/HAL_MDMA_Start_IT 00061 or within the current linked list node parameters. 00062 (++) MDMA_REPEAT_BLOCK_TRANSFER : each request triggers a transfer of a number of blocks 00063 with block size and number of blocks defined within the function HAL_MDMA_Start/HAL_MDMA_Start_IT 00064 or within the current linked list node parameters. 00065 (++) MDMA_FULL_TRANSFER : each request triggers a full transfer 00066 all blocks and all nodes(if a linked list has been created using HAL_MDMA_LinkedList_CreateNode \ HAL_MDMA_LinkedList_AddNode). 00067 00068 *** Polling mode IO operation *** 00069 ================================= 00070 [..] 00071 (+) Use HAL_MDMA_Start() to start MDMA transfer after the configuration of Source 00072 address and destination address and the Length of data to be transferred. 00073 (+) Use HAL_MDMA_PollForTransfer() to poll for the end of current transfer or a transfer level 00074 In this case a fixed Timeout can be configured by User depending from his application. 00075 (+) Use HAL_MDMA_Abort() function to abort the current transfer : blocking method this API returns 00076 when the abort ends or timeout (should not be called from an interrupt service routine). 00077 00078 *** Interrupt mode IO operation *** 00079 =================================== 00080 [..] 00081 (+) Configure the MDMA interrupt priority using HAL_NVIC_SetPriority() 00082 (+) Enable the MDMA IRQ handler using HAL_NVIC_EnableIRQ() 00083 (+) Use HAL_MDMA_Start_IT() to start MDMA transfer after the configuration of 00084 Source address and destination address and the Length of data to be transferred. In this 00085 case the MDMA interrupt is configured. 00086 (+) Use HAL_MDMA_IRQHandler() called under MDMA_IRQHandler() Interrupt subroutine 00087 (+) At the end of data transfer HAL_MDMA_IRQHandler() function is executed and user can 00088 add his own function by customization of function pointer XferCpltCallback and 00089 XferErrorCallback (i.e a member of MDMA handle structure). 00090 00091 (+) Use HAL_MDMA_Abort_IT() function to abort the current transfer : non-blocking method. This API will finish the execution immediately 00092 then the callback XferAbortCallback (if specified by the user) is asserted once the MDMA channel has effectively aborted. 00093 (could be called from an interrupt service routine). 00094 00095 (+) Use functions HAL_MDMA_RegisterCallback and HAL_MDMA_UnRegisterCallback respectevely to register unregister user callbacks 00096 from the following list : 00097 (++) XferCpltCallback : transfer complete callback. 00098 (++) XferBufferCpltCallback : buffer transfer complete callback. 00099 (++) XferBlockCpltCallback : block transfer complete callback. 00100 (++) XferRepeatBlockCpltCallback : repeated block transfer complete callback. 00101 (++) XferErrorCallback : transfer error callback. 00102 (++) XferAbortCallback : transfer abort complete callback. 00103 00104 [..] 00105 (+) If the transfer Request corresponds to SW request (MDMA_REQUEST_SW) User can use function HAL_MDMA_GenerateSWRequest to 00106 trigger requests manually. Function HAL_MDMA_GenerateSWRequest must be used with the following precautions: 00107 (++) This function returns an error if used while the Transfer has ended or not started. 00108 (++) If used while the current request has not been served yet (current request transfer on going) 00109 this function returns an error and the new request is ignored. 00110 00111 Generally this function should be used in conjunctions with the MDMA callbacks: 00112 (++) example 1: 00113 (+++) Configure a transfer with request set to MDMA_REQUEST_SW and trigger mode set to MDMA_BUFFER_TRANSFER 00114 (+++) Register a callback for buffer transfer complete (using callback ID set to HAL_MDMA_XFER_BUFFERCPLT_CB_ID) 00115 (+++) After calling HAL_MDMA_Start_IT the MDMA will issue the transfer of a first BufferTransferLength data. 00116 (+++) When the buffer transfer complete callback is asserted first buffer has been transferred and user can ask for a new buffer transfer 00117 request using HAL_MDMA_GenerateSWRequest. 00118 00119 (++) example 2: 00120 (+++) Configure a transfer with request set to MDMA_REQUEST_SW and trigger mode set to MDMA_BLOCK_TRANSFER 00121 (+++) Register a callback for block transfer complete (using callback ID HAL_MDMA_XFER_BLOCKCPLT_CB_ID) 00122 (+++) After calling HAL_MDMA_Start_IT the MDMA will issue the transfer of a first block of data. 00123 (+++) When the block transfer complete callback is asserted the first block has been transferred and user can ask 00124 for a new block transfer request using HAL_MDMA_GenerateSWRequest. 00125 00126 [..] Use HAL_MDMA_GetState() function to return the MDMA state and HAL_MDMA_GetError() in case of error detection. 00127 00128 *** MDMA HAL driver macros list *** 00129 ============================================= 00130 [..] 00131 Below the list of most used macros in MDMA HAL driver. 00132 00133 (+) __HAL_MDMA_ENABLE: Enable the specified MDMA Channel. 00134 (+) __HAL_MDMA_DISABLE: Disable the specified MDMA Channel. 00135 (+) __HAL_MDMA_GET_FLAG: Get the MDMA Channel pending flags. 00136 (+) __HAL_MDMA_CLEAR_FLAG: Clear the MDMA Channel pending flags. 00137 (+) __HAL_MDMA_ENABLE_IT: Enable the specified MDMA Channel interrupts. 00138 (+) __HAL_MDMA_DISABLE_IT: Disable the specified MDMA Channel interrupts. 00139 (+) __HAL_MDMA_GET_IT_SOURCE: Check whether the specified MDMA Channel interrupt has occurred or not. 00140 00141 [..] 00142 (@) You can refer to the header file of the MDMA HAL driver for more useful macros. 00143 00144 [..] 00145 00146 @endverbatim 00147 */ 00148 00149 /* Includes ------------------------------------------------------------------*/ 00150 #include "stm32h7xx_hal.h" 00151 00152 /** @addtogroup STM32H7xx_HAL_Driver 00153 * @{ 00154 */ 00155 00156 /** @defgroup MDMA MDMA 00157 * @brief MDMA HAL module driver 00158 * @{ 00159 */ 00160 00161 #ifdef HAL_MDMA_MODULE_ENABLED 00162 00163 /* Private typedef -----------------------------------------------------------*/ 00164 /* Private constants ---------------------------------------------------------*/ 00165 /** @addtogroup MDMA_Private_Constants 00166 * @{ 00167 */ 00168 #define HAL_TIMEOUT_MDMA_ABORT 5U /* 5 ms */ 00169 #define HAL_MDMA_CHANNEL_SIZE 0x40U /* an MDMA instance channel size is 64 byte */ 00170 /** 00171 * @} 00172 */ 00173 /* Private macro -------------------------------------------------------------*/ 00174 /* Private variables ---------------------------------------------------------*/ 00175 /* Private function prototypes -----------------------------------------------*/ 00176 /** @addtogroup MDMA_Private_Functions_Prototypes 00177 * @{ 00178 */ 00179 static void MDMA_SetConfig(MDMA_HandleTypeDef *hmdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t BlockDataLength, uint32_t BlockCount); 00180 static void MDMA_Init(MDMA_HandleTypeDef *hmdma); 00181 00182 /** 00183 * @} 00184 */ 00185 00186 /** @addtogroup MDMA_Exported_Functions MDMA Exported Functions 00187 * @{ 00188 */ 00189 00190 /** @addtogroup MDMA_Exported_Functions_Group1 00191 * 00192 @verbatim 00193 =============================================================================== 00194 ##### Initialization and de-initialization functions ##### 00195 =============================================================================== 00196 [..] 00197 This section provides functions allowing to : 00198 Initialize and de-initialize the MDMA channel. 00199 Register and Unregister MDMA callbacks 00200 [..] 00201 The HAL_MDMA_Init() function follows the MDMA channel configuration procedures as described in 00202 reference manual. 00203 The HAL_MDMA_DeInit function allows to deinitialize the MDMA channel. 00204 HAL_MDMA_RegisterCallback and HAL_MDMA_UnRegisterCallback functions allows 00205 respectevely to register/unregister an MDMA callback function. 00206 00207 @endverbatim 00208 * @{ 00209 */ 00210 00211 /** 00212 * @brief Initializes the MDMA according to the specified 00213 * parameters in the MDMA_InitTypeDef and create the associated handle. 00214 * @param hmdma: Pointer to a MDMA_HandleTypeDef structure that contains 00215 * the configuration information for the specified MDMA Channel. 00216 * @retval HAL status 00217 */ 00218 HAL_StatusTypeDef HAL_MDMA_Init(MDMA_HandleTypeDef *hmdma) 00219 { 00220 uint32_t tickstart = HAL_GetTick(); 00221 00222 /* Check the MDMA peripheral handle */ 00223 if(hmdma == NULL) 00224 { 00225 return HAL_ERROR; 00226 } 00227 00228 /* Check the parameters */ 00229 assert_param(IS_MDMA_STREAM_ALL_INSTANCE(hmdma->Instance)); 00230 assert_param(IS_MDMA_PRIORITY(hmdma->Init.Priority)); 00231 assert_param(IS_MDMA_ENDIANNESS_MODE(hmdma->Init.Endianness)); 00232 assert_param(IS_MDMA_REQUEST(hmdma->Init.Request)); 00233 assert_param(IS_MDMA_SOURCE_INC(hmdma->Init.SourceInc)); 00234 assert_param(IS_MDMA_DESTINATION_INC(hmdma->Init.DestinationInc)); 00235 assert_param(IS_MDMA_SOURCE_DATASIZE(hmdma->Init.SourceDataSize)); 00236 assert_param(IS_MDMA_DESTINATION_DATASIZE(hmdma->Init.DestDataSize)); 00237 assert_param(IS_MDMA_DATA_ALIGNMENT(hmdma->Init.DataAlignment)); 00238 assert_param(IS_MDMA_SOURCE_BURST(hmdma->Init.SourceBurst)); 00239 assert_param(IS_MDMA_DESTINATION_BURST(hmdma->Init.DestBurst)); 00240 assert_param(IS_MDMA_BUFFER_TRANSFER_LENGTH(hmdma->Init.BufferTransferLength)); 00241 assert_param(IS_MDMA_TRANSFER_TRIGGER_MODE(hmdma->Init.TransferTriggerMode)); 00242 assert_param(IS_MDMA_BLOCK_ADDR_OFFSET(hmdma->Init.SourceBlockAddressOffset)); 00243 assert_param(IS_MDMA_BLOCK_ADDR_OFFSET(hmdma->Init.DestBlockAddressOffset)); 00244 00245 00246 /* Allocate lock resource */ 00247 __HAL_UNLOCK(hmdma); 00248 00249 /* Change MDMA peripheral state */ 00250 hmdma->State = HAL_MDMA_STATE_BUSY; 00251 00252 /* Disable the MDMA channel */ 00253 __HAL_MDMA_DISABLE(hmdma); 00254 00255 /* Check if the MDMA channel is effectively disabled */ 00256 while((hmdma->Instance->CCR & MDMA_CCR_EN) != 0U) 00257 { 00258 /* Check for the Timeout */ 00259 if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_MDMA_ABORT) 00260 { 00261 /* Update error code */ 00262 hmdma->ErrorCode = HAL_MDMA_ERROR_TIMEOUT; 00263 00264 /* Change the MDMA state */ 00265 hmdma->State = HAL_MDMA_STATE_ERROR; 00266 00267 return HAL_ERROR; 00268 } 00269 } 00270 00271 /* Initialize the MDMA channel registers */ 00272 MDMA_Init(hmdma); 00273 00274 /* Reset the MDMA first/last linkedlist node addresses and node counter */ 00275 hmdma->FirstLinkedListNodeAddress = 0; 00276 hmdma->LastLinkedListNodeAddress = 0; 00277 hmdma->LinkedListNodeCounter = 0; 00278 00279 /* Initialize the error code */ 00280 hmdma->ErrorCode = HAL_MDMA_ERROR_NONE; 00281 00282 /* Initialize the MDMA state */ 00283 hmdma->State = HAL_MDMA_STATE_READY; 00284 00285 return HAL_OK; 00286 } 00287 00288 /** 00289 * @brief DeInitializes the MDMA peripheral 00290 * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains 00291 * the configuration information for the specified MDMA Channel. 00292 * @retval HAL status 00293 */ 00294 HAL_StatusTypeDef HAL_MDMA_DeInit(MDMA_HandleTypeDef *hmdma) 00295 { 00296 00297 /* Check the MDMA peripheral handle */ 00298 if(hmdma == NULL) 00299 { 00300 return HAL_ERROR; 00301 } 00302 00303 /* Disable the selected MDMA Channelx */ 00304 __HAL_MDMA_DISABLE(hmdma); 00305 00306 /* Reset MDMA Channel control register */ 00307 hmdma->Instance->CCR = 0; 00308 hmdma->Instance->CTCR = 0; 00309 hmdma->Instance->CBNDTR = 0; 00310 hmdma->Instance->CSAR = 0; 00311 hmdma->Instance->CDAR = 0; 00312 hmdma->Instance->CBRUR = 0; 00313 hmdma->Instance->CLAR = 0; 00314 hmdma->Instance->CTBR = 0; 00315 hmdma->Instance->CMAR = 0; 00316 hmdma->Instance->CMDR = 0; 00317 00318 /* Clear all flags */ 00319 __HAL_MDMA_CLEAR_FLAG(hmdma,(MDMA_FLAG_TE | MDMA_FLAG_CTC | MDMA_FLAG_BRT | MDMA_FLAG_BT | MDMA_FLAG_BFTC)); 00320 00321 /* Reset the MDMA first/last linkedlist node addresses and node counter */ 00322 hmdma->FirstLinkedListNodeAddress = 0; 00323 hmdma->LastLinkedListNodeAddress = 0; 00324 hmdma->LinkedListNodeCounter = 0; 00325 00326 /* Initialize the error code */ 00327 hmdma->ErrorCode = HAL_MDMA_ERROR_NONE; 00328 00329 /* Initialize the MDMA state */ 00330 hmdma->State = HAL_MDMA_STATE_RESET; 00331 00332 /* Release Lock */ 00333 __HAL_UNLOCK(hmdma); 00334 00335 return HAL_OK; 00336 } 00337 00338 /** 00339 * @brief Config the Post request Mask address and Mask data 00340 * @param hmdma : pointer to a MDMA_HandleTypeDef structure that contains 00341 * the configuration information for the specified MDMA Channel. 00342 * @param MaskAddress: specifies the address to be updated (written) with MaskData after a request is served. 00343 * @param MaskData: specifies the value to be written to MaskAddress after a request is served. 00344 * MaskAddress and MaskData could be used to automatically clear a peripheral flag when the request is served. 00345 * @retval HAL status 00346 */ 00347 HAL_StatusTypeDef HAL_MDMA_ConfigPostRequestMask(MDMA_HandleTypeDef *hmdma, uint32_t MaskAddress, uint32_t MaskData) 00348 { 00349 HAL_StatusTypeDef status = HAL_OK; 00350 00351 /* Check the MDMA peripheral handle */ 00352 if(hmdma == NULL) 00353 { 00354 return HAL_ERROR; 00355 } 00356 00357 /* Process locked */ 00358 __HAL_LOCK(hmdma); 00359 00360 if(HAL_MDMA_STATE_READY == hmdma->State) 00361 { 00362 /* if HW request set Post Request MaskAddress and MaskData, */ 00363 if((hmdma->Instance->CTCR & MDMA_CTCR_SWRM) == 0U) 00364 { 00365 /* Set the HW request clear Mask and Data */ 00366 hmdma->Instance->CMAR = MaskAddress; 00367 hmdma->Instance->CMDR = MaskData; 00368 00369 /* 00370 -If the request is done by SW : BWM could be set to 1 or 0. 00371 -If the request is done by a peripheral : 00372 If mask address not set (0) => BWM must be set to 0 00373 If mask address set (different than 0) => BWM could be set to 1 or 0 00374 */ 00375 if(MaskAddress == 0U) 00376 { 00377 hmdma->Instance->CTCR &= ~MDMA_CTCR_BWM; 00378 } 00379 else 00380 { 00381 hmdma->Instance->CTCR |= MDMA_CTCR_BWM; 00382 } 00383 } 00384 else 00385 { 00386 /* Return error status */ 00387 status = HAL_ERROR; 00388 } 00389 } 00390 else 00391 { 00392 /* Return error status */ 00393 status = HAL_ERROR; 00394 } 00395 /* Release Lock */ 00396 __HAL_UNLOCK(hmdma); 00397 00398 return status; 00399 } 00400 00401 /** 00402 * @brief Register callbacks 00403 * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains 00404 * the configuration information for the specified MDMA Channel. 00405 * @param CallbackID: User Callback identifier 00406 * @param pCallback: pointer to callbacsk function. 00407 * @retval HAL status 00408 */ 00409 HAL_StatusTypeDef HAL_MDMA_RegisterCallback(MDMA_HandleTypeDef *hmdma, HAL_MDMA_CallbackIDTypeDef CallbackID, void (* pCallback)(MDMA_HandleTypeDef *_hmdma)) 00410 { 00411 HAL_StatusTypeDef status = HAL_OK; 00412 00413 /* Check the MDMA peripheral handle */ 00414 if(hmdma == NULL) 00415 { 00416 return HAL_ERROR; 00417 } 00418 00419 /* Process locked */ 00420 __HAL_LOCK(hmdma); 00421 00422 if(HAL_MDMA_STATE_READY == hmdma->State) 00423 { 00424 switch (CallbackID) 00425 { 00426 case HAL_MDMA_XFER_CPLT_CB_ID: 00427 hmdma->XferCpltCallback = pCallback; 00428 break; 00429 00430 case HAL_MDMA_XFER_BUFFERCPLT_CB_ID: 00431 hmdma->XferBufferCpltCallback = pCallback; 00432 break; 00433 00434 case HAL_MDMA_XFER_BLOCKCPLT_CB_ID: 00435 hmdma->XferBlockCpltCallback = pCallback; 00436 break; 00437 00438 case HAL_MDMA_XFER_REPBLOCKCPLT_CB_ID: 00439 hmdma->XferRepeatBlockCpltCallback = pCallback; 00440 break; 00441 00442 case HAL_MDMA_XFER_ERROR_CB_ID: 00443 hmdma->XferErrorCallback = pCallback; 00444 break; 00445 00446 case HAL_MDMA_XFER_ABORT_CB_ID: 00447 hmdma->XferAbortCallback = pCallback; 00448 break; 00449 00450 default: 00451 break; 00452 } 00453 } 00454 else 00455 { 00456 /* Return error status */ 00457 status = HAL_ERROR; 00458 } 00459 00460 /* Release Lock */ 00461 __HAL_UNLOCK(hmdma); 00462 00463 return status; 00464 } 00465 00466 /** 00467 * @brief UnRegister callbacks 00468 * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains 00469 * the configuration information for the specified MDMA Channel. 00470 * @param CallbackID: User Callback identifier 00471 * a HAL_MDMA_CallbackIDTypeDef ENUM as parameter. 00472 * @retval HAL status 00473 */ 00474 HAL_StatusTypeDef HAL_MDMA_UnRegisterCallback(MDMA_HandleTypeDef *hmdma, HAL_MDMA_CallbackIDTypeDef CallbackID) 00475 { 00476 HAL_StatusTypeDef status = HAL_OK; 00477 00478 /* Check the MDMA peripheral handle */ 00479 if(hmdma == NULL) 00480 { 00481 return HAL_ERROR; 00482 } 00483 00484 /* Process locked */ 00485 __HAL_LOCK(hmdma); 00486 00487 if(HAL_MDMA_STATE_READY == hmdma->State) 00488 { 00489 switch (CallbackID) 00490 { 00491 case HAL_MDMA_XFER_CPLT_CB_ID: 00492 hmdma->XferCpltCallback = NULL; 00493 break; 00494 00495 case HAL_MDMA_XFER_BUFFERCPLT_CB_ID: 00496 hmdma->XferBufferCpltCallback = NULL; 00497 break; 00498 00499 case HAL_MDMA_XFER_BLOCKCPLT_CB_ID: 00500 hmdma->XferBlockCpltCallback = NULL; 00501 break; 00502 00503 case HAL_MDMA_XFER_REPBLOCKCPLT_CB_ID: 00504 hmdma->XferRepeatBlockCpltCallback = NULL; 00505 break; 00506 00507 case HAL_MDMA_XFER_ERROR_CB_ID: 00508 hmdma->XferErrorCallback = NULL; 00509 break; 00510 00511 case HAL_MDMA_XFER_ABORT_CB_ID: 00512 hmdma->XferAbortCallback = NULL; 00513 break; 00514 00515 case HAL_MDMA_XFER_ALL_CB_ID: 00516 hmdma->XferCpltCallback = NULL; 00517 hmdma->XferBufferCpltCallback = NULL; 00518 hmdma->XferBlockCpltCallback = NULL; 00519 hmdma->XferRepeatBlockCpltCallback = NULL; 00520 hmdma->XferErrorCallback = NULL; 00521 hmdma->XferAbortCallback = NULL; 00522 break; 00523 00524 default: 00525 status = HAL_ERROR; 00526 break; 00527 } 00528 } 00529 else 00530 { 00531 status = HAL_ERROR; 00532 } 00533 00534 /* Release Lock */ 00535 __HAL_UNLOCK(hmdma); 00536 00537 return status; 00538 } 00539 00540 /** 00541 * @} 00542 */ 00543 00544 /** @addtogroup MDMA_Exported_Functions_Group2 00545 * 00546 @verbatim 00547 =============================================================================== 00548 ##### Linked list operation functions ##### 00549 =============================================================================== 00550 [..] This section provides functions allowing to: 00551 (+) Create a linked list node 00552 (+) Add a node to the MDMA linked list 00553 (+) Remove a node from the MDMA linked list 00554 (+) Enable/Disable linked list circular mode 00555 @endverbatim 00556 * @{ 00557 */ 00558 00559 /** 00560 * @brief Initializes an MDMA Link Node according to the specified 00561 * parameters in the pMDMA_LinkedListNodeConfig . 00562 * @param pNode: Pointer to a MDMA_LinkNodeTypeDef structure that contains Linked list node 00563 * registers configurations. 00564 * @param pNodeConfig: Pointer to a MDMA_LinkNodeConfTypeDef structure that contains 00565 * the configuration information for the specified MDMA Linked List Node. 00566 * @retval HAL status 00567 */ 00568 HAL_StatusTypeDef HAL_MDMA_LinkedList_CreateNode(MDMA_LinkNodeTypeDef *pNode, MDMA_LinkNodeConfTypeDef *pNodeConfig) 00569 { 00570 uint32_t addressMask; 00571 uint32_t blockoffset; 00572 00573 /* Check the MDMA peripheral state */ 00574 if((pNode == NULL) || (pNodeConfig == NULL)) 00575 { 00576 return HAL_ERROR; 00577 } 00578 00579 /* Check the parameters */ 00580 assert_param(IS_MDMA_PRIORITY(pNodeConfig->Init.Priority)); 00581 assert_param(IS_MDMA_ENDIANNESS_MODE(pNodeConfig->Init.Endianness)); 00582 assert_param(IS_MDMA_REQUEST(pNodeConfig->Init.Request)); 00583 assert_param(IS_MDMA_SOURCE_INC(pNodeConfig->Init.SourceInc)); 00584 assert_param(IS_MDMA_DESTINATION_INC(pNodeConfig->Init.DestinationInc)); 00585 assert_param(IS_MDMA_SOURCE_DATASIZE(pNodeConfig->Init.SourceDataSize)); 00586 assert_param(IS_MDMA_DESTINATION_DATASIZE(pNodeConfig->Init.DestDataSize)); 00587 assert_param(IS_MDMA_DATA_ALIGNMENT(pNodeConfig->Init.DataAlignment)); 00588 assert_param(IS_MDMA_SOURCE_BURST(pNodeConfig->Init.SourceBurst)); 00589 assert_param(IS_MDMA_DESTINATION_BURST(pNodeConfig->Init.DestBurst)); 00590 assert_param(IS_MDMA_BUFFER_TRANSFER_LENGTH(pNodeConfig->Init.BufferTransferLength)); 00591 assert_param(IS_MDMA_TRANSFER_TRIGGER_MODE(pNodeConfig->Init.TransferTriggerMode)); 00592 assert_param(IS_MDMA_BLOCK_ADDR_OFFSET(pNodeConfig->Init.SourceBlockAddressOffset)); 00593 assert_param(IS_MDMA_BLOCK_ADDR_OFFSET(pNodeConfig->Init.DestBlockAddressOffset)); 00594 00595 assert_param(IS_MDMA_TRANSFER_LENGTH(pNodeConfig->BlockDataLength)); 00596 assert_param(IS_MDMA_BLOCK_COUNT(pNodeConfig->BlockCount)); 00597 00598 00599 /* Configure next Link node Address Register to zero */ 00600 pNode->CLAR = 0; 00601 00602 /* Configure the Link Node registers*/ 00603 pNode->CTBR = 0; 00604 pNode->CMAR = 0; 00605 pNode->CMDR = 0; 00606 pNode->Reserved = 0; 00607 00608 /* Write new CTCR Register value */ 00609 pNode->CTCR = pNodeConfig->Init.SourceInc | pNodeConfig->Init.DestinationInc | \ 00610 pNodeConfig->Init.SourceDataSize | pNodeConfig->Init.DestDataSize | \ 00611 pNodeConfig->Init.DataAlignment| pNodeConfig->Init.SourceBurst | \ 00612 pNodeConfig->Init.DestBurst | \ 00613 ((pNodeConfig->Init.BufferTransferLength - 1U) << MDMA_CTCR_TLEN_Pos) | \ 00614 pNodeConfig->Init.TransferTriggerMode; 00615 00616 /* If SW request set the CTCR register to SW Request Mode*/ 00617 if(pNodeConfig->Init.Request == MDMA_REQUEST_SW) 00618 { 00619 pNode->CTCR |= MDMA_CTCR_SWRM; 00620 } 00621 00622 /* 00623 -If the request is done by SW : BWM could be set to 1 or 0. 00624 -If the request is done by a peripheral : 00625 If mask address not set (0) => BWM must be set to 0 00626 If mask address set (different than 0) => BWM could be set to 1 or 0 00627 */ 00628 if((pNodeConfig->Init.Request == MDMA_REQUEST_SW) || (pNodeConfig->PostRequestMaskAddress != 0U)) 00629 { 00630 pNode->CTCR |= MDMA_CTCR_BWM; 00631 } 00632 00633 /* Set the new CBNDTR Register value */ 00634 pNode->CBNDTR = ((pNodeConfig->BlockCount - 1U) << MDMA_CBNDTR_BRC_Pos) & MDMA_CBNDTR_BRC; 00635 00636 /* if block source address offset is negative set the Block Repeat Source address Update Mode to decrement */ 00637 if(pNodeConfig->Init.SourceBlockAddressOffset < 0) 00638 { 00639 pNode->CBNDTR |= MDMA_CBNDTR_BRSUM; 00640 /*write new CBRUR Register value : source repeat block offset */ 00641 blockoffset = (uint32_t)(- pNodeConfig->Init.SourceBlockAddressOffset); 00642 pNode->CBRUR = blockoffset & 0x0000FFFFU; 00643 } 00644 else 00645 { 00646 /*write new CBRUR Register value : source repeat block offset */ 00647 pNode->CBRUR = (((uint32_t) pNodeConfig->Init.SourceBlockAddressOffset) & 0x0000FFFFU); 00648 } 00649 00650 /* if block destination address offset is negative set the Block Repeat destination address Update Mode to decrement */ 00651 if(pNodeConfig->Init.DestBlockAddressOffset < 0) 00652 { 00653 pNode->CBNDTR |= MDMA_CBNDTR_BRDUM; 00654 /*write new CBRUR Register value : destination repeat block offset */ 00655 blockoffset = (uint32_t)(- pNodeConfig->Init.DestBlockAddressOffset); 00656 pNode->CBRUR |= ((blockoffset & 0x0000FFFFU) << MDMA_CBRUR_DUV_Pos); 00657 } 00658 else 00659 { 00660 /*write new CBRUR Register value : destination repeat block offset */ 00661 pNode->CBRUR |= ((((uint32_t)pNodeConfig->Init.DestBlockAddressOffset) & 0x0000FFFFU) << MDMA_CBRUR_DUV_Pos); 00662 } 00663 00664 /* Configure MDMA Link Node data length */ 00665 pNode->CBNDTR |= pNodeConfig->BlockDataLength; 00666 00667 /* Configure MDMA Link Node destination address */ 00668 pNode->CDAR = pNodeConfig->DstAddress; 00669 00670 /* Configure MDMA Link Node Source address */ 00671 pNode->CSAR = pNodeConfig->SrcAddress; 00672 00673 /* if HW request set the HW request and the requet CleraMask and ClearData MaskData, */ 00674 if(pNodeConfig->Init.Request != MDMA_REQUEST_SW) 00675 { 00676 /* Set the HW request in CTBR register */ 00677 pNode->CTBR = pNodeConfig->Init.Request & MDMA_CTBR_TSEL; 00678 /* Set the HW request clear Mask and Data */ 00679 pNode->CMAR = pNodeConfig->PostRequestMaskAddress; 00680 pNode->CMDR = pNodeConfig->PostRequestMaskData; 00681 } 00682 00683 addressMask = pNodeConfig->SrcAddress & 0xFF000000U; 00684 if((addressMask == 0x20000000U) || (addressMask == 0x00000000U)) 00685 { 00686 /*The AHBSbus is used as source (read operation) on channel x */ 00687 pNode->CTBR |= MDMA_CTBR_SBUS; 00688 } 00689 00690 addressMask = pNodeConfig->DstAddress & 0xFF000000U; 00691 if((addressMask == 0x20000000U) || (addressMask == 0x00000000U)) 00692 { 00693 /*The AHB bus is used as destination (write operation) on channel x */ 00694 pNode->CTBR |= MDMA_CTBR_DBUS; 00695 } 00696 00697 return HAL_OK; 00698 } 00699 00700 /** 00701 * @brief Connect a node to the linked list. 00702 * @param hmdma : Pointer to a MDMA_HandleTypeDef structure that contains 00703 * the configuration information for the specified MDMA Channel. 00704 * @param pNewNode : Pointer to a MDMA_LinkNodeTypeDef structure that contains Linked list node 00705 * to be add to the list. 00706 * @param pPrevNode : Pointer to the new node position in the linked list or zero to insert the new node 00707 * at the end of the list 00708 * 00709 * @retval HAL status 00710 */ 00711 HAL_StatusTypeDef HAL_MDMA_LinkedList_AddNode(MDMA_HandleTypeDef *hmdma, MDMA_LinkNodeTypeDef *pNewNode, MDMA_LinkNodeTypeDef *pPrevNode) 00712 { 00713 MDMA_LinkNodeTypeDef *pNode; 00714 uint32_t counter = 0, nodeInserted = 0; 00715 HAL_StatusTypeDef hal_status = HAL_OK; 00716 00717 /* Check the MDMA peripheral handle */ 00718 if((hmdma == NULL) || (pNewNode == NULL)) 00719 { 00720 return HAL_ERROR; 00721 } 00722 00723 /* Process locked */ 00724 __HAL_LOCK(hmdma); 00725 00726 if(HAL_MDMA_STATE_READY == hmdma->State) 00727 { 00728 /* Change MDMA peripheral state */ 00729 hmdma->State = HAL_MDMA_STATE_BUSY; 00730 00731 /* Check if this is the first node (after the Inititlization node) */ 00732 if((uint32_t)hmdma->FirstLinkedListNodeAddress == 0U) 00733 { 00734 if(pPrevNode == NULL) 00735 { 00736 /* if this is the first node after the initialization 00737 connect this node to the node 0 by updating 00738 the MDMA channel CLAR register to this node address */ 00739 hmdma->Instance->CLAR = (uint32_t)pNewNode; 00740 /* Set the MDMA handle First linked List node*/ 00741 hmdma->FirstLinkedListNodeAddress = pNewNode; 00742 00743 /*reset New node link */ 00744 pNewNode->CLAR = 0; 00745 00746 /* Update the Handle last node address */ 00747 hmdma->LastLinkedListNodeAddress = pNewNode; 00748 00749 hmdma->LinkedListNodeCounter = 1; 00750 } 00751 else 00752 { 00753 hal_status = HAL_ERROR; 00754 } 00755 } 00756 else if(hmdma->FirstLinkedListNodeAddress != pNewNode) 00757 { 00758 /* Check if the node to insert already exists*/ 00759 pNode = hmdma->FirstLinkedListNodeAddress; 00760 while((counter < hmdma->LinkedListNodeCounter) && (hal_status == HAL_OK)) 00761 { 00762 if(pNode->CLAR == (uint32_t)pNewNode) 00763 { 00764 hal_status = HAL_ERROR; /* error this node already exist in the linked list and it is not first node */ 00765 } 00766 pNode = (MDMA_LinkNodeTypeDef *)pNode->CLAR; 00767 counter++; 00768 } 00769 00770 if(hal_status == HAL_OK) 00771 { 00772 /* Check if the previous node is the last one in the current list or zero */ 00773 if((pPrevNode == hmdma->LastLinkedListNodeAddress) || (pPrevNode == NULL)) 00774 { 00775 /* insert the new node at the end of the list */ 00776 pNewNode->CLAR = hmdma->LastLinkedListNodeAddress->CLAR; 00777 hmdma->LastLinkedListNodeAddress->CLAR = (uint32_t)pNewNode; 00778 /* Update the Handle last node address */ 00779 hmdma->LastLinkedListNodeAddress = pNewNode; 00780 /* Increment the linked list node counter */ 00781 hmdma->LinkedListNodeCounter++; 00782 } 00783 else 00784 { 00785 /*insert the new node after the pPreviousNode node */ 00786 pNode = hmdma->FirstLinkedListNodeAddress; 00787 counter = 0; 00788 while((counter < hmdma->LinkedListNodeCounter) && (nodeInserted == 0U)) 00789 { 00790 counter++; 00791 if(pNode == pPrevNode) 00792 { 00793 /*Insert the new node after the previous one */ 00794 pNewNode->CLAR = pNode->CLAR; 00795 pNode->CLAR = (uint32_t)pNewNode; 00796 /* Increment the linked list node counter */ 00797 hmdma->LinkedListNodeCounter++; 00798 nodeInserted = 1; 00799 } 00800 else 00801 { 00802 pNode = (MDMA_LinkNodeTypeDef *)pNode->CLAR; 00803 } 00804 } 00805 00806 if(nodeInserted == 0U) 00807 { 00808 hal_status = HAL_ERROR; 00809 } 00810 } 00811 } 00812 } 00813 else 00814 { 00815 hal_status = HAL_ERROR; 00816 } 00817 00818 /* Process unlocked */ 00819 __HAL_UNLOCK(hmdma); 00820 00821 hmdma->State = HAL_MDMA_STATE_READY; 00822 00823 return hal_status; 00824 } 00825 else 00826 { 00827 /* Process unlocked */ 00828 __HAL_UNLOCK(hmdma); 00829 00830 /* Return error status */ 00831 return HAL_BUSY; 00832 } 00833 } 00834 00835 /** 00836 * @brief Disconnect/Remove a node from the transfer linked list. 00837 * @param hmdma : Pointer to a MDMA_HandleTypeDef structure that contains 00838 * the configuration information for the specified MDMA Channel. 00839 * @param pNode : Pointer to a MDMA_LinkNodeTypeDef structure that contains Linked list node 00840 * to be removed from the list. 00841 * 00842 * @retval HAL status 00843 */ 00844 HAL_StatusTypeDef HAL_MDMA_LinkedList_RemoveNode(MDMA_HandleTypeDef *hmdma, MDMA_LinkNodeTypeDef *pNode) 00845 { 00846 MDMA_LinkNodeTypeDef *ptmpNode; 00847 uint32_t counter = 0, nodeDeleted = 0; 00848 HAL_StatusTypeDef hal_status = HAL_OK; 00849 00850 /* Check the MDMA peripheral handle */ 00851 if((hmdma == NULL) || (pNode == NULL)) 00852 { 00853 return HAL_ERROR; 00854 } 00855 00856 /* Process locked */ 00857 __HAL_LOCK(hmdma); 00858 00859 if(HAL_MDMA_STATE_READY == hmdma->State) 00860 { 00861 /* Change MDMA peripheral state */ 00862 hmdma->State = HAL_MDMA_STATE_BUSY; 00863 00864 /* If first and last node are null (no nodes in the list) : return error*/ 00865 if(((uint32_t)hmdma->FirstLinkedListNodeAddress == 0U) || ((uint32_t)hmdma->LastLinkedListNodeAddress == 0U) || (hmdma->LinkedListNodeCounter == 0U)) 00866 { 00867 hal_status = HAL_ERROR; 00868 } 00869 else if(hmdma->FirstLinkedListNodeAddress == pNode) /* Deleting first node */ 00870 { 00871 /* Delete 1st node */ 00872 if(hmdma->LastLinkedListNodeAddress == pNode) 00873 { 00874 /*if the last node is at the same time the first one (1 single node after the init node 0) 00875 then update the last node too */ 00876 00877 hmdma->FirstLinkedListNodeAddress = 0; 00878 hmdma->LastLinkedListNodeAddress = 0; 00879 hmdma->LinkedListNodeCounter = 0; 00880 00881 hmdma->Instance->CLAR = 0; 00882 } 00883 else 00884 { 00885 if((uint32_t)hmdma->FirstLinkedListNodeAddress == hmdma->LastLinkedListNodeAddress->CLAR) 00886 { 00887 /* if last node is looping to first (circular list) one update the last node connection */ 00888 hmdma->LastLinkedListNodeAddress->CLAR = pNode->CLAR; 00889 } 00890 00891 /* if deleting the first node after the initialization 00892 connect the next node to the node 0 by updating 00893 the MDMA channel CLAR register to this node address */ 00894 hmdma->Instance->CLAR = pNode->CLAR; 00895 hmdma->FirstLinkedListNodeAddress = (MDMA_LinkNodeTypeDef *)hmdma->Instance->CLAR; 00896 /* Update the Handle node counter */ 00897 hmdma->LinkedListNodeCounter--; 00898 } 00899 } 00900 else /* Deleting any other node */ 00901 { 00902 /*Deleted node is not the first one : find it */ 00903 ptmpNode = hmdma->FirstLinkedListNodeAddress; 00904 while((counter < hmdma->LinkedListNodeCounter) && (nodeDeleted == 0U)) 00905 { 00906 counter++; 00907 if(ptmpNode->CLAR == ((uint32_t)pNode)) 00908 { 00909 /* if deleting the last node */ 00910 if(pNode == hmdma->LastLinkedListNodeAddress) 00911 { 00912 /*Update the linked list last node address in the handle*/ 00913 hmdma->LastLinkedListNodeAddress = ptmpNode; 00914 } 00915 /* update the next node link after deleting pMDMA_LinkedListNode */ 00916 ptmpNode->CLAR = pNode->CLAR; 00917 nodeDeleted = 1; 00918 /* Update the Handle node counter */ 00919 hmdma->LinkedListNodeCounter--; 00920 } 00921 else 00922 { 00923 ptmpNode = (MDMA_LinkNodeTypeDef *)ptmpNode->CLAR; 00924 } 00925 } 00926 00927 if(nodeDeleted == 0U) 00928 { 00929 /* last node reashed without finding the node to delete : return error */ 00930 hal_status = HAL_ERROR; 00931 } 00932 } 00933 00934 /* Process unlocked */ 00935 __HAL_UNLOCK(hmdma); 00936 00937 hmdma->State = HAL_MDMA_STATE_READY; 00938 00939 return hal_status; 00940 } 00941 else 00942 { 00943 /* Process unlocked */ 00944 __HAL_UNLOCK(hmdma); 00945 00946 /* Return error status */ 00947 return HAL_BUSY; 00948 } 00949 } 00950 00951 /** 00952 * @brief Make the linked list circular by connecting the last node to the first. 00953 * @param hmdma : Pointer to a MDMA_HandleTypeDef structure that contains 00954 * the configuration information for the specified MDMA Channel. 00955 * @retval HAL status 00956 */ 00957 HAL_StatusTypeDef HAL_MDMA_LinkedList_EnableCircularMode(MDMA_HandleTypeDef *hmdma) 00958 { 00959 HAL_StatusTypeDef hal_status = HAL_OK; 00960 00961 /* Check the MDMA peripheral handle */ 00962 if(hmdma == NULL) 00963 { 00964 return HAL_ERROR; 00965 } 00966 00967 /* Process locked */ 00968 __HAL_LOCK(hmdma); 00969 00970 if(HAL_MDMA_STATE_READY == hmdma->State) 00971 { 00972 /* Change MDMA peripheral state */ 00973 hmdma->State = HAL_MDMA_STATE_BUSY; 00974 00975 /* If first and last node are null (no nodes in the list) : return error*/ 00976 if(((uint32_t)hmdma->FirstLinkedListNodeAddress == 0U) || ((uint32_t)hmdma->LastLinkedListNodeAddress == 0U) || (hmdma->LinkedListNodeCounter == 0U)) 00977 { 00978 hal_status = HAL_ERROR; 00979 } 00980 else 00981 { 00982 /* to enable circular mode Last Node should be connected to first node */ 00983 hmdma->LastLinkedListNodeAddress->CLAR = (uint32_t)hmdma->FirstLinkedListNodeAddress; 00984 } 00985 00986 } 00987 /* Process unlocked */ 00988 __HAL_UNLOCK(hmdma); 00989 00990 hmdma->State = HAL_MDMA_STATE_READY; 00991 00992 return hal_status; 00993 } 00994 00995 /** 00996 * @brief Disable the linked list circular mode by setting the last node connection to null 00997 * @param hmdma : Pointer to a MDMA_HandleTypeDef structure that contains 00998 * the configuration information for the specified MDMA Channel. 00999 * @retval HAL status 01000 */ 01001 HAL_StatusTypeDef HAL_MDMA_LinkedList_DisableCircularMode(MDMA_HandleTypeDef *hmdma) 01002 { 01003 HAL_StatusTypeDef hal_status = HAL_OK; 01004 01005 /* Check the MDMA peripheral handle */ 01006 if(hmdma == NULL) 01007 { 01008 return HAL_ERROR; 01009 } 01010 01011 /* Process locked */ 01012 __HAL_LOCK(hmdma); 01013 01014 if(HAL_MDMA_STATE_READY == hmdma->State) 01015 { 01016 /* Change MDMA peripheral state */ 01017 hmdma->State = HAL_MDMA_STATE_BUSY; 01018 01019 /* If first and last node are null (no nodes in the list) : return error*/ 01020 if(((uint32_t)hmdma->FirstLinkedListNodeAddress == 0U) || ((uint32_t)hmdma->LastLinkedListNodeAddress == 0U) || (hmdma->LinkedListNodeCounter == 0U)) 01021 { 01022 hal_status = HAL_ERROR; 01023 } 01024 else 01025 { 01026 /* to disable circular mode Last Node should be connected to NULL */ 01027 hmdma->LastLinkedListNodeAddress->CLAR = 0; 01028 } 01029 01030 } 01031 /* Process unlocked */ 01032 __HAL_UNLOCK(hmdma); 01033 01034 hmdma->State = HAL_MDMA_STATE_READY; 01035 01036 return hal_status; 01037 } 01038 01039 /** 01040 * @} 01041 */ 01042 01043 /** @addtogroup MDMA_Exported_Functions_Group3 01044 * 01045 @verbatim 01046 =============================================================================== 01047 ##### IO operation functions ##### 01048 =============================================================================== 01049 [..] This section provides functions allowing to: 01050 (+) Configure the source, destination address and data length and Start MDMA transfer 01051 (+) Configure the source, destination address and data length and 01052 Start MDMA transfer with interrupt 01053 (+) Abort MDMA transfer 01054 (+) Poll for transfer complete 01055 (+) Generate a SW request (when Request is set to MDMA_REQUEST_SW) 01056 (+) Handle MDMA interrupt request 01057 01058 @endverbatim 01059 * @{ 01060 */ 01061 01062 /** 01063 * @brief Starts the MDMA Transfer. 01064 * @param hmdma : pointer to a MDMA_HandleTypeDef structure that contains 01065 * the configuration information for the specified MDMA Channel. 01066 * @param SrcAddress : The source memory Buffer address 01067 * @param DstAddress : The destination memory Buffer address 01068 * @param BlockDataLength : The length of a block transfer in bytes 01069 * @param BlockCount : The number of a blocks to be transfer 01070 * @retval HAL status 01071 */ 01072 HAL_StatusTypeDef HAL_MDMA_Start(MDMA_HandleTypeDef *hmdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t BlockDataLength, uint32_t BlockCount) 01073 { 01074 /* Check the parameters */ 01075 assert_param(IS_MDMA_TRANSFER_LENGTH(BlockDataLength)); 01076 assert_param(IS_MDMA_BLOCK_COUNT(BlockCount)); 01077 01078 /* Check the MDMA peripheral handle */ 01079 if(hmdma == NULL) 01080 { 01081 return HAL_ERROR; 01082 } 01083 01084 /* Process locked */ 01085 __HAL_LOCK(hmdma); 01086 01087 if(HAL_MDMA_STATE_READY == hmdma->State) 01088 { 01089 /* Change MDMA peripheral state */ 01090 hmdma->State = HAL_MDMA_STATE_BUSY; 01091 01092 /* Initialize the error code */ 01093 hmdma->ErrorCode = HAL_MDMA_ERROR_NONE; 01094 01095 /* Disable the peripheral */ 01096 __HAL_MDMA_DISABLE(hmdma); 01097 01098 /* Configure the source, destination address and the data length */ 01099 MDMA_SetConfig(hmdma, SrcAddress, DstAddress, BlockDataLength, BlockCount); 01100 01101 /* Enable the Peripheral */ 01102 __HAL_MDMA_ENABLE(hmdma); 01103 01104 if(hmdma->Init.Request == MDMA_REQUEST_SW) 01105 { 01106 /* activate If SW request mode*/ 01107 hmdma->Instance->CCR |= MDMA_CCR_SWRQ; 01108 } 01109 } 01110 else 01111 { 01112 /* Process unlocked */ 01113 __HAL_UNLOCK(hmdma); 01114 01115 /* Return error status */ 01116 return HAL_BUSY; 01117 } 01118 01119 return HAL_OK; 01120 } 01121 01122 /** 01123 * @brief Starts the MDMA Transfer with interrupts enabled. 01124 * @param hmdma : pointer to a MDMA_HandleTypeDef structure that contains 01125 * the configuration information for the specified MDMA Channel. 01126 * @param SrcAddress : The source memory Buffer address 01127 * @param DstAddress : The destination memory Buffer address 01128 * @param BlockDataLength : The length of a block transfer in bytes 01129 * @param BlockCount : The number of a blocks to be transfer 01130 * @retval HAL status 01131 */ 01132 HAL_StatusTypeDef HAL_MDMA_Start_IT(MDMA_HandleTypeDef *hmdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t BlockDataLength, uint32_t BlockCount) 01133 { 01134 /* Check the parameters */ 01135 assert_param(IS_MDMA_TRANSFER_LENGTH(BlockDataLength)); 01136 assert_param(IS_MDMA_BLOCK_COUNT(BlockCount)); 01137 01138 /* Check the MDMA peripheral handle */ 01139 if(hmdma == NULL) 01140 { 01141 return HAL_ERROR; 01142 } 01143 01144 /* Process locked */ 01145 __HAL_LOCK(hmdma); 01146 01147 if(HAL_MDMA_STATE_READY == hmdma->State) 01148 { 01149 /* Change MDMA peripheral state */ 01150 hmdma->State = HAL_MDMA_STATE_BUSY; 01151 01152 /* Initialize the error code */ 01153 hmdma->ErrorCode = HAL_MDMA_ERROR_NONE; 01154 01155 /* Disable the peripheral */ 01156 __HAL_MDMA_DISABLE(hmdma); 01157 01158 /* Configure the source, destination address and the data length */ 01159 MDMA_SetConfig(hmdma, SrcAddress, DstAddress, BlockDataLength, BlockCount); 01160 01161 /* Enable Common interrupts i.e Transfer Error IT and Channel Transfer Complete IT*/ 01162 __HAL_MDMA_ENABLE_IT(hmdma, (MDMA_IT_TE | MDMA_IT_CTC)); 01163 01164 if(hmdma->XferBlockCpltCallback != NULL) 01165 { 01166 /* if Block transfer complete Callback is set enable the corresponding IT*/ 01167 __HAL_MDMA_ENABLE_IT(hmdma, MDMA_IT_BT); 01168 } 01169 01170 if(hmdma->XferRepeatBlockCpltCallback != NULL) 01171 { 01172 /* if Repeated Block transfer complete Callback is set enable the corresponding IT*/ 01173 __HAL_MDMA_ENABLE_IT(hmdma, MDMA_IT_BRT); 01174 } 01175 01176 if(hmdma->XferBufferCpltCallback != NULL) 01177 { 01178 /* if buffer transfer complete Callback is set enable the corresponding IT*/ 01179 __HAL_MDMA_ENABLE_IT(hmdma, MDMA_IT_BFTC); 01180 } 01181 01182 /* Enable the Peripheral */ 01183 __HAL_MDMA_ENABLE(hmdma); 01184 01185 if(hmdma->Init.Request == MDMA_REQUEST_SW) 01186 { 01187 /* activate If SW request mode*/ 01188 hmdma->Instance->CCR |= MDMA_CCR_SWRQ; 01189 } 01190 } 01191 else 01192 { 01193 /* Process unlocked */ 01194 __HAL_UNLOCK(hmdma); 01195 01196 /* Return error status */ 01197 return HAL_BUSY; 01198 } 01199 01200 return HAL_OK; 01201 } 01202 01203 /** 01204 * @brief Aborts the MDMA Transfer. 01205 * @param hmdma : pointer to a MDMA_HandleTypeDef structure that contains 01206 * the configuration information for the specified MDMA Channel. 01207 * 01208 * @note After disabling a MDMA Channel, a check for wait until the MDMA Channel is 01209 * effectively disabled is added. If a Channel is disabled 01210 * while a data transfer is ongoing, the current data will be transferred 01211 * and the Channel will be effectively disabled only after the transfer of 01212 * this single data is finished. 01213 * @retval HAL status 01214 */ 01215 HAL_StatusTypeDef HAL_MDMA_Abort(MDMA_HandleTypeDef *hmdma) 01216 { 01217 uint32_t tickstart = HAL_GetTick(); 01218 01219 /* Check the MDMA peripheral handle */ 01220 if(hmdma == NULL) 01221 { 01222 return HAL_ERROR; 01223 } 01224 01225 if(HAL_MDMA_STATE_BUSY != hmdma->State) 01226 { 01227 hmdma->ErrorCode = HAL_MDMA_ERROR_NO_XFER; 01228 01229 /* Process Unlocked */ 01230 __HAL_UNLOCK(hmdma); 01231 01232 return HAL_ERROR; 01233 } 01234 else 01235 { 01236 /* Disable all the transfer interrupts */ 01237 __HAL_MDMA_DISABLE_IT(hmdma, (MDMA_IT_TE | MDMA_IT_CTC | MDMA_IT_BT | MDMA_IT_BRT | MDMA_IT_BFTC)); 01238 01239 /* Disable the channel */ 01240 __HAL_MDMA_DISABLE(hmdma); 01241 01242 /* Check if the MDMA Channel is effectively disabled */ 01243 while((hmdma->Instance->CCR & MDMA_CCR_EN) != 0U) 01244 { 01245 /* Check for the Timeout */ 01246 if( (HAL_GetTick() - tickstart ) > HAL_TIMEOUT_MDMA_ABORT) 01247 { 01248 /* Update error code */ 01249 hmdma->ErrorCode |= HAL_MDMA_ERROR_TIMEOUT; 01250 01251 /* Process Unlocked */ 01252 __HAL_UNLOCK(hmdma); 01253 01254 /* Change the MDMA state */ 01255 hmdma->State = HAL_MDMA_STATE_ERROR; 01256 01257 return HAL_ERROR; 01258 } 01259 } 01260 01261 /* Clear all interrupt flags */ 01262 __HAL_MDMA_CLEAR_FLAG(hmdma, (MDMA_FLAG_TE | MDMA_FLAG_CTC | MDMA_FLAG_BT | MDMA_FLAG_BRT | MDMA_FLAG_BFTC)); 01263 01264 /* Process Unlocked */ 01265 __HAL_UNLOCK(hmdma); 01266 01267 /* Change the MDMA state*/ 01268 hmdma->State = HAL_MDMA_STATE_READY; 01269 } 01270 01271 return HAL_OK; 01272 } 01273 01274 /** 01275 * @brief Aborts the MDMA Transfer in Interrupt mode. 01276 * @param hmdma : pointer to a MDMA_HandleTypeDef structure that contains 01277 * the configuration information for the specified MDMA Channel. 01278 * @retval HAL status 01279 */ 01280 HAL_StatusTypeDef HAL_MDMA_Abort_IT(MDMA_HandleTypeDef *hmdma) 01281 { 01282 /* Check the MDMA peripheral handle */ 01283 if(hmdma == NULL) 01284 { 01285 return HAL_ERROR; 01286 } 01287 01288 if(HAL_MDMA_STATE_BUSY != hmdma->State) 01289 { 01290 /* No transfer ongoing */ 01291 hmdma->ErrorCode = HAL_MDMA_ERROR_NO_XFER; 01292 01293 return HAL_ERROR; 01294 } 01295 else 01296 { 01297 /* Set Abort State */ 01298 hmdma->State = HAL_MDMA_STATE_ABORT; 01299 01300 /* Disable the stream */ 01301 __HAL_MDMA_DISABLE(hmdma); 01302 } 01303 01304 return HAL_OK; 01305 } 01306 01307 /** 01308 * @brief Polling for transfer complete. 01309 * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains 01310 * the configuration information for the specified MDMA Channel. 01311 * @param CompleteLevel: Specifies the MDMA level complete. 01312 * @param Timeout: Timeout duration. 01313 * @retval HAL status 01314 */ 01315 HAL_StatusTypeDef HAL_MDMA_PollForTransfer(MDMA_HandleTypeDef *hmdma, HAL_MDMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout) 01316 { 01317 uint32_t levelFlag, errorFlag; 01318 uint32_t tickstart; 01319 01320 /* Check the parameters */ 01321 assert_param(IS_MDMA_LEVEL_COMPLETE(CompleteLevel)); 01322 01323 /* Check the MDMA peripheral handle */ 01324 if(hmdma == NULL) 01325 { 01326 return HAL_ERROR; 01327 } 01328 01329 if(HAL_MDMA_STATE_BUSY != hmdma->State) 01330 { 01331 /* No transfer ongoing */ 01332 hmdma->ErrorCode = HAL_MDMA_ERROR_NO_XFER; 01333 01334 return HAL_ERROR; 01335 } 01336 01337 /* Get the level transfer complete flag */ 01338 levelFlag = ((CompleteLevel == HAL_MDMA_FULL_TRANSFER) ? MDMA_FLAG_CTC : \ 01339 (CompleteLevel == HAL_MDMA_BUFFER_TRANSFER)? MDMA_FLAG_BFTC : \ 01340 (CompleteLevel == HAL_MDMA_BLOCK_TRANSFER) ? MDMA_FLAG_BT : \ 01341 MDMA_FLAG_BRT); 01342 01343 01344 /* Get timeout */ 01345 tickstart = HAL_GetTick(); 01346 01347 while(__HAL_MDMA_GET_FLAG(hmdma, levelFlag) == 0U) 01348 { 01349 if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_TE) != 0U)) 01350 { 01351 /* Get the transfer error source flag */ 01352 errorFlag = hmdma->Instance->CESR; 01353 01354 if((errorFlag & MDMA_CESR_TED) == 0U) 01355 { 01356 /* Update error code : Read Transfer error */ 01357 hmdma->ErrorCode |= HAL_MDMA_ERROR_READ_XFER; 01358 } 01359 else 01360 { 01361 /* Update error code : Write Transfer error */ 01362 hmdma->ErrorCode |= HAL_MDMA_ERROR_WRITE_XFER; 01363 } 01364 01365 if((errorFlag & MDMA_CESR_TEMD) != 0U) 01366 { 01367 /* Update error code : Error Mask Data */ 01368 hmdma->ErrorCode |= HAL_MDMA_ERROR_MASK_DATA; 01369 } 01370 01371 if((errorFlag & MDMA_CESR_TELD) != 0U) 01372 { 01373 /* Update error code : Error Linked list */ 01374 hmdma->ErrorCode |= HAL_MDMA_ERROR_LINKED_LIST; 01375 } 01376 01377 if((errorFlag & MDMA_CESR_ASE) != 0U) 01378 { 01379 /* Update error code : Address/Size alignment error */ 01380 hmdma->ErrorCode |= HAL_MDMA_ERROR_ALIGNMENT; 01381 } 01382 01383 if((errorFlag & MDMA_CESR_BSE) != 0U) 01384 { 01385 /* Update error code : Block Size error */ 01386 hmdma->ErrorCode |= HAL_MDMA_ERROR_BLOCK_SIZE; 01387 } 01388 01389 (void) HAL_MDMA_Abort(hmdma); /* if error then abort the current transfer */ 01390 01391 /* 01392 Note that the Abort function will 01393 - Clear all transfer flags 01394 - Unlock 01395 - Set the State 01396 */ 01397 01398 return HAL_ERROR; 01399 01400 } 01401 01402 /* Check for the Timeout */ 01403 if(Timeout != HAL_MAX_DELAY) 01404 { 01405 if(((HAL_GetTick() - tickstart ) > Timeout) || (Timeout == 0U)) 01406 { 01407 /* Update error code */ 01408 hmdma->ErrorCode |= HAL_MDMA_ERROR_TIMEOUT; 01409 01410 (void) HAL_MDMA_Abort(hmdma); /* if timeout then abort the current transfer */ 01411 01412 /* 01413 Note that the Abort function will 01414 - Clear all transfer flags 01415 - Unlock 01416 - Set the State 01417 */ 01418 01419 return HAL_ERROR; 01420 } 01421 } 01422 } 01423 01424 /* Clear the transfer level flag */ 01425 if(CompleteLevel == HAL_MDMA_BUFFER_TRANSFER) 01426 { 01427 __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_BFTC); 01428 01429 } 01430 else if(CompleteLevel == HAL_MDMA_BLOCK_TRANSFER) 01431 { 01432 __HAL_MDMA_CLEAR_FLAG(hmdma, (MDMA_FLAG_BFTC | MDMA_FLAG_BT)); 01433 01434 } 01435 else if(CompleteLevel == HAL_MDMA_REPEAT_BLOCK_TRANSFER) 01436 { 01437 __HAL_MDMA_CLEAR_FLAG(hmdma, (MDMA_FLAG_BFTC | MDMA_FLAG_BT | MDMA_FLAG_BRT)); 01438 } 01439 else if(CompleteLevel == HAL_MDMA_FULL_TRANSFER) 01440 { 01441 __HAL_MDMA_CLEAR_FLAG(hmdma, (MDMA_FLAG_BRT | MDMA_FLAG_BT | MDMA_FLAG_BFTC | MDMA_FLAG_CTC)); 01442 01443 /* Process unlocked */ 01444 __HAL_UNLOCK(hmdma); 01445 01446 hmdma->State = HAL_MDMA_STATE_READY; 01447 } 01448 else 01449 { 01450 return HAL_ERROR; 01451 } 01452 01453 return HAL_OK; 01454 } 01455 01456 /** 01457 * @brief Generate an MDMA SW request trigger to activate the request on the given Channel. 01458 * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains 01459 * the configuration information for the specified MDMA Stream. 01460 * @retval HAL status 01461 */ 01462 HAL_StatusTypeDef HAL_MDMA_GenerateSWRequest(MDMA_HandleTypeDef *hmdma) 01463 { 01464 uint32_t request_mode; 01465 01466 /* Check the MDMA peripheral handle */ 01467 if(hmdma == NULL) 01468 { 01469 return HAL_ERROR; 01470 } 01471 01472 /* Get the softawre request mode */ 01473 request_mode = hmdma->Instance->CTCR & MDMA_CTCR_SWRM; 01474 01475 if((hmdma->Instance->CCR & MDMA_CCR_EN) == 0U) 01476 { 01477 /* if no Transfer on going (MDMA enable bit not set) return error */ 01478 hmdma->ErrorCode = HAL_MDMA_ERROR_NO_XFER; 01479 01480 return HAL_ERROR; 01481 } 01482 else if(((hmdma->Instance->CISR & MDMA_CISR_CRQA) != 0U) || (request_mode == 0U)) 01483 { 01484 /* if an MDMA ongoing request has not yet end or if request mode is not SW request return error */ 01485 hmdma->ErrorCode = HAL_MDMA_ERROR_BUSY; 01486 01487 return HAL_ERROR; 01488 } 01489 else 01490 { 01491 /* Set the SW request bit to activate the request on the Channel */ 01492 hmdma->Instance->CCR |= MDMA_CCR_SWRQ; 01493 01494 return HAL_OK; 01495 } 01496 } 01497 01498 /** 01499 * @brief Handles MDMA interrupt request. 01500 * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains 01501 * the configuration information for the specified MDMA Channel. 01502 * @retval None 01503 */ 01504 void HAL_MDMA_IRQHandler(MDMA_HandleTypeDef *hmdma) 01505 { 01506 __IO uint32_t count = 0; 01507 uint32_t timeout = SystemCoreClock / 9600U; 01508 01509 uint32_t generalIntFlag, errorFlag; 01510 01511 /* General Interrupt Flag management ****************************************/ 01512 generalIntFlag = 1UL << ((((uint32_t)hmdma->Instance - (uint32_t)(MDMA_Channel0))/HAL_MDMA_CHANNEL_SIZE) & 0x1FU); 01513 if((MDMA->GISR0 & generalIntFlag) == 0U) 01514 { 01515 return; /* the General interrupt flag for the current channel is down , nothing to do */ 01516 } 01517 01518 /* Transfer Error Interrupt management ***************************************/ 01519 if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_TE) != 0U)) 01520 { 01521 if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_TE) != 0U) 01522 { 01523 /* Disable the transfer error interrupt */ 01524 __HAL_MDMA_DISABLE_IT(hmdma, MDMA_IT_TE); 01525 01526 /* Get the transfer error source flag */ 01527 errorFlag = hmdma->Instance->CESR; 01528 01529 if((errorFlag & MDMA_CESR_TED) == 0U) 01530 { 01531 /* Update error code : Read Transfer error */ 01532 hmdma->ErrorCode |= HAL_MDMA_ERROR_READ_XFER; 01533 } 01534 else 01535 { 01536 /* Update error code : Write Transfer error */ 01537 hmdma->ErrorCode |= HAL_MDMA_ERROR_WRITE_XFER; 01538 } 01539 01540 if((errorFlag & MDMA_CESR_TEMD) != 0U) 01541 { 01542 /* Update error code : Error Mask Data */ 01543 hmdma->ErrorCode |= HAL_MDMA_ERROR_MASK_DATA; 01544 } 01545 01546 if((errorFlag & MDMA_CESR_TELD) != 0U) 01547 { 01548 /* Update error code : Error Linked list */ 01549 hmdma->ErrorCode |= HAL_MDMA_ERROR_LINKED_LIST; 01550 } 01551 01552 if((errorFlag & MDMA_CESR_ASE) != 0U) 01553 { 01554 /* Update error code : Address/Size alignment error */ 01555 hmdma->ErrorCode |= HAL_MDMA_ERROR_ALIGNMENT; 01556 } 01557 01558 if((errorFlag & MDMA_CESR_BSE) != 0U) 01559 { 01560 /* Update error code : Block Size error error */ 01561 hmdma->ErrorCode |= HAL_MDMA_ERROR_BLOCK_SIZE; 01562 } 01563 01564 /* Clear the transfer error flags */ 01565 __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_TE); 01566 } 01567 } 01568 01569 /* Buffer Transfer Complete Interrupt management ******************************/ 01570 if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_BFTC) != 0U)) 01571 { 01572 if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_BFTC) != 0U) 01573 { 01574 /* Clear the buffer transfer complete flag */ 01575 __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_BFTC); 01576 01577 if(hmdma->XferBufferCpltCallback != NULL) 01578 { 01579 /* Buffer transfer callback */ 01580 hmdma->XferBufferCpltCallback(hmdma); 01581 } 01582 } 01583 } 01584 01585 /* Block Transfer Complete Interrupt management ******************************/ 01586 if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_BT) != 0U)) 01587 { 01588 if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_BT) != 0U) 01589 { 01590 /* Clear the block transfer complete flag */ 01591 __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_BT); 01592 01593 if(hmdma->XferBlockCpltCallback != NULL) 01594 { 01595 /* Block transfer callback */ 01596 hmdma->XferBlockCpltCallback(hmdma); 01597 } 01598 } 01599 } 01600 01601 /* Repeated Block Transfer Complete Interrupt management ******************************/ 01602 if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_BRT) != 0U)) 01603 { 01604 if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_BRT) != 0U) 01605 { 01606 /* Clear the repeat block transfer complete flag */ 01607 __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_BRT); 01608 01609 if(hmdma->XferRepeatBlockCpltCallback != NULL) 01610 { 01611 /* Repeated Block transfer callback */ 01612 hmdma->XferRepeatBlockCpltCallback(hmdma); 01613 } 01614 } 01615 } 01616 01617 /* Channel Transfer Complete Interrupt management ***********************************/ 01618 if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_CTC) != 0U)) 01619 { 01620 if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_CTC) != 0U) 01621 { 01622 /* Disable all the transfer interrupts */ 01623 __HAL_MDMA_DISABLE_IT(hmdma, (MDMA_IT_TE | MDMA_IT_CTC | MDMA_IT_BT | MDMA_IT_BRT | MDMA_IT_BFTC)); 01624 01625 if(HAL_MDMA_STATE_ABORT == hmdma->State) 01626 { 01627 /* Process Unlocked */ 01628 __HAL_UNLOCK(hmdma); 01629 01630 /* Change the DMA state */ 01631 hmdma->State = HAL_MDMA_STATE_READY; 01632 01633 if(hmdma->XferAbortCallback != NULL) 01634 { 01635 hmdma->XferAbortCallback(hmdma); 01636 } 01637 return; 01638 } 01639 01640 /* Clear the Channel Transfer Complete flag */ 01641 __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_CTC); 01642 01643 /* Process Unlocked */ 01644 __HAL_UNLOCK(hmdma); 01645 01646 /* Change MDMA peripheral state */ 01647 hmdma->State = HAL_MDMA_STATE_READY; 01648 01649 if(hmdma->XferCpltCallback != NULL) 01650 { 01651 /* Channel Transfer Complete callback */ 01652 hmdma->XferCpltCallback(hmdma); 01653 } 01654 } 01655 } 01656 01657 /* manage error case */ 01658 if(hmdma->ErrorCode != HAL_MDMA_ERROR_NONE) 01659 { 01660 hmdma->State = HAL_MDMA_STATE_ABORT; 01661 01662 /* Disable the channel */ 01663 __HAL_MDMA_DISABLE(hmdma); 01664 01665 do 01666 { 01667 if (++count > timeout) 01668 { 01669 break; 01670 } 01671 } 01672 while((hmdma->Instance->CCR & MDMA_CCR_EN) != 0U); 01673 01674 /* Process Unlocked */ 01675 __HAL_UNLOCK(hmdma); 01676 01677 if((hmdma->Instance->CCR & MDMA_CCR_EN) != 0U) 01678 { 01679 /* Change the MDMA state to error if MDMA disable fails */ 01680 hmdma->State = HAL_MDMA_STATE_ERROR; 01681 } 01682 else 01683 { 01684 /* Change the MDMA state to Ready if MDMA disable success */ 01685 hmdma->State = HAL_MDMA_STATE_READY; 01686 } 01687 01688 01689 if (hmdma->XferErrorCallback != NULL) 01690 { 01691 /* Transfer error callback */ 01692 hmdma->XferErrorCallback(hmdma); 01693 } 01694 } 01695 } 01696 01697 /** 01698 * @} 01699 */ 01700 01701 /** @addtogroup MDMA_Exported_Functions_Group4 01702 * 01703 @verbatim 01704 =============================================================================== 01705 ##### State and Errors functions ##### 01706 =============================================================================== 01707 [..] 01708 This subsection provides functions allowing to 01709 (+) Check the MDMA state 01710 (+) Get error code 01711 01712 @endverbatim 01713 * @{ 01714 */ 01715 01716 /** 01717 * @brief Returns the MDMA state. 01718 * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains 01719 * the configuration information for the specified MDMA Channel. 01720 * @retval HAL state 01721 */ 01722 HAL_MDMA_StateTypeDef HAL_MDMA_GetState(MDMA_HandleTypeDef *hmdma) 01723 { 01724 return hmdma->State; 01725 } 01726 01727 /** 01728 * @brief Return the MDMA error code 01729 * @param hmdma : pointer to a MDMA_HandleTypeDef structure that contains 01730 * the configuration information for the specified MDMA Channel. 01731 * @retval MDMA Error Code 01732 */ 01733 uint32_t HAL_MDMA_GetError(MDMA_HandleTypeDef *hmdma) 01734 { 01735 return hmdma->ErrorCode; 01736 } 01737 01738 /** 01739 * @} 01740 */ 01741 01742 /** 01743 * @} 01744 */ 01745 01746 /** @addtogroup MDMA_Private_Functions 01747 * @{ 01748 */ 01749 01750 /** 01751 * @brief Sets the MDMA Transfer parameter. 01752 * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains 01753 * the configuration information for the specified MDMA Channel. 01754 * @param SrcAddress: The source memory Buffer address 01755 * @param DstAddress: The destination memory Buffer address 01756 * @param BlockDataLength : The length of a block transfer in bytes 01757 * @param BlockCount: The number of blocks to be transferred 01758 * @retval HAL status 01759 */ 01760 static void MDMA_SetConfig(MDMA_HandleTypeDef *hmdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t BlockDataLength, uint32_t BlockCount) 01761 { 01762 uint32_t addressMask; 01763 01764 /* Configure the MDMA Channel data length */ 01765 MODIFY_REG(hmdma->Instance->CBNDTR ,MDMA_CBNDTR_BNDT, (BlockDataLength & MDMA_CBNDTR_BNDT)); 01766 01767 /* Configure the MDMA block repeat count */ 01768 MODIFY_REG(hmdma->Instance->CBNDTR , MDMA_CBNDTR_BRC , ((BlockCount - 1U) << MDMA_CBNDTR_BRC_Pos) & MDMA_CBNDTR_BRC); 01769 01770 /* Clear all interrupt flags */ 01771 __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_TE | MDMA_FLAG_CTC | MDMA_CISR_BRTIF | MDMA_CISR_BTIF | MDMA_CISR_TCIF); 01772 01773 /* Configure MDMA Channel destination address */ 01774 hmdma->Instance->CDAR = DstAddress; 01775 01776 /* Configure MDMA Channel Source address */ 01777 hmdma->Instance->CSAR = SrcAddress; 01778 01779 addressMask = SrcAddress & 0xFF000000U; 01780 if((addressMask == 0x20000000U) || (addressMask == 0x00000000U)) 01781 { 01782 /*The AHBSbus is used as source (read operation) on channel x */ 01783 hmdma->Instance->CTBR |= MDMA_CTBR_SBUS; 01784 } 01785 else 01786 { 01787 /*The AXI bus is used as source (read operation) on channel x */ 01788 hmdma->Instance->CTBR &= (~MDMA_CTBR_SBUS); 01789 } 01790 01791 addressMask = DstAddress & 0xFF000000U; 01792 if((addressMask == 0x20000000U) || (addressMask == 0x00000000U)) 01793 { 01794 /*The AHB bus is used as destination (write operation) on channel x */ 01795 hmdma->Instance->CTBR |= MDMA_CTBR_DBUS; 01796 } 01797 else 01798 { 01799 /*The AXI bus is used as destination (write operation) on channel x */ 01800 hmdma->Instance->CTBR &= (~MDMA_CTBR_DBUS); 01801 } 01802 01803 /* Set the linked list register to the first node of the list */ 01804 hmdma->Instance->CLAR = (uint32_t)hmdma->FirstLinkedListNodeAddress; 01805 } 01806 01807 /** 01808 * @brief Initializes the MDMA handle according to the specified 01809 * parameters in the MDMA_InitTypeDef 01810 * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains 01811 * the configuration information for the specified MDMA Channel. 01812 * @retval None 01813 */ 01814 static void MDMA_Init(MDMA_HandleTypeDef *hmdma) 01815 { 01816 uint32_t blockoffset; 01817 01818 /* Prepare the MDMA Channel configuration */ 01819 hmdma->Instance->CCR = hmdma->Init.Priority | hmdma->Init.Endianness; 01820 01821 /* Write new CTCR Register value */ 01822 hmdma->Instance->CTCR = hmdma->Init.SourceInc | hmdma->Init.DestinationInc | \ 01823 hmdma->Init.SourceDataSize | hmdma->Init.DestDataSize | \ 01824 hmdma->Init.DataAlignment | hmdma->Init.SourceBurst | \ 01825 hmdma->Init.DestBurst | \ 01826 ((hmdma->Init.BufferTransferLength - 1U) << MDMA_CTCR_TLEN_Pos) | \ 01827 hmdma->Init.TransferTriggerMode; 01828 01829 /* If SW request set the CTCR register to SW Request Mode */ 01830 if(hmdma->Init.Request == MDMA_REQUEST_SW) 01831 { 01832 /* 01833 -If the request is done by SW : BWM could be set to 1 or 0. 01834 -If the request is done by a peripheral : 01835 If mask address not set (0) => BWM must be set to 0 01836 If mask address set (different than 0) => BWM could be set to 1 or 0 01837 */ 01838 hmdma->Instance->CTCR |= (MDMA_CTCR_SWRM | MDMA_CTCR_BWM); 01839 } 01840 01841 /* Reset CBNDTR Register */ 01842 hmdma->Instance->CBNDTR = 0; 01843 01844 /* if block source address offset is negative set the Block Repeat Source address Update Mode to decrement */ 01845 if(hmdma->Init.SourceBlockAddressOffset < 0) 01846 { 01847 hmdma->Instance->CBNDTR |= MDMA_CBNDTR_BRSUM; 01848 /* Write new CBRUR Register value : source repeat block offset */ 01849 blockoffset = (uint32_t)(- hmdma->Init.SourceBlockAddressOffset); 01850 hmdma->Instance->CBRUR = (blockoffset & 0x0000FFFFU); 01851 } 01852 else 01853 { 01854 /* Write new CBRUR Register value : source repeat block offset */ 01855 hmdma->Instance->CBRUR = (((uint32_t)hmdma->Init.SourceBlockAddressOffset) & 0x0000FFFFU); 01856 } 01857 01858 /* If block destination address offset is negative set the Block Repeat destination address Update Mode to decrement */ 01859 if(hmdma->Init.DestBlockAddressOffset < 0) 01860 { 01861 hmdma->Instance->CBNDTR |= MDMA_CBNDTR_BRDUM; 01862 /* Write new CBRUR Register value : destination repeat block offset */ 01863 blockoffset = (uint32_t)(- hmdma->Init.DestBlockAddressOffset); 01864 hmdma->Instance->CBRUR |= ((blockoffset & 0x0000FFFFU) << MDMA_CBRUR_DUV_Pos); 01865 } 01866 else 01867 { 01868 /*write new CBRUR Register value : destination repeat block offset */ 01869 hmdma->Instance->CBRUR |= ((((uint32_t)hmdma->Init.DestBlockAddressOffset) & 0x0000FFFFU) << MDMA_CBRUR_DUV_Pos); 01870 } 01871 01872 /* if HW request set the HW request and the requet CleraMask and ClearData MaskData, */ 01873 if(hmdma->Init.Request != MDMA_REQUEST_SW) 01874 { 01875 /* Set the HW request in CTRB register */ 01876 hmdma->Instance->CTBR = hmdma->Init.Request & MDMA_CTBR_TSEL; 01877 } 01878 else /* SW request : reset the CTBR register */ 01879 { 01880 hmdma->Instance->CTBR = 0; 01881 } 01882 01883 /* Write Link Address Register */ 01884 hmdma->Instance->CLAR = 0; 01885 } 01886 01887 /** 01888 * @} 01889 */ 01890 01891 #endif /* HAL_MDMA_MODULE_ENABLED */ 01892 /** 01893 * @} 01894 */ 01895 01896 /** 01897 * @} 01898 */ 01899