STM32F479xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_dma.c 00004 * @author MCD Application Team 00005 * @brief DMA HAL module driver. 00006 * 00007 * This file provides firmware functions to manage the following 00008 * functionalities of the Direct Memory Access (DMA) peripheral: 00009 * + Initialization and de-initialization functions 00010 * + IO operation functions 00011 * + Peripheral State and errors functions 00012 @verbatim 00013 ============================================================================== 00014 ##### How to use this driver ##### 00015 ============================================================================== 00016 [..] 00017 (#) Enable and configure the peripheral to be connected to the DMA Stream 00018 (except for internal SRAM/FLASH memories: no initialization is 00019 necessary) please refer to Reference manual for connection between peripherals 00020 and DMA requests. 00021 00022 (#) For a given Stream, program the required configuration through the following parameters: 00023 Transfer Direction, Source and Destination data formats, 00024 Circular, Normal or peripheral flow control mode, Stream Priority level, 00025 Source and Destination Increment mode, FIFO mode and its Threshold (if needed), 00026 Burst mode for Source and/or Destination (if needed) using HAL_DMA_Init() function. 00027 00028 -@- Prior to HAL_DMA_Init() the clock must be enabled for DMA through the following macros: 00029 __HAL_RCC_DMA1_CLK_ENABLE() or __HAL_RCC_DMA2_CLK_ENABLE(). 00030 00031 *** Polling mode IO operation *** 00032 ================================= 00033 [..] 00034 (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source 00035 address and destination address and the Length of data to be transferred. 00036 (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this 00037 case a fixed Timeout can be configured by User depending from his application. 00038 (+) Use HAL_DMA_Abort() function to abort the current transfer. 00039 00040 *** Interrupt mode IO operation *** 00041 =================================== 00042 [..] 00043 (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority() 00044 (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ() 00045 (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of 00046 Source address and destination address and the Length of data to be transferred. In this 00047 case the DMA interrupt is configured 00048 (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine 00049 (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can 00050 add his own function by customization of function pointer XferCpltCallback and 00051 XferErrorCallback (i.e a member of DMA handle structure). 00052 [..] 00053 (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error 00054 detection. 00055 00056 (#) Use HAL_DMA_Abort_IT() function to abort the current transfer 00057 00058 -@- In Memory-to-Memory transfer mode, Circular mode is not allowed. 00059 00060 -@- The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is 00061 possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set 00062 Half-Word data size for the peripheral to access its data register and set Word data size 00063 for the Memory to gain in access time. Each two half words will be packed and written in 00064 a single access to a Word in the Memory). 00065 00066 -@- When FIFO is disabled, it is not allowed to configure different Data Sizes for Source 00067 and Destination. In this case the Peripheral Data Size will be applied to both Source 00068 and Destination. 00069 00070 *** DMA HAL driver macros list *** 00071 ============================================= 00072 [..] 00073 Below the list of most used macros in DMA HAL driver. 00074 00075 (+) __HAL_DMA_ENABLE: Enable the specified DMA Stream. 00076 (+) __HAL_DMA_DISABLE: Disable the specified DMA Stream. 00077 (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Stream interrupt has occurred or not. 00078 00079 [..] 00080 (@) You can refer to the DMA HAL driver header file for more useful macros 00081 00082 @endverbatim 00083 ****************************************************************************** 00084 * @attention 00085 * 00086 * <h2><center>© Copyright (c) 2017 STMicroelectronics. 00087 * All rights reserved.</center></h2> 00088 * 00089 * This software component is licensed by ST under BSD 3-Clause license, 00090 * the "License"; You may not use this file except in compliance with the 00091 * License. You may obtain a copy of the License at: 00092 * opensource.org/licenses/BSD-3-Clause 00093 * 00094 ****************************************************************************** 00095 */ 00096 00097 /* Includes ------------------------------------------------------------------*/ 00098 #include "stm32f4xx_hal.h" 00099 00100 /** @addtogroup STM32F4xx_HAL_Driver 00101 * @{ 00102 */ 00103 00104 /** @defgroup DMA DMA 00105 * @brief DMA HAL module driver 00106 * @{ 00107 */ 00108 00109 #ifdef HAL_DMA_MODULE_ENABLED 00110 00111 /* Private types -------------------------------------------------------------*/ 00112 typedef struct 00113 { 00114 __IO uint32_t ISR; /*!< DMA interrupt status register */ 00115 __IO uint32_t Reserved0; 00116 __IO uint32_t IFCR; /*!< DMA interrupt flag clear register */ 00117 } DMA_Base_Registers; 00118 00119 /* Private variables ---------------------------------------------------------*/ 00120 /* Private constants ---------------------------------------------------------*/ 00121 /** @addtogroup DMA_Private_Constants 00122 * @{ 00123 */ 00124 #define HAL_TIMEOUT_DMA_ABORT 5U /* 5 ms */ 00125 /** 00126 * @} 00127 */ 00128 /* Private macros ------------------------------------------------------------*/ 00129 /* Private functions ---------------------------------------------------------*/ 00130 /** @addtogroup DMA_Private_Functions 00131 * @{ 00132 */ 00133 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); 00134 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma); 00135 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma); 00136 00137 /** 00138 * @} 00139 */ 00140 00141 /* Exported functions ---------------------------------------------------------*/ 00142 /** @addtogroup DMA_Exported_Functions 00143 * @{ 00144 */ 00145 00146 /** @addtogroup DMA_Exported_Functions_Group1 00147 * 00148 @verbatim 00149 =============================================================================== 00150 ##### Initialization and de-initialization functions ##### 00151 =============================================================================== 00152 [..] 00153 This section provides functions allowing to initialize the DMA Stream source 00154 and destination addresses, incrementation and data sizes, transfer direction, 00155 circular/normal mode selection, memory-to-memory mode selection and Stream priority value. 00156 [..] 00157 The HAL_DMA_Init() function follows the DMA configuration procedures as described in 00158 reference manual. 00159 00160 @endverbatim 00161 * @{ 00162 */ 00163 00164 /** 00165 * @brief Initialize the DMA according to the specified 00166 * parameters in the DMA_InitTypeDef and create the associated handle. 00167 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 00168 * the configuration information for the specified DMA Stream. 00169 * @retval HAL status 00170 */ 00171 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma) 00172 { 00173 uint32_t tmp = 0U; 00174 uint32_t tickstart = HAL_GetTick(); 00175 DMA_Base_Registers *regs; 00176 00177 /* Check the DMA peripheral state */ 00178 if(hdma == NULL) 00179 { 00180 return HAL_ERROR; 00181 } 00182 00183 /* Check the parameters */ 00184 assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance)); 00185 assert_param(IS_DMA_CHANNEL(hdma->Init.Channel)); 00186 assert_param(IS_DMA_DIRECTION(hdma->Init.Direction)); 00187 assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc)); 00188 assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc)); 00189 assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment)); 00190 assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment)); 00191 assert_param(IS_DMA_MODE(hdma->Init.Mode)); 00192 assert_param(IS_DMA_PRIORITY(hdma->Init.Priority)); 00193 assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode)); 00194 /* Check the memory burst, peripheral burst and FIFO threshold parameters only 00195 when FIFO mode is enabled */ 00196 if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE) 00197 { 00198 assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold)); 00199 assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst)); 00200 assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst)); 00201 } 00202 00203 /* Change DMA peripheral state */ 00204 hdma->State = HAL_DMA_STATE_BUSY; 00205 00206 /* Allocate lock resource */ 00207 __HAL_UNLOCK(hdma); 00208 00209 /* Disable the peripheral */ 00210 __HAL_DMA_DISABLE(hdma); 00211 00212 /* Check if the DMA Stream is effectively disabled */ 00213 while((hdma->Instance->CR & DMA_SxCR_EN) != RESET) 00214 { 00215 /* Check for the Timeout */ 00216 if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT) 00217 { 00218 /* Update error code */ 00219 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT; 00220 00221 /* Change the DMA state */ 00222 hdma->State = HAL_DMA_STATE_TIMEOUT; 00223 00224 return HAL_TIMEOUT; 00225 } 00226 } 00227 00228 /* Get the CR register value */ 00229 tmp = hdma->Instance->CR; 00230 00231 /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */ 00232 tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \ 00233 DMA_SxCR_PL | DMA_SxCR_MSIZE | DMA_SxCR_PSIZE | \ 00234 DMA_SxCR_MINC | DMA_SxCR_PINC | DMA_SxCR_CIRC | \ 00235 DMA_SxCR_DIR | DMA_SxCR_CT | DMA_SxCR_DBM)); 00236 00237 /* Prepare the DMA Stream configuration */ 00238 tmp |= hdma->Init.Channel | hdma->Init.Direction | 00239 hdma->Init.PeriphInc | hdma->Init.MemInc | 00240 hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment | 00241 hdma->Init.Mode | hdma->Init.Priority; 00242 00243 /* the Memory burst and peripheral burst are not used when the FIFO is disabled */ 00244 if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE) 00245 { 00246 /* Get memory burst and peripheral burst */ 00247 tmp |= hdma->Init.MemBurst | hdma->Init.PeriphBurst; 00248 } 00249 00250 /* Write to DMA Stream CR register */ 00251 hdma->Instance->CR = tmp; 00252 00253 /* Get the FCR register value */ 00254 tmp = hdma->Instance->FCR; 00255 00256 /* Clear Direct mode and FIFO threshold bits */ 00257 tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); 00258 00259 /* Prepare the DMA Stream FIFO configuration */ 00260 tmp |= hdma->Init.FIFOMode; 00261 00262 /* The FIFO threshold is not used when the FIFO mode is disabled */ 00263 if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE) 00264 { 00265 /* Get the FIFO threshold */ 00266 tmp |= hdma->Init.FIFOThreshold; 00267 00268 /* Check compatibility between FIFO threshold level and size of the memory burst */ 00269 /* for INCR4, INCR8, INCR16 bursts */ 00270 if (hdma->Init.MemBurst != DMA_MBURST_SINGLE) 00271 { 00272 if (DMA_CheckFifoParam(hdma) != HAL_OK) 00273 { 00274 /* Update error code */ 00275 hdma->ErrorCode = HAL_DMA_ERROR_PARAM; 00276 00277 /* Change the DMA state */ 00278 hdma->State = HAL_DMA_STATE_READY; 00279 00280 return HAL_ERROR; 00281 } 00282 } 00283 } 00284 00285 /* Write to DMA Stream FCR */ 00286 hdma->Instance->FCR = tmp; 00287 00288 /* Initialize StreamBaseAddress and StreamIndex parameters to be used to calculate 00289 DMA steam Base Address needed by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */ 00290 regs = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma); 00291 00292 /* Clear all interrupt flags */ 00293 regs->IFCR = 0x3FU << hdma->StreamIndex; 00294 00295 /* Initialize the error code */ 00296 hdma->ErrorCode = HAL_DMA_ERROR_NONE; 00297 00298 /* Initialize the DMA state */ 00299 hdma->State = HAL_DMA_STATE_READY; 00300 00301 return HAL_OK; 00302 } 00303 00304 /** 00305 * @brief DeInitializes the DMA peripheral 00306 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 00307 * the configuration information for the specified DMA Stream. 00308 * @retval HAL status 00309 */ 00310 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma) 00311 { 00312 DMA_Base_Registers *regs; 00313 00314 /* Check the DMA peripheral state */ 00315 if(hdma == NULL) 00316 { 00317 return HAL_ERROR; 00318 } 00319 00320 /* Check the DMA peripheral state */ 00321 if(hdma->State == HAL_DMA_STATE_BUSY) 00322 { 00323 /* Return error status */ 00324 return HAL_BUSY; 00325 } 00326 00327 /* Check the parameters */ 00328 assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance)); 00329 00330 /* Disable the selected DMA Streamx */ 00331 __HAL_DMA_DISABLE(hdma); 00332 00333 /* Reset DMA Streamx control register */ 00334 hdma->Instance->CR = 0U; 00335 00336 /* Reset DMA Streamx number of data to transfer register */ 00337 hdma->Instance->NDTR = 0U; 00338 00339 /* Reset DMA Streamx peripheral address register */ 00340 hdma->Instance->PAR = 0U; 00341 00342 /* Reset DMA Streamx memory 0 address register */ 00343 hdma->Instance->M0AR = 0U; 00344 00345 /* Reset DMA Streamx memory 1 address register */ 00346 hdma->Instance->M1AR = 0U; 00347 00348 /* Reset DMA Streamx FIFO control register */ 00349 hdma->Instance->FCR = 0x00000021U; 00350 00351 /* Get DMA steam Base Address */ 00352 regs = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma); 00353 00354 /* Clean all callbacks */ 00355 hdma->XferCpltCallback = NULL; 00356 hdma->XferHalfCpltCallback = NULL; 00357 hdma->XferM1CpltCallback = NULL; 00358 hdma->XferM1HalfCpltCallback = NULL; 00359 hdma->XferErrorCallback = NULL; 00360 hdma->XferAbortCallback = NULL; 00361 00362 /* Clear all interrupt flags at correct offset within the register */ 00363 regs->IFCR = 0x3FU << hdma->StreamIndex; 00364 00365 /* Reset the error code */ 00366 hdma->ErrorCode = HAL_DMA_ERROR_NONE; 00367 00368 /* Reset the DMA state */ 00369 hdma->State = HAL_DMA_STATE_RESET; 00370 00371 /* Release Lock */ 00372 __HAL_UNLOCK(hdma); 00373 00374 return HAL_OK; 00375 } 00376 00377 /** 00378 * @} 00379 */ 00380 00381 /** @addtogroup DMA_Exported_Functions_Group2 00382 * 00383 @verbatim 00384 =============================================================================== 00385 ##### IO operation functions ##### 00386 =============================================================================== 00387 [..] This section provides functions allowing to: 00388 (+) Configure the source, destination address and data length and Start DMA transfer 00389 (+) Configure the source, destination address and data length and 00390 Start DMA transfer with interrupt 00391 (+) Abort DMA transfer 00392 (+) Poll for transfer complete 00393 (+) Handle DMA interrupt request 00394 00395 @endverbatim 00396 * @{ 00397 */ 00398 00399 /** 00400 * @brief Starts the DMA Transfer. 00401 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 00402 * the configuration information for the specified DMA Stream. 00403 * @param SrcAddress The source memory Buffer address 00404 * @param DstAddress The destination memory Buffer address 00405 * @param DataLength The length of data to be transferred from source to destination 00406 * @retval HAL status 00407 */ 00408 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) 00409 { 00410 HAL_StatusTypeDef status = HAL_OK; 00411 00412 /* Check the parameters */ 00413 assert_param(IS_DMA_BUFFER_SIZE(DataLength)); 00414 00415 /* Process locked */ 00416 __HAL_LOCK(hdma); 00417 00418 if(HAL_DMA_STATE_READY == hdma->State) 00419 { 00420 /* Change DMA peripheral state */ 00421 hdma->State = HAL_DMA_STATE_BUSY; 00422 00423 /* Initialize the error code */ 00424 hdma->ErrorCode = HAL_DMA_ERROR_NONE; 00425 00426 /* Configure the source, destination address and the data length */ 00427 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); 00428 00429 /* Enable the Peripheral */ 00430 __HAL_DMA_ENABLE(hdma); 00431 } 00432 else 00433 { 00434 /* Process unlocked */ 00435 __HAL_UNLOCK(hdma); 00436 00437 /* Return error status */ 00438 status = HAL_BUSY; 00439 } 00440 return status; 00441 } 00442 00443 /** 00444 * @brief Start the DMA Transfer with interrupt enabled. 00445 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 00446 * the configuration information for the specified DMA Stream. 00447 * @param SrcAddress The source memory Buffer address 00448 * @param DstAddress The destination memory Buffer address 00449 * @param DataLength The length of data to be transferred from source to destination 00450 * @retval HAL status 00451 */ 00452 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) 00453 { 00454 HAL_StatusTypeDef status = HAL_OK; 00455 00456 /* calculate DMA base and stream number */ 00457 DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress; 00458 00459 /* Check the parameters */ 00460 assert_param(IS_DMA_BUFFER_SIZE(DataLength)); 00461 00462 /* Process locked */ 00463 __HAL_LOCK(hdma); 00464 00465 if(HAL_DMA_STATE_READY == hdma->State) 00466 { 00467 /* Change DMA peripheral state */ 00468 hdma->State = HAL_DMA_STATE_BUSY; 00469 00470 /* Initialize the error code */ 00471 hdma->ErrorCode = HAL_DMA_ERROR_NONE; 00472 00473 /* Configure the source, destination address and the data length */ 00474 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); 00475 00476 /* Clear all interrupt flags at correct offset within the register */ 00477 regs->IFCR = 0x3FU << hdma->StreamIndex; 00478 00479 /* Enable Common interrupts*/ 00480 hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME; 00481 00482 if(hdma->XferHalfCpltCallback != NULL) 00483 { 00484 hdma->Instance->CR |= DMA_IT_HT; 00485 } 00486 00487 /* Enable the Peripheral */ 00488 __HAL_DMA_ENABLE(hdma); 00489 } 00490 else 00491 { 00492 /* Process unlocked */ 00493 __HAL_UNLOCK(hdma); 00494 00495 /* Return error status */ 00496 status = HAL_BUSY; 00497 } 00498 00499 return status; 00500 } 00501 00502 /** 00503 * @brief Aborts the DMA Transfer. 00504 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 00505 * the configuration information for the specified DMA Stream. 00506 * 00507 * @note After disabling a DMA Stream, a check for wait until the DMA Stream is 00508 * effectively disabled is added. If a Stream is disabled 00509 * while a data transfer is ongoing, the current data will be transferred 00510 * and the Stream will be effectively disabled only after the transfer of 00511 * this single data is finished. 00512 * @retval HAL status 00513 */ 00514 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma) 00515 { 00516 /* calculate DMA base and stream number */ 00517 DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress; 00518 00519 uint32_t tickstart = HAL_GetTick(); 00520 00521 if(hdma->State != HAL_DMA_STATE_BUSY) 00522 { 00523 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; 00524 00525 /* Process Unlocked */ 00526 __HAL_UNLOCK(hdma); 00527 00528 return HAL_ERROR; 00529 } 00530 else 00531 { 00532 /* Disable all the transfer interrupts */ 00533 hdma->Instance->CR &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME); 00534 hdma->Instance->FCR &= ~(DMA_IT_FE); 00535 00536 if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL)) 00537 { 00538 hdma->Instance->CR &= ~(DMA_IT_HT); 00539 } 00540 00541 /* Disable the stream */ 00542 __HAL_DMA_DISABLE(hdma); 00543 00544 /* Check if the DMA Stream is effectively disabled */ 00545 while((hdma->Instance->CR & DMA_SxCR_EN) != RESET) 00546 { 00547 /* Check for the Timeout */ 00548 if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT) 00549 { 00550 /* Update error code */ 00551 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT; 00552 00553 /* Change the DMA state */ 00554 hdma->State = HAL_DMA_STATE_TIMEOUT; 00555 00556 /* Process Unlocked */ 00557 __HAL_UNLOCK(hdma); 00558 00559 return HAL_TIMEOUT; 00560 } 00561 } 00562 00563 /* Clear all interrupt flags at correct offset within the register */ 00564 regs->IFCR = 0x3FU << hdma->StreamIndex; 00565 00566 /* Change the DMA state*/ 00567 hdma->State = HAL_DMA_STATE_READY; 00568 00569 /* Process Unlocked */ 00570 __HAL_UNLOCK(hdma); 00571 } 00572 return HAL_OK; 00573 } 00574 00575 /** 00576 * @brief Aborts the DMA Transfer in Interrupt mode. 00577 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 00578 * the configuration information for the specified DMA Stream. 00579 * @retval HAL status 00580 */ 00581 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma) 00582 { 00583 if(hdma->State != HAL_DMA_STATE_BUSY) 00584 { 00585 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; 00586 return HAL_ERROR; 00587 } 00588 else 00589 { 00590 /* Set Abort State */ 00591 hdma->State = HAL_DMA_STATE_ABORT; 00592 00593 /* Disable the stream */ 00594 __HAL_DMA_DISABLE(hdma); 00595 } 00596 00597 return HAL_OK; 00598 } 00599 00600 /** 00601 * @brief Polling for transfer complete. 00602 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 00603 * the configuration information for the specified DMA Stream. 00604 * @param CompleteLevel Specifies the DMA level complete. 00605 * @note The polling mode is kept in this version for legacy. it is recommanded to use the IT model instead. 00606 * This model could be used for debug purpose. 00607 * @note The HAL_DMA_PollForTransfer API cannot be used in circular and double buffering mode (automatic circular mode). 00608 * @param Timeout Timeout duration. 00609 * @retval HAL status 00610 */ 00611 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout) 00612 { 00613 HAL_StatusTypeDef status = HAL_OK; 00614 uint32_t mask_cpltlevel; 00615 uint32_t tickstart = HAL_GetTick(); 00616 uint32_t tmpisr; 00617 00618 /* calculate DMA base and stream number */ 00619 DMA_Base_Registers *regs; 00620 00621 if(HAL_DMA_STATE_BUSY != hdma->State) 00622 { 00623 /* No transfer ongoing */ 00624 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; 00625 __HAL_UNLOCK(hdma); 00626 return HAL_ERROR; 00627 } 00628 00629 /* Polling mode not supported in circular mode and double buffering mode */ 00630 if ((hdma->Instance->CR & DMA_SxCR_CIRC) != RESET) 00631 { 00632 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED; 00633 return HAL_ERROR; 00634 } 00635 00636 /* Get the level transfer complete flag */ 00637 if(CompleteLevel == HAL_DMA_FULL_TRANSFER) 00638 { 00639 /* Transfer Complete flag */ 00640 mask_cpltlevel = DMA_FLAG_TCIF0_4 << hdma->StreamIndex; 00641 } 00642 else 00643 { 00644 /* Half Transfer Complete flag */ 00645 mask_cpltlevel = DMA_FLAG_HTIF0_4 << hdma->StreamIndex; 00646 } 00647 00648 regs = (DMA_Base_Registers *)hdma->StreamBaseAddress; 00649 tmpisr = regs->ISR; 00650 00651 while(((tmpisr & mask_cpltlevel) == RESET) && ((hdma->ErrorCode & HAL_DMA_ERROR_TE) == RESET)) 00652 { 00653 /* Check for the Timeout (Not applicable in circular mode)*/ 00654 if(Timeout != HAL_MAX_DELAY) 00655 { 00656 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 00657 { 00658 /* Update error code */ 00659 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT; 00660 00661 /* Change the DMA state */ 00662 hdma->State = HAL_DMA_STATE_READY; 00663 00664 /* Process Unlocked */ 00665 __HAL_UNLOCK(hdma); 00666 00667 return HAL_TIMEOUT; 00668 } 00669 } 00670 00671 /* Get the ISR register value */ 00672 tmpisr = regs->ISR; 00673 00674 if((tmpisr & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET) 00675 { 00676 /* Update error code */ 00677 hdma->ErrorCode |= HAL_DMA_ERROR_TE; 00678 00679 /* Clear the transfer error flag */ 00680 regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex; 00681 } 00682 00683 if((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET) 00684 { 00685 /* Update error code */ 00686 hdma->ErrorCode |= HAL_DMA_ERROR_FE; 00687 00688 /* Clear the FIFO error flag */ 00689 regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex; 00690 } 00691 00692 if((tmpisr & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET) 00693 { 00694 /* Update error code */ 00695 hdma->ErrorCode |= HAL_DMA_ERROR_DME; 00696 00697 /* Clear the Direct Mode error flag */ 00698 regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex; 00699 } 00700 } 00701 00702 if(hdma->ErrorCode != HAL_DMA_ERROR_NONE) 00703 { 00704 if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != RESET) 00705 { 00706 HAL_DMA_Abort(hdma); 00707 00708 /* Clear the half transfer and transfer complete flags */ 00709 regs->IFCR = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << hdma->StreamIndex; 00710 00711 /* Change the DMA state */ 00712 hdma->State= HAL_DMA_STATE_READY; 00713 00714 /* Process Unlocked */ 00715 __HAL_UNLOCK(hdma); 00716 00717 return HAL_ERROR; 00718 } 00719 } 00720 00721 /* Get the level transfer complete flag */ 00722 if(CompleteLevel == HAL_DMA_FULL_TRANSFER) 00723 { 00724 /* Clear the half transfer and transfer complete flags */ 00725 regs->IFCR = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << hdma->StreamIndex; 00726 00727 hdma->State = HAL_DMA_STATE_READY; 00728 00729 /* Process Unlocked */ 00730 __HAL_UNLOCK(hdma); 00731 } 00732 else 00733 { 00734 /* Clear the half transfer and transfer complete flags */ 00735 regs->IFCR = (DMA_FLAG_HTIF0_4) << hdma->StreamIndex; 00736 } 00737 00738 return status; 00739 } 00740 00741 /** 00742 * @brief Handles DMA interrupt request. 00743 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 00744 * the configuration information for the specified DMA Stream. 00745 * @retval None 00746 */ 00747 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma) 00748 { 00749 uint32_t tmpisr; 00750 __IO uint32_t count = 0U; 00751 uint32_t timeout = SystemCoreClock / 9600U; 00752 00753 /* calculate DMA base and stream number */ 00754 DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress; 00755 00756 tmpisr = regs->ISR; 00757 00758 /* Transfer Error Interrupt management ***************************************/ 00759 if ((tmpisr & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET) 00760 { 00761 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET) 00762 { 00763 /* Disable the transfer error interrupt */ 00764 hdma->Instance->CR &= ~(DMA_IT_TE); 00765 00766 /* Clear the transfer error flag */ 00767 regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex; 00768 00769 /* Update error code */ 00770 hdma->ErrorCode |= HAL_DMA_ERROR_TE; 00771 } 00772 } 00773 /* FIFO Error Interrupt management ******************************************/ 00774 if ((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET) 00775 { 00776 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET) 00777 { 00778 /* Clear the FIFO error flag */ 00779 regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex; 00780 00781 /* Update error code */ 00782 hdma->ErrorCode |= HAL_DMA_ERROR_FE; 00783 } 00784 } 00785 /* Direct Mode Error Interrupt management ***********************************/ 00786 if ((tmpisr & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET) 00787 { 00788 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET) 00789 { 00790 /* Clear the direct mode error flag */ 00791 regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex; 00792 00793 /* Update error code */ 00794 hdma->ErrorCode |= HAL_DMA_ERROR_DME; 00795 } 00796 } 00797 /* Half Transfer Complete Interrupt management ******************************/ 00798 if ((tmpisr & (DMA_FLAG_HTIF0_4 << hdma->StreamIndex)) != RESET) 00799 { 00800 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET) 00801 { 00802 /* Clear the half transfer complete flag */ 00803 regs->IFCR = DMA_FLAG_HTIF0_4 << hdma->StreamIndex; 00804 00805 /* Multi_Buffering mode enabled */ 00806 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET) 00807 { 00808 /* Current memory buffer used is Memory 0 */ 00809 if((hdma->Instance->CR & DMA_SxCR_CT) == RESET) 00810 { 00811 if(hdma->XferHalfCpltCallback != NULL) 00812 { 00813 /* Half transfer callback */ 00814 hdma->XferHalfCpltCallback(hdma); 00815 } 00816 } 00817 /* Current memory buffer used is Memory 1 */ 00818 else 00819 { 00820 if(hdma->XferM1HalfCpltCallback != NULL) 00821 { 00822 /* Half transfer callback */ 00823 hdma->XferM1HalfCpltCallback(hdma); 00824 } 00825 } 00826 } 00827 else 00828 { 00829 /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */ 00830 if((hdma->Instance->CR & DMA_SxCR_CIRC) == RESET) 00831 { 00832 /* Disable the half transfer interrupt */ 00833 hdma->Instance->CR &= ~(DMA_IT_HT); 00834 } 00835 00836 if(hdma->XferHalfCpltCallback != NULL) 00837 { 00838 /* Half transfer callback */ 00839 hdma->XferHalfCpltCallback(hdma); 00840 } 00841 } 00842 } 00843 } 00844 /* Transfer Complete Interrupt management ***********************************/ 00845 if ((tmpisr & (DMA_FLAG_TCIF0_4 << hdma->StreamIndex)) != RESET) 00846 { 00847 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET) 00848 { 00849 /* Clear the transfer complete flag */ 00850 regs->IFCR = DMA_FLAG_TCIF0_4 << hdma->StreamIndex; 00851 00852 if(HAL_DMA_STATE_ABORT == hdma->State) 00853 { 00854 /* Disable all the transfer interrupts */ 00855 hdma->Instance->CR &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME); 00856 hdma->Instance->FCR &= ~(DMA_IT_FE); 00857 00858 if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL)) 00859 { 00860 hdma->Instance->CR &= ~(DMA_IT_HT); 00861 } 00862 00863 /* Clear all interrupt flags at correct offset within the register */ 00864 regs->IFCR = 0x3FU << hdma->StreamIndex; 00865 00866 /* Change the DMA state */ 00867 hdma->State = HAL_DMA_STATE_READY; 00868 00869 /* Process Unlocked */ 00870 __HAL_UNLOCK(hdma); 00871 00872 if(hdma->XferAbortCallback != NULL) 00873 { 00874 hdma->XferAbortCallback(hdma); 00875 } 00876 return; 00877 } 00878 00879 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET) 00880 { 00881 /* Current memory buffer used is Memory 0 */ 00882 if((hdma->Instance->CR & DMA_SxCR_CT) == RESET) 00883 { 00884 if(hdma->XferM1CpltCallback != NULL) 00885 { 00886 /* Transfer complete Callback for memory1 */ 00887 hdma->XferM1CpltCallback(hdma); 00888 } 00889 } 00890 /* Current memory buffer used is Memory 1 */ 00891 else 00892 { 00893 if(hdma->XferCpltCallback != NULL) 00894 { 00895 /* Transfer complete Callback for memory0 */ 00896 hdma->XferCpltCallback(hdma); 00897 } 00898 } 00899 } 00900 /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */ 00901 else 00902 { 00903 if((hdma->Instance->CR & DMA_SxCR_CIRC) == RESET) 00904 { 00905 /* Disable the transfer complete interrupt */ 00906 hdma->Instance->CR &= ~(DMA_IT_TC); 00907 00908 /* Change the DMA state */ 00909 hdma->State = HAL_DMA_STATE_READY; 00910 00911 /* Process Unlocked */ 00912 __HAL_UNLOCK(hdma); 00913 } 00914 00915 if(hdma->XferCpltCallback != NULL) 00916 { 00917 /* Transfer complete callback */ 00918 hdma->XferCpltCallback(hdma); 00919 } 00920 } 00921 } 00922 } 00923 00924 /* manage error case */ 00925 if(hdma->ErrorCode != HAL_DMA_ERROR_NONE) 00926 { 00927 if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != RESET) 00928 { 00929 hdma->State = HAL_DMA_STATE_ABORT; 00930 00931 /* Disable the stream */ 00932 __HAL_DMA_DISABLE(hdma); 00933 00934 do 00935 { 00936 if (++count > timeout) 00937 { 00938 break; 00939 } 00940 } 00941 while((hdma->Instance->CR & DMA_SxCR_EN) != RESET); 00942 00943 /* Change the DMA state */ 00944 hdma->State = HAL_DMA_STATE_READY; 00945 00946 /* Process Unlocked */ 00947 __HAL_UNLOCK(hdma); 00948 } 00949 00950 if(hdma->XferErrorCallback != NULL) 00951 { 00952 /* Transfer error callback */ 00953 hdma->XferErrorCallback(hdma); 00954 } 00955 } 00956 } 00957 00958 /** 00959 * @brief Register callbacks 00960 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 00961 * the configuration information for the specified DMA Stream. 00962 * @param CallbackID User Callback identifer 00963 * a DMA_HandleTypeDef structure as parameter. 00964 * @param pCallback pointer to private callbacsk function which has pointer to 00965 * a DMA_HandleTypeDef structure as parameter. 00966 * @retval HAL status 00967 */ 00968 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)(DMA_HandleTypeDef *_hdma)) 00969 { 00970 00971 HAL_StatusTypeDef status = HAL_OK; 00972 00973 /* Process locked */ 00974 __HAL_LOCK(hdma); 00975 00976 if(HAL_DMA_STATE_READY == hdma->State) 00977 { 00978 switch (CallbackID) 00979 { 00980 case HAL_DMA_XFER_CPLT_CB_ID: 00981 hdma->XferCpltCallback = pCallback; 00982 break; 00983 00984 case HAL_DMA_XFER_HALFCPLT_CB_ID: 00985 hdma->XferHalfCpltCallback = pCallback; 00986 break; 00987 00988 case HAL_DMA_XFER_M1CPLT_CB_ID: 00989 hdma->XferM1CpltCallback = pCallback; 00990 break; 00991 00992 case HAL_DMA_XFER_M1HALFCPLT_CB_ID: 00993 hdma->XferM1HalfCpltCallback = pCallback; 00994 break; 00995 00996 case HAL_DMA_XFER_ERROR_CB_ID: 00997 hdma->XferErrorCallback = pCallback; 00998 break; 00999 01000 case HAL_DMA_XFER_ABORT_CB_ID: 01001 hdma->XferAbortCallback = pCallback; 01002 break; 01003 01004 default: 01005 break; 01006 } 01007 } 01008 else 01009 { 01010 /* Return error status */ 01011 status = HAL_ERROR; 01012 } 01013 01014 /* Release Lock */ 01015 __HAL_UNLOCK(hdma); 01016 01017 return status; 01018 } 01019 01020 /** 01021 * @brief UnRegister callbacks 01022 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01023 * the configuration information for the specified DMA Stream. 01024 * @param CallbackID User Callback identifer 01025 * a HAL_DMA_CallbackIDTypeDef ENUM as parameter. 01026 * @retval HAL status 01027 */ 01028 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID) 01029 { 01030 HAL_StatusTypeDef status = HAL_OK; 01031 01032 /* Process locked */ 01033 __HAL_LOCK(hdma); 01034 01035 if(HAL_DMA_STATE_READY == hdma->State) 01036 { 01037 switch (CallbackID) 01038 { 01039 case HAL_DMA_XFER_CPLT_CB_ID: 01040 hdma->XferCpltCallback = NULL; 01041 break; 01042 01043 case HAL_DMA_XFER_HALFCPLT_CB_ID: 01044 hdma->XferHalfCpltCallback = NULL; 01045 break; 01046 01047 case HAL_DMA_XFER_M1CPLT_CB_ID: 01048 hdma->XferM1CpltCallback = NULL; 01049 break; 01050 01051 case HAL_DMA_XFER_M1HALFCPLT_CB_ID: 01052 hdma->XferM1HalfCpltCallback = NULL; 01053 break; 01054 01055 case HAL_DMA_XFER_ERROR_CB_ID: 01056 hdma->XferErrorCallback = NULL; 01057 break; 01058 01059 case HAL_DMA_XFER_ABORT_CB_ID: 01060 hdma->XferAbortCallback = NULL; 01061 break; 01062 01063 case HAL_DMA_XFER_ALL_CB_ID: 01064 hdma->XferCpltCallback = NULL; 01065 hdma->XferHalfCpltCallback = NULL; 01066 hdma->XferM1CpltCallback = NULL; 01067 hdma->XferM1HalfCpltCallback = NULL; 01068 hdma->XferErrorCallback = NULL; 01069 hdma->XferAbortCallback = NULL; 01070 break; 01071 01072 default: 01073 status = HAL_ERROR; 01074 break; 01075 } 01076 } 01077 else 01078 { 01079 status = HAL_ERROR; 01080 } 01081 01082 /* Release Lock */ 01083 __HAL_UNLOCK(hdma); 01084 01085 return status; 01086 } 01087 01088 /** 01089 * @} 01090 */ 01091 01092 /** @addtogroup DMA_Exported_Functions_Group3 01093 * 01094 @verbatim 01095 =============================================================================== 01096 ##### State and Errors functions ##### 01097 =============================================================================== 01098 [..] 01099 This subsection provides functions allowing to 01100 (+) Check the DMA state 01101 (+) Get error code 01102 01103 @endverbatim 01104 * @{ 01105 */ 01106 01107 /** 01108 * @brief Returns the DMA state. 01109 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01110 * the configuration information for the specified DMA Stream. 01111 * @retval HAL state 01112 */ 01113 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma) 01114 { 01115 return hdma->State; 01116 } 01117 01118 /** 01119 * @brief Return the DMA error code 01120 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01121 * the configuration information for the specified DMA Stream. 01122 * @retval DMA Error Code 01123 */ 01124 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma) 01125 { 01126 return hdma->ErrorCode; 01127 } 01128 01129 /** 01130 * @} 01131 */ 01132 01133 /** 01134 * @} 01135 */ 01136 01137 /** @addtogroup DMA_Private_Functions 01138 * @{ 01139 */ 01140 01141 /** 01142 * @brief Sets the DMA Transfer parameter. 01143 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01144 * the configuration information for the specified DMA Stream. 01145 * @param SrcAddress The source memory Buffer address 01146 * @param DstAddress The destination memory Buffer address 01147 * @param DataLength The length of data to be transferred from source to destination 01148 * @retval HAL status 01149 */ 01150 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) 01151 { 01152 /* Clear DBM bit */ 01153 hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM); 01154 01155 /* Configure DMA Stream data length */ 01156 hdma->Instance->NDTR = DataLength; 01157 01158 /* Memory to Peripheral */ 01159 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) 01160 { 01161 /* Configure DMA Stream destination address */ 01162 hdma->Instance->PAR = DstAddress; 01163 01164 /* Configure DMA Stream source address */ 01165 hdma->Instance->M0AR = SrcAddress; 01166 } 01167 /* Peripheral to Memory */ 01168 else 01169 { 01170 /* Configure DMA Stream source address */ 01171 hdma->Instance->PAR = SrcAddress; 01172 01173 /* Configure DMA Stream destination address */ 01174 hdma->Instance->M0AR = DstAddress; 01175 } 01176 } 01177 01178 /** 01179 * @brief Returns the DMA Stream base address depending on stream number 01180 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01181 * the configuration information for the specified DMA Stream. 01182 * @retval Stream base address 01183 */ 01184 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma) 01185 { 01186 uint32_t stream_number = (((uint32_t)hdma->Instance & 0xFFU) - 16U) / 24U; 01187 01188 /* lookup table for necessary bitshift of flags within status registers */ 01189 static const uint8_t flagBitshiftOffset[8U] = {0U, 6U, 16U, 22U, 0U, 6U, 16U, 22U}; 01190 hdma->StreamIndex = flagBitshiftOffset[stream_number]; 01191 01192 if (stream_number > 3U) 01193 { 01194 /* return pointer to HISR and HIFCR */ 01195 hdma->StreamBaseAddress = (((uint32_t)hdma->Instance & (uint32_t)(~0x3FFU)) + 4U); 01196 } 01197 else 01198 { 01199 /* return pointer to LISR and LIFCR */ 01200 hdma->StreamBaseAddress = ((uint32_t)hdma->Instance & (uint32_t)(~0x3FFU)); 01201 } 01202 01203 return hdma->StreamBaseAddress; 01204 } 01205 01206 /** 01207 * @brief Check compatibility between FIFO threshold level and size of the memory burst 01208 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01209 * the configuration information for the specified DMA Stream. 01210 * @retval HAL status 01211 */ 01212 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma) 01213 { 01214 HAL_StatusTypeDef status = HAL_OK; 01215 uint32_t tmp = hdma->Init.FIFOThreshold; 01216 01217 /* Memory Data size equal to Byte */ 01218 if(hdma->Init.MemDataAlignment == DMA_MDATAALIGN_BYTE) 01219 { 01220 switch (tmp) 01221 { 01222 case DMA_FIFO_THRESHOLD_1QUARTERFULL: 01223 case DMA_FIFO_THRESHOLD_3QUARTERSFULL: 01224 if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1) 01225 { 01226 status = HAL_ERROR; 01227 } 01228 break; 01229 case DMA_FIFO_THRESHOLD_HALFFULL: 01230 if (hdma->Init.MemBurst == DMA_MBURST_INC16) 01231 { 01232 status = HAL_ERROR; 01233 } 01234 break; 01235 case DMA_FIFO_THRESHOLD_FULL: 01236 break; 01237 default: 01238 break; 01239 } 01240 } 01241 01242 /* Memory Data size equal to Half-Word */ 01243 else if (hdma->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD) 01244 { 01245 switch (tmp) 01246 { 01247 case DMA_FIFO_THRESHOLD_1QUARTERFULL: 01248 case DMA_FIFO_THRESHOLD_3QUARTERSFULL: 01249 status = HAL_ERROR; 01250 break; 01251 case DMA_FIFO_THRESHOLD_HALFFULL: 01252 if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1) 01253 { 01254 status = HAL_ERROR; 01255 } 01256 break; 01257 case DMA_FIFO_THRESHOLD_FULL: 01258 if (hdma->Init.MemBurst == DMA_MBURST_INC16) 01259 { 01260 status = HAL_ERROR; 01261 } 01262 break; 01263 default: 01264 break; 01265 } 01266 } 01267 01268 /* Memory Data size equal to Word */ 01269 else 01270 { 01271 switch (tmp) 01272 { 01273 case DMA_FIFO_THRESHOLD_1QUARTERFULL: 01274 case DMA_FIFO_THRESHOLD_HALFFULL: 01275 case DMA_FIFO_THRESHOLD_3QUARTERSFULL: 01276 status = HAL_ERROR; 01277 break; 01278 case DMA_FIFO_THRESHOLD_FULL: 01279 if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1) 01280 { 01281 status = HAL_ERROR; 01282 } 01283 break; 01284 default: 01285 break; 01286 } 01287 } 01288 01289 return status; 01290 } 01291 01292 /** 01293 * @} 01294 */ 01295 01296 #endif /* HAL_DMA_MODULE_ENABLED */ 01297 /** 01298 * @} 01299 */ 01300 01301 /** 01302 * @} 01303 */ 01304 01305 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/