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