Hal Drivers for L4
Dependents: BSP OneHopeOnePrayer FINAL_AUDIO_RECORD AudioDemo
Fork of STM32L4xx_HAL_Driver by
stm32l4xx_hal_dma.c
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_dma.c 00004 * @author MCD Application Team 00005 * @version V1.1.0 00006 * @date 16-September-2015 00007 * @brief DMA HAL module driver. 00008 * 00009 * This file provides firmware functions to manage the following 00010 * functionalities of the Direct Memory Access (DMA) peripheral: 00011 * + Initialization and de-initialization functions 00012 * + IO operation functions 00013 * + Peripheral State and errors functions 00014 @verbatim 00015 ============================================================================== 00016 ##### How to use this driver ##### 00017 ============================================================================== 00018 [..] 00019 (#) Enable and configure the peripheral to be connected to the DMA Channel 00020 (except for internal SRAM / FLASH memories: no initialization is 00021 necessary). Please refer to the Reference manual for connection between peripherals 00022 and DMA requests. 00023 00024 (#) For a given Channel, program the required configuration through the following parameters: 00025 Channel request, Transfer Direction, Source and Destination data formats, 00026 Circular or Normal mode, Channel Priority level, Source and Destination Increment mode 00027 using HAL_DMA_Init() function. 00028 00029 (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error 00030 detection. 00031 00032 (#) Use HAL_DMA_Abort() function to abort the current transfer 00033 00034 -@- In Memory-to-Memory transfer mode, Circular mode is not allowed. 00035 *** Polling mode IO operation *** 00036 ================================= 00037 [..] 00038 (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source 00039 address and destination address and the Length of data to be transferred 00040 (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this 00041 case a fixed Timeout can be configured by User depending from his application. 00042 00043 *** Interrupt mode IO operation *** 00044 =================================== 00045 [..] 00046 (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority() 00047 (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ() 00048 (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of 00049 Source address and destination address and the Length of data to be transferred. 00050 In this case the DMA interrupt is configured 00051 (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine 00052 (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can 00053 add his own function by customization of function pointer XferCpltCallback and 00054 XferErrorCallback (i.e. a member of DMA handle structure). 00055 00056 *** DMA HAL driver macros list *** 00057 ============================================= 00058 [..] 00059 Below the list of most used macros in DMA HAL driver. 00060 00061 (+) __HAL_DMA_ENABLE: Enable the specified DMA Channel. 00062 (+) __HAL_DMA_DISABLE: Disable the specified DMA Channel. 00063 (+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags. 00064 (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags. 00065 (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts. 00066 (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts. 00067 (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt has occurred or not. 00068 00069 [..] 00070 (@) You can refer to the DMA HAL driver header file for more useful macros 00071 00072 @endverbatim 00073 ****************************************************************************** 00074 * @attention 00075 * 00076 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> 00077 * 00078 * Redistribution and use in source and binary forms, with or without modification, 00079 * are permitted provided that the following conditions are met: 00080 * 1. Redistributions of source code must retain the above copyright notice, 00081 * this list of conditions and the following disclaimer. 00082 * 2. Redistributions in binary form must reproduce the above copyright notice, 00083 * this list of conditions and the following disclaimer in the documentation 00084 * and/or other materials provided with the distribution. 00085 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00086 * may be used to endorse or promote products derived from this software 00087 * without specific prior written permission. 00088 * 00089 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00090 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00091 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00092 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00093 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00094 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00095 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00096 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00097 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00098 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00099 * 00100 ****************************************************************************** 00101 */ 00102 00103 /* Includes ------------------------------------------------------------------*/ 00104 #include "stm32l4xx_hal.h" 00105 00106 /** @addtogroup STM32L4xx_HAL_Driver 00107 * @{ 00108 */ 00109 00110 /** @defgroup DMA DMA 00111 * @brief DMA HAL module driver 00112 * @{ 00113 */ 00114 00115 #ifdef HAL_DMA_MODULE_ENABLED 00116 00117 /* Private typedef -----------------------------------------------------------*/ 00118 /* Private define ------------------------------------------------------------*/ 00119 /** @defgroup DMA_Private_Constants DMA Private Constants 00120 * @{ 00121 */ 00122 #define HAL_TIMEOUT_DMA_ABORT ((uint32_t)1000) /* 1s */ 00123 /** 00124 * @} 00125 */ 00126 00127 /* Private macro -------------------------------------------------------------*/ 00128 /* Private variables ---------------------------------------------------------*/ 00129 /* Private function prototypes -----------------------------------------------*/ 00130 /** @defgroup DMA_Private_Functions DMA Private Functions 00131 * @{ 00132 */ 00133 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); 00134 /** 00135 * @} 00136 */ 00137 00138 /* Exported functions ---------------------------------------------------------*/ 00139 00140 /** @defgroup DMA_Exported_Functions DMA Exported Functions 00141 * @{ 00142 */ 00143 00144 /** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions 00145 * @brief Initialization and de-initialization functions 00146 * 00147 @verbatim 00148 =============================================================================== 00149 ##### Initialization and de-initialization functions ##### 00150 =============================================================================== 00151 [..] 00152 This section provides functions allowing to initialize the DMA Channel source 00153 and destination addresses, incrementation and data sizes, transfer direction, 00154 circular/normal mode selection, memory-to-memory mode selection and Channel priority value. 00155 [..] 00156 The HAL_DMA_Init() function follows the DMA configuration procedures as described in 00157 reference manual. 00158 00159 @endverbatim 00160 * @{ 00161 */ 00162 00163 /** 00164 * @brief Initialize the DMA according to the specified 00165 * parameters in the DMA_InitTypeDef and initialize the associated handle. 00166 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains 00167 * the configuration information for the specified DMA Channel. 00168 * @retval HAL status 00169 */ 00170 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma) 00171 { 00172 uint32_t tmp = 0; 00173 00174 /* Check the DMA handle allocation */ 00175 if(hdma == NULL) 00176 { 00177 return HAL_ERROR; 00178 } 00179 00180 /* Check the parameters */ 00181 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); 00182 assert_param(IS_DMA_DIRECTION(hdma->Init.Direction)); 00183 assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc)); 00184 assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc)); 00185 assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment)); 00186 assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment)); 00187 assert_param(IS_DMA_MODE(hdma->Init.Mode)); 00188 assert_param(IS_DMA_PRIORITY(hdma->Init.Priority)); 00189 if(hdma->Init.Direction != DMA_MEMORY_TO_MEMORY) 00190 { 00191 assert_param(IS_DMA_ALL_REQUEST(hdma->Init.Request)); 00192 } 00193 00194 if(hdma->State == HAL_DMA_STATE_RESET) 00195 { 00196 /* Allocate lock resource and initialize it */ 00197 hdma->Lock = HAL_UNLOCKED; 00198 } 00199 00200 /* Change DMA peripheral state */ 00201 hdma->State = HAL_DMA_STATE_BUSY; 00202 00203 /* Get the CR register value */ 00204 tmp = hdma->Instance->CCR; 00205 00206 /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR bits */ 00207 tmp &= ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \ 00208 DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \ 00209 DMA_CCR_DIR)); 00210 00211 /* Prepare the DMA Channel configuration */ 00212 tmp |= hdma->Init.Direction | 00213 hdma->Init.PeriphInc | hdma->Init.MemInc | 00214 hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment | 00215 hdma->Init.Mode | hdma->Init.Priority; 00216 00217 /* Write to DMA Channel CR register */ 00218 hdma->Instance->CCR = tmp; 00219 00220 /* Set request selection */ 00221 if(hdma->Init.Direction != DMA_MEMORY_TO_MEMORY) 00222 { 00223 /* Write to DMA channel selection register */ 00224 if (hdma->Instance == DMA1_Channel1) 00225 { 00226 /*Reset request selection for DMA1 Channel1*/ 00227 DMA1_CSELR->CSELR &= ~DMA_CSELR_C1S; 00228 00229 /* Configure request selection for DMA1 Channel1 */ 00230 DMA1_CSELR->CSELR |= hdma->Init.Request; 00231 } 00232 else if (hdma->Instance == DMA1_Channel2) 00233 { 00234 /*Reset request selection for DMA1 Channel2*/ 00235 DMA1_CSELR->CSELR &= ~DMA_CSELR_C2S; 00236 00237 /* Configure request selection for DMA1 Channel2 */ 00238 DMA1_CSELR->CSELR |= (uint32_t)(hdma->Init.Request << 4); 00239 } 00240 else if (hdma->Instance == DMA1_Channel3) 00241 { 00242 /*Reset request selection for DMA1 Channel3*/ 00243 DMA1_CSELR->CSELR &= ~DMA_CSELR_C3S; 00244 00245 /* Configure request selection for DMA1 Channel3 */ 00246 DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 8); 00247 } 00248 else if (hdma->Instance == DMA1_Channel4) 00249 { 00250 /*Reset request selection for DMA1 Channel4*/ 00251 DMA1_CSELR->CSELR &= ~DMA_CSELR_C4S; 00252 00253 /* Configure request selection for DMA1 Channel4 */ 00254 DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 12); 00255 } 00256 else if (hdma->Instance == DMA1_Channel5) 00257 { 00258 /*Reset request selection for DMA1 Channel5*/ 00259 DMA1_CSELR->CSELR &= ~DMA_CSELR_C5S; 00260 00261 /* Configure request selection for DMA1 Channel5 */ 00262 DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 16); 00263 } 00264 else if (hdma->Instance == DMA1_Channel6) 00265 { 00266 /*Reset request selection for DMA1 Channel6*/ 00267 DMA1_CSELR->CSELR &= ~DMA_CSELR_C6S; 00268 00269 /* Configure request selection for DMA1 Channel6 */ 00270 DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 20); 00271 } 00272 else if (hdma->Instance == DMA1_Channel7) 00273 { 00274 /*Reset request selection for DMA1 Channel7*/ 00275 DMA1_CSELR->CSELR &= ~DMA_CSELR_C7S; 00276 00277 /* Configure request selection for DMA1 Channel7 */ 00278 DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 24); 00279 } 00280 else if (hdma->Instance == DMA2_Channel1) 00281 { 00282 /*Reset request selection for DMA2 Channel1*/ 00283 DMA2_CSELR->CSELR &= ~DMA_CSELR_C1S; 00284 00285 /* Configure request selection for DMA2 Channel1 */ 00286 DMA2_CSELR->CSELR |= hdma->Init.Request; 00287 } 00288 else if (hdma->Instance == DMA2_Channel2) 00289 { 00290 /*Reset request selection for DMA2 Channel2*/ 00291 DMA2_CSELR->CSELR &= ~DMA_CSELR_C2S; 00292 00293 /* Configure request selection for DMA2 Channel2 */ 00294 DMA2_CSELR->CSELR |= (uint32_t)(hdma->Init.Request << 4); 00295 } 00296 else if (hdma->Instance == DMA2_Channel3) 00297 { 00298 /*Reset request selection for DMA2 Channel3*/ 00299 DMA2_CSELR->CSELR &= ~DMA_CSELR_C3S; 00300 00301 /* Configure request selection for DMA2 Channel3 */ 00302 DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 8); 00303 } 00304 else if (hdma->Instance == DMA2_Channel4) 00305 { 00306 /*Reset request selection for DMA2 Channel4*/ 00307 DMA2_CSELR->CSELR &= ~DMA_CSELR_C4S; 00308 00309 /* Configure request selection for DMA2 Channel4 */ 00310 DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 12); 00311 } 00312 else if (hdma->Instance == DMA2_Channel5) 00313 { 00314 /*Reset request selection for DMA2 Channel5*/ 00315 DMA2_CSELR->CSELR &= ~DMA_CSELR_C5S; 00316 00317 /* Configure request selection for DMA2 Channel5 */ 00318 DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 16); 00319 } 00320 else if (hdma->Instance == DMA2_Channel6) 00321 { 00322 /*Reset request selection for DMA2 Channel6*/ 00323 DMA2_CSELR->CSELR &= ~DMA_CSELR_C6S; 00324 00325 /* Configure request selection for DMA2 Channel6 */ 00326 DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 20); 00327 } 00328 else if (hdma->Instance == DMA2_Channel7) 00329 { 00330 /*Reset request selection for DMA2 Channel7*/ 00331 DMA2_CSELR->CSELR &= ~DMA_CSELR_C7S; 00332 00333 /* Configure request selection for DMA2 Channel7 */ 00334 DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 24); 00335 } 00336 } 00337 00338 /* Initialize the error code */ 00339 hdma->ErrorCode = HAL_DMA_ERROR_NONE; 00340 00341 /* Initialize the DMA state*/ 00342 hdma->State = HAL_DMA_STATE_READY; 00343 00344 return HAL_OK; 00345 } 00346 00347 /** 00348 * @brief DeInitialize the DMA peripheral. 00349 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00350 * the configuration information for the specified DMA Channel. 00351 * @retval HAL status 00352 */ 00353 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma) 00354 { 00355 /* Check the DMA handle allocation */ 00356 if(hdma == NULL) 00357 { 00358 return HAL_ERROR; 00359 } 00360 00361 /* Check the parameters */ 00362 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); 00363 00364 /* Check the DMA peripheral state */ 00365 if(hdma->State == HAL_DMA_STATE_BUSY) 00366 { 00367 return HAL_ERROR; 00368 } 00369 00370 /* Disable the selected DMA Channelx */ 00371 __HAL_DMA_DISABLE(hdma); 00372 00373 /* Reset DMA Channel control register */ 00374 hdma->Instance->CCR = 0; 00375 00376 /* Reset DMA Channel Number of Data to Transfer register */ 00377 hdma->Instance->CNDTR = 0; 00378 00379 /* Reset DMA Channel peripheral address register */ 00380 hdma->Instance->CPAR = 0; 00381 00382 /* Reset DMA Channel memory address register */ 00383 hdma->Instance->CMAR = 0; 00384 00385 /* Clear all flags */ 00386 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_GI_FLAG_INDEX(hdma)); 00387 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); 00388 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); 00389 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); 00390 00391 /* Reset DMA channel selection register */ 00392 if (hdma->Instance == DMA1_Channel1) 00393 { 00394 /*Reset DMA request*/ 00395 DMA1_CSELR->CSELR &= ~DMA_CSELR_C1S; 00396 } 00397 else if (hdma->Instance == DMA1_Channel2) 00398 { 00399 /*Reset DMA request*/ 00400 DMA1_CSELR->CSELR &= ~DMA_CSELR_C2S; 00401 } 00402 else if (hdma->Instance == DMA1_Channel3) 00403 { 00404 /*Reset DMA request*/ 00405 DMA1_CSELR->CSELR &= ~DMA_CSELR_C3S; 00406 } 00407 else if (hdma->Instance == DMA1_Channel4) 00408 { 00409 /*Reset DMA request*/ 00410 DMA1_CSELR->CSELR &= ~DMA_CSELR_C4S; 00411 } 00412 else if (hdma->Instance == DMA1_Channel5) 00413 { 00414 /*Reset DMA request*/ 00415 DMA1_CSELR->CSELR &= ~DMA_CSELR_C5S; 00416 } 00417 else if (hdma->Instance == DMA1_Channel6) 00418 { 00419 /*Reset DMA request*/ 00420 DMA1_CSELR->CSELR &= ~DMA_CSELR_C6S; 00421 } 00422 else if (hdma->Instance == DMA1_Channel7) 00423 { 00424 /*Reset DMA request*/ 00425 DMA1_CSELR->CSELR &= ~DMA_CSELR_C7S; 00426 } 00427 else if (hdma->Instance == DMA2_Channel1) 00428 { 00429 /*Reset DMA request*/ 00430 DMA2_CSELR->CSELR &= ~DMA_CSELR_C1S; 00431 } 00432 else if (hdma->Instance == DMA2_Channel2) 00433 { 00434 /*Reset DMA request*/ 00435 DMA2_CSELR->CSELR &= ~DMA_CSELR_C2S; 00436 } 00437 else if (hdma->Instance == DMA2_Channel3) 00438 { 00439 /*Reset DMA request*/ 00440 DMA2_CSELR->CSELR &= ~DMA_CSELR_C3S; 00441 } 00442 else if (hdma->Instance == DMA2_Channel4) 00443 { 00444 /*Reset DMA request*/ 00445 DMA2_CSELR->CSELR &= ~DMA_CSELR_C4S; 00446 } 00447 else if (hdma->Instance == DMA2_Channel5) 00448 { 00449 /*Reset DMA request*/ 00450 DMA2_CSELR->CSELR &= ~DMA_CSELR_C5S; 00451 } 00452 else if (hdma->Instance == DMA2_Channel6) 00453 { 00454 /*Reset DMA request*/ 00455 DMA2_CSELR->CSELR &= ~DMA_CSELR_C6S; 00456 } 00457 else if (hdma->Instance == DMA2_Channel7) 00458 { 00459 /*Reset DMA request*/ 00460 DMA2_CSELR->CSELR &= ~DMA_CSELR_C7S; 00461 } 00462 00463 /* Initialize the error code */ 00464 hdma->ErrorCode = HAL_DMA_ERROR_NONE; 00465 00466 /* Initialize the DMA state */ 00467 hdma->State = HAL_DMA_STATE_RESET; 00468 00469 /* Release Lock */ 00470 __HAL_UNLOCK(hdma); 00471 00472 return HAL_OK; 00473 } 00474 00475 /** 00476 * @} 00477 */ 00478 00479 /** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions 00480 * @brief Input and Output operation functions 00481 * 00482 @verbatim 00483 =============================================================================== 00484 ##### IO operation functions ##### 00485 =============================================================================== 00486 [..] This section provides functions allowing to: 00487 (+) Configure the source, destination address and data length and Start DMA transfer 00488 (+) Configure the source, destination address and data length and 00489 Start DMA transfer with interrupt 00490 (+) Abort DMA transfer 00491 (+) Poll for transfer complete 00492 (+) Handle DMA interrupt request 00493 00494 @endverbatim 00495 * @{ 00496 */ 00497 00498 /** 00499 * @brief Start the DMA Transfer. 00500 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00501 * the configuration information for the specified DMA Channel. 00502 * @param SrcAddress: The source memory Buffer address 00503 * @param DstAddress: The destination memory Buffer address 00504 * @param DataLength: The length of data to be transferred from source to destination 00505 * @retval HAL status 00506 */ 00507 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) 00508 { 00509 /* Process locked */ 00510 __HAL_LOCK(hdma); 00511 00512 /* Change DMA peripheral state */ 00513 hdma->State = HAL_DMA_STATE_BUSY; 00514 00515 /* Check the parameters */ 00516 assert_param(IS_DMA_BUFFER_SIZE(DataLength)); 00517 00518 /* Disable the peripheral */ 00519 __HAL_DMA_DISABLE(hdma); 00520 00521 /* Configure the source, destination address and the data length */ 00522 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); 00523 00524 /* Enable the Peripheral */ 00525 __HAL_DMA_ENABLE(hdma); 00526 00527 return HAL_OK; 00528 } 00529 00530 /** 00531 * @brief Start the DMA Transfer with interrupt enabled. 00532 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00533 * the configuration information for the specified DMA Channel. 00534 * @param SrcAddress: The source memory Buffer address 00535 * @param DstAddress: The destination memory Buffer address 00536 * @param DataLength: The length of data to be transferred from source to destination 00537 * @retval HAL status 00538 */ 00539 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) 00540 { 00541 /* Process locked */ 00542 __HAL_LOCK(hdma); 00543 00544 /* Change DMA peripheral state */ 00545 hdma->State = HAL_DMA_STATE_BUSY; 00546 00547 /* Check the parameters */ 00548 assert_param(IS_DMA_BUFFER_SIZE(DataLength)); 00549 00550 /* Disable the peripheral */ 00551 __HAL_DMA_DISABLE(hdma); 00552 00553 /* Configure the source, destination address and the data length */ 00554 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); 00555 00556 /* Enable the transfer complete interrupt */ 00557 /* Enable the Half transfer complete interrupt */ 00558 /* Enable the transfer Error interrupt */ 00559 __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); 00560 00561 /* Enable the Peripheral */ 00562 __HAL_DMA_ENABLE(hdma); 00563 00564 return HAL_OK; 00565 } 00566 00567 /** 00568 * @brief Abort the DMA Transfer. 00569 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00570 * the configuration information for the specified DMA Channel. 00571 * 00572 * @note After disabling a DMA Channel, a check for wait until the DMA Channel is 00573 * effectively disabled is added. If a Channel is disabled 00574 * while a data transfer is ongoing, the current data will be transferred 00575 * and the Channel will be effectively disabled only after the transfer of 00576 * this single data is finished. 00577 * @retval HAL status 00578 */ 00579 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma) 00580 { 00581 uint32_t tickstart = 0; 00582 00583 /* Disable the channel */ 00584 __HAL_DMA_DISABLE(hdma); 00585 00586 /* Get tick */ 00587 tickstart = HAL_GetTick(); 00588 00589 /* Check if the DMA Channel is effectively disabled */ 00590 while((hdma->Instance->CCR & DMA_CCR_EN) != 0) 00591 { 00592 /* Check for the Timeout */ 00593 if((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT) 00594 { 00595 /* Update error code */ 00596 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT; 00597 00598 /* Change the DMA state */ 00599 hdma->State = HAL_DMA_STATE_TIMEOUT; 00600 00601 /* Process Unlocked */ 00602 __HAL_UNLOCK(hdma); 00603 00604 return HAL_TIMEOUT; 00605 } 00606 } 00607 /* Change the DMA state */ 00608 hdma->State = HAL_DMA_STATE_READY; 00609 00610 /* Process Unlocked */ 00611 __HAL_UNLOCK(hdma); 00612 00613 return HAL_OK; 00614 } 00615 00616 /** 00617 * @brief Polling for transfer complete. 00618 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00619 * the configuration information for the specified DMA Channel. 00620 * @param CompleteLevel: Specifies the DMA level complete. 00621 * @param Timeout: Timeout duration. 00622 * @retval HAL status 00623 */ 00624 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout) 00625 { 00626 uint32_t temp; 00627 uint32_t tickstart = 0; 00628 00629 /* Get the level transfer complete flag */ 00630 if(CompleteLevel == HAL_DMA_FULL_TRANSFER) 00631 { 00632 /* Transfer Complete flag */ 00633 temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma); 00634 } 00635 else 00636 { 00637 /* Half Transfer Complete flag */ 00638 temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma); 00639 } 00640 00641 /* Get tick */ 00642 tickstart = HAL_GetTick(); 00643 00644 while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET) 00645 { 00646 if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)) 00647 { 00648 /* Clear the transfer error flags */ 00649 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); 00650 00651 /* Update error code */ 00652 SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE); 00653 00654 /* Change the DMA state */ 00655 hdma->State= HAL_DMA_STATE_ERROR; 00656 00657 /* Process Unlocked */ 00658 __HAL_UNLOCK(hdma); 00659 00660 return HAL_ERROR; 00661 } 00662 /* Check for the Timeout */ 00663 if(Timeout != HAL_MAX_DELAY) 00664 { 00665 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) 00666 { 00667 /* Update error code */ 00668 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT; 00669 00670 /* Change the DMA state */ 00671 hdma->State = HAL_DMA_STATE_TIMEOUT; 00672 00673 /* Process Unlocked */ 00674 __HAL_UNLOCK(hdma); 00675 00676 return HAL_TIMEOUT; 00677 } 00678 } 00679 } 00680 00681 if(CompleteLevel == HAL_DMA_FULL_TRANSFER) 00682 { 00683 /* Clear the transfer complete flag */ 00684 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); 00685 00686 /* The selected Channelx EN bit is cleared (DMA is disabled and 00687 all transfers are complete) */ 00688 hdma->State = HAL_DMA_STATE_READY; 00689 00690 } 00691 else 00692 { 00693 /* Clear the half transfer complete flag */ 00694 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); 00695 00696 hdma->State = HAL_DMA_STATE_READY_HALF; 00697 } 00698 00699 /* Process unlocked */ 00700 __HAL_UNLOCK(hdma); 00701 00702 return HAL_OK; 00703 } 00704 00705 /** 00706 * @brief Handle DMA interrupt request. 00707 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00708 * the configuration information for the specified DMA Channel. 00709 * @retval None 00710 */ 00711 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma) 00712 { 00713 /* Transfer Error Interrupt management ***************************************/ 00714 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET) 00715 { 00716 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET) 00717 { 00718 /* Disable the transfer error interrupt */ 00719 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE); 00720 00721 /* Clear the transfer error flag */ 00722 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); 00723 00724 /* Update error code */ 00725 hdma->ErrorCode |= HAL_DMA_ERROR_TE; 00726 00727 /* Change the DMA state */ 00728 hdma->State = HAL_DMA_STATE_ERROR; 00729 00730 /* Process Unlocked */ 00731 __HAL_UNLOCK(hdma); 00732 00733 if (hdma->XferErrorCallback != NULL) 00734 { 00735 /* Transfer error callback */ 00736 hdma->XferErrorCallback(hdma); 00737 } 00738 } 00739 } 00740 00741 /* Half Transfer Complete Interrupt management ******************************/ 00742 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET) 00743 { 00744 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET) 00745 { 00746 /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */ 00747 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0) 00748 { 00749 /* Disable the half transfer interrupt */ 00750 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT); 00751 } 00752 /* Clear the half transfer complete flag */ 00753 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); 00754 00755 /* Change DMA peripheral state */ 00756 hdma->State = HAL_DMA_STATE_READY_HALF; 00757 00758 if(hdma->XferHalfCpltCallback != NULL) 00759 { 00760 /* Half transfer callback */ 00761 hdma->XferHalfCpltCallback(hdma); 00762 } 00763 } 00764 } 00765 00766 /* Transfer Complete Interrupt management ***********************************/ 00767 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET) 00768 { 00769 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET) 00770 { 00771 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0) 00772 { 00773 /* Disable the transfer complete interrupt */ 00774 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC); 00775 } 00776 /* Clear the transfer complete flag */ 00777 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); 00778 00779 /* Update error code */ 00780 hdma->ErrorCode |= HAL_DMA_ERROR_NONE; 00781 00782 /* Change the DMA state */ 00783 hdma->State = HAL_DMA_STATE_READY; 00784 00785 /* Process Unlocked */ 00786 __HAL_UNLOCK(hdma); 00787 00788 if(hdma->XferCpltCallback != NULL) 00789 { 00790 /* Transfer complete callback */ 00791 hdma->XferCpltCallback(hdma); 00792 } 00793 } 00794 } 00795 } 00796 00797 /** 00798 * @} 00799 */ 00800 00801 /** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions 00802 * @brief Peripheral State and Errors functions 00803 * 00804 @verbatim 00805 =============================================================================== 00806 ##### Peripheral State and Errors functions ##### 00807 =============================================================================== 00808 [..] 00809 This subsection provides functions allowing to 00810 (+) Check the DMA state 00811 (+) Get error code 00812 00813 @endverbatim 00814 * @{ 00815 */ 00816 00817 /** 00818 * @brief Return the DMA hande state. 00819 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00820 * the configuration information for the specified DMA Channel. 00821 * @retval HAL state 00822 */ 00823 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma) 00824 { 00825 /* Return DMA handle state */ 00826 return hdma->State; 00827 } 00828 00829 /** 00830 * @brief Return the DMA error code. 00831 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains 00832 * the configuration information for the specified DMA Channel. 00833 * @retval DMA Error Code 00834 */ 00835 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma) 00836 { 00837 return hdma->ErrorCode; 00838 } 00839 00840 /** 00841 * @} 00842 */ 00843 00844 /** 00845 * @} 00846 */ 00847 00848 /** @addtogroup DMA_Private_Functions 00849 * @{ 00850 */ 00851 00852 /** 00853 * @brief Sets the DMA Transfer parameter. 00854 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00855 * the configuration information for the specified DMA Channel. 00856 * @param SrcAddress: The source memory Buffer address 00857 * @param DstAddress: The destination memory Buffer address 00858 * @param DataLength: The length of data to be transferred from source to destination 00859 * @retval HAL status 00860 */ 00861 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) 00862 { 00863 /* Configure DMA Channel data length */ 00864 hdma->Instance->CNDTR = DataLength; 00865 00866 /* Peripheral to Memory */ 00867 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) 00868 { 00869 /* Configure DMA Channel destination address */ 00870 hdma->Instance->CPAR = DstAddress; 00871 00872 /* Configure DMA Channel source address */ 00873 hdma->Instance->CMAR = SrcAddress; 00874 } 00875 /* Memory to Peripheral */ 00876 else 00877 { 00878 /* Configure DMA Channel source address */ 00879 hdma->Instance->CPAR = SrcAddress; 00880 00881 /* Configure DMA Channel destination address */ 00882 hdma->Instance->CMAR = DstAddress; 00883 } 00884 } 00885 00886 /** 00887 * @} 00888 */ 00889 00890 #endif /* HAL_DMA_MODULE_ENABLED */ 00891 /** 00892 * @} 00893 */ 00894 00895 /** 00896 * @} 00897 */ 00898 00899 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 00900
Generated on Tue Jul 12 2022 11:35:09 by
