STM32H735xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32h7xx_hal_dma_ex.c 00004 * @author MCD Application Team 00005 * @brief DMA Extension HAL module driver 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the DMA Extension peripheral: 00008 * + Extended features functions 00009 * 00010 @verbatim 00011 ============================================================================== 00012 ##### How to use this driver ##### 00013 ============================================================================== 00014 [..] 00015 The DMA Extension HAL driver can be used as follows: 00016 (+) Start a multi buffer transfer using the HAL_DMA_MultiBufferStart() function 00017 for polling mode or HAL_DMA_MultiBufferStart_IT() for interrupt mode. 00018 00019 (+) Configure the DMA_MUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function. 00020 (+) Configure the DMA_MUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function. 00021 Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used 00022 to respectively enable/disable the request generator. 00023 00024 (+) To handle the DMAMUX Interrupts, the function HAL_DMAEx_MUX_IRQHandler should be called from 00025 the DMAMUX IRQ handler i.e DMAMUX1_OVR_IRQHandler or DMAMUX2_OVR_IRQHandler . 00026 As only one interrupt line is available for all DMAMUX channels and request generators , HAL_DMA_MUX_IRQHandler should be 00027 called with, as parameter, the appropriate DMA handle as many as used DMAs in the user project 00028 (exception done if a given DMA is not using the DMAMUX SYNC block neither a request generator) 00029 00030 -@- In Memory-to-Memory transfer mode, Multi (Double) Buffer mode is not allowed. 00031 -@- When Multi (Double) Buffer mode is enabled, the transfer is circular by default. 00032 -@- In Multi (Double) buffer mode, it is possible to update the base address for 00033 the AHB memory port on the fly (DMA_SxM0AR or DMA_SxM1AR) when the stream is enabled. 00034 -@- Multi (Double) buffer mode is possible with DMA and BDMA instances. 00035 00036 @endverbatim 00037 ****************************************************************************** 00038 * @attention 00039 * 00040 * Copyright (c) 2017 STMicroelectronics. 00041 * All rights reserved. 00042 * 00043 * This software is licensed under terms that can be found in the LICENSE file 00044 * in the root directory of this software component. 00045 * If no LICENSE file comes with this software, it is provided AS-IS. 00046 * 00047 ****************************************************************************** 00048 */ 00049 00050 /* Includes ------------------------------------------------------------------*/ 00051 #include "stm32h7xx_hal.h" 00052 00053 /** @addtogroup STM32H7xx_HAL_Driver 00054 * @{ 00055 */ 00056 00057 /** @defgroup DMAEx DMAEx 00058 * @brief DMA Extended HAL module driver 00059 * @{ 00060 */ 00061 00062 #ifdef HAL_DMA_MODULE_ENABLED 00063 00064 /* Private types -------------------------------------------------------------*/ 00065 /* Private variables ---------------------------------------------------------*/ 00066 /* Private Constants ---------------------------------------------------------*/ 00067 /* Private macros ------------------------------------------------------------*/ 00068 /* Private functions ---------------------------------------------------------*/ 00069 /** @addtogroup DMAEx_Private_Functions 00070 * @{ 00071 */ 00072 00073 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); 00074 00075 /** 00076 * @} 00077 */ 00078 00079 /* Exported functions ---------------------------------------------------------*/ 00080 00081 /** @addtogroup DMAEx_Exported_Functions 00082 * @{ 00083 */ 00084 00085 00086 /** @addtogroup DMAEx_Exported_Functions_Group1 00087 * 00088 @verbatim 00089 =============================================================================== 00090 ##### Extended features functions ##### 00091 =============================================================================== 00092 [..] This section provides functions allowing to: 00093 (+) Configure the source, destination address and data length and 00094 Start MultiBuffer DMA transfer 00095 (+) Configure the source, destination address and data length and 00096 Start MultiBuffer DMA transfer with interrupt 00097 (+) Change on the fly the memory0 or memory1 address. 00098 (+) Configure the DMA_MUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function. 00099 (+) Configure the DMA_MUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function. 00100 (+) Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used 00101 to respectively enable/disable the request generator. 00102 (+) Handle DMAMUX interrupts using HAL_DMAEx_MUX_IRQHandler : should be called from 00103 the DMAMUX IRQ handler i.e DMAMUX1_OVR_IRQHandler or DMAMUX2_OVR_IRQHandler 00104 00105 @endverbatim 00106 * @{ 00107 */ 00108 00109 00110 /** 00111 * @brief Starts the multi_buffer DMA Transfer. 00112 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains 00113 * the configuration information for the specified DMA Stream. 00114 * @param SrcAddress: The source memory Buffer address 00115 * @param DstAddress: The destination memory Buffer address 00116 * @param SecondMemAddress: The second memory Buffer address in case of multi buffer Transfer 00117 * @param DataLength: The length of data to be transferred from source to destination 00118 * @retval HAL status 00119 */ 00120 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength) 00121 { 00122 HAL_StatusTypeDef status = HAL_OK; 00123 __IO uint32_t *ifcRegister_Base; /* DMA Stream Interrupt Clear register */ 00124 00125 /* Check the parameters */ 00126 assert_param(IS_DMA_BUFFER_SIZE(DataLength)); 00127 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); 00128 00129 /* Memory-to-memory transfer not supported in double buffering mode */ 00130 if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY) 00131 { 00132 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED; 00133 status = HAL_ERROR; 00134 } 00135 else 00136 { 00137 /* Process Locked */ 00138 __HAL_LOCK(hdma); 00139 00140 if(HAL_DMA_STATE_READY == hdma->State) 00141 { 00142 /* Change DMA peripheral state */ 00143 hdma->State = HAL_DMA_STATE_BUSY; 00144 00145 /* Initialize the error code */ 00146 hdma->ErrorCode = HAL_DMA_ERROR_NONE; 00147 00148 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */ 00149 { 00150 /* Enable the Double buffer mode */ 00151 ((DMA_Stream_TypeDef *)hdma->Instance)->CR |= DMA_SxCR_DBM; 00152 00153 /* Configure DMA Stream destination address */ 00154 ((DMA_Stream_TypeDef *)hdma->Instance)->M1AR = SecondMemAddress; 00155 00156 /* Calculate the interrupt clear flag register (IFCR) base address */ 00157 ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 8U)); 00158 00159 /* Clear all flags */ 00160 *ifcRegister_Base = 0x3FUL << (hdma->StreamIndex & 0x1FU); 00161 } 00162 else /* BDMA instance(s) */ 00163 { 00164 /* Enable the Double buffer mode */ 00165 ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR |= (BDMA_CCR_DBM | BDMA_CCR_CIRC); 00166 00167 /* Configure DMA Stream destination address */ 00168 ((BDMA_Channel_TypeDef *)hdma->Instance)->CM1AR = SecondMemAddress; 00169 00170 /* Calculate the interrupt clear flag register (IFCR) base address */ 00171 ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 4U)); 00172 00173 /* Clear all flags */ 00174 *ifcRegister_Base = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU); 00175 } 00176 00177 if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */ 00178 { 00179 /* Configure the source, destination address and the data length */ 00180 DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength); 00181 00182 /* Clear the DMAMUX synchro overrun flag */ 00183 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask; 00184 00185 if(hdma->DMAmuxRequestGen != 0U) 00186 { 00187 /* Clear the DMAMUX request generator overrun flag */ 00188 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask; 00189 } 00190 } 00191 00192 /* Enable the peripheral */ 00193 __HAL_DMA_ENABLE(hdma); 00194 } 00195 else 00196 { 00197 /* Set the error code to busy */ 00198 hdma->ErrorCode = HAL_DMA_ERROR_BUSY; 00199 00200 /* Return error status */ 00201 status = HAL_ERROR; 00202 } 00203 } 00204 return status; 00205 } 00206 00207 /** 00208 * @brief Starts the multi_buffer DMA Transfer with interrupt enabled. 00209 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00210 * the configuration information for the specified DMA Stream. 00211 * @param SrcAddress: The source memory Buffer address 00212 * @param DstAddress: The destination memory Buffer address 00213 * @param SecondMemAddress: The second memory Buffer address in case of multi buffer Transfer 00214 * @param DataLength: The length of data to be transferred from source to destination 00215 * @retval HAL status 00216 */ 00217 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength) 00218 { 00219 HAL_StatusTypeDef status = HAL_OK; 00220 __IO uint32_t *ifcRegister_Base; /* DMA Stream Interrupt Clear register */ 00221 00222 /* Check the parameters */ 00223 assert_param(IS_DMA_BUFFER_SIZE(DataLength)); 00224 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); 00225 00226 /* Memory-to-memory transfer not supported in double buffering mode */ 00227 if(hdma->Init.Direction == DMA_MEMORY_TO_MEMORY) 00228 { 00229 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED; 00230 return HAL_ERROR; 00231 } 00232 00233 /* Process locked */ 00234 __HAL_LOCK(hdma); 00235 00236 if(HAL_DMA_STATE_READY == hdma->State) 00237 { 00238 /* Change DMA peripheral state */ 00239 hdma->State = HAL_DMA_STATE_BUSY; 00240 00241 /* Initialize the error code */ 00242 hdma->ErrorCode = HAL_DMA_ERROR_NONE; 00243 00244 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */ 00245 { 00246 /* Enable the Double buffer mode */ 00247 ((DMA_Stream_TypeDef *)hdma->Instance)->CR |= DMA_SxCR_DBM; 00248 00249 /* Configure DMA Stream destination address */ 00250 ((DMA_Stream_TypeDef *)hdma->Instance)->M1AR = SecondMemAddress; 00251 00252 /* Calculate the interrupt clear flag register (IFCR) base address */ 00253 ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 8U)); 00254 00255 /* Clear all flags */ 00256 *ifcRegister_Base = 0x3FUL << (hdma->StreamIndex & 0x1FU); 00257 } 00258 else /* BDMA instance(s) */ 00259 { 00260 /* Enable the Double buffer mode */ 00261 ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR |= (BDMA_CCR_DBM | BDMA_CCR_CIRC); 00262 00263 /* Configure DMA Stream destination address */ 00264 ((BDMA_Channel_TypeDef *)hdma->Instance)->CM1AR = SecondMemAddress; 00265 00266 /* Calculate the interrupt clear flag register (IFCR) base address */ 00267 ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 4U)); 00268 00269 /* Clear all flags */ 00270 *ifcRegister_Base = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU); 00271 } 00272 00273 /* Configure the source, destination address and the data length */ 00274 DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength); 00275 00276 if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */ 00277 { 00278 /* Clear the DMAMUX synchro overrun flag */ 00279 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask; 00280 00281 if(hdma->DMAmuxRequestGen != 0U) 00282 { 00283 /* Clear the DMAMUX request generator overrun flag */ 00284 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask; 00285 } 00286 } 00287 00288 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */ 00289 { 00290 /* Enable Common interrupts*/ 00291 MODIFY_REG(((DMA_Stream_TypeDef *)hdma->Instance)->CR, (DMA_IT_TC | DMA_IT_TE | DMA_IT_DME | DMA_IT_HT), (DMA_IT_TC | DMA_IT_TE | DMA_IT_DME)); 00292 ((DMA_Stream_TypeDef *)hdma->Instance)->FCR |= DMA_IT_FE; 00293 00294 if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL)) 00295 { 00296 /*Enable Half Transfer IT if corresponding Callback is set*/ 00297 ((DMA_Stream_TypeDef *)hdma->Instance)->CR |= DMA_IT_HT; 00298 } 00299 } 00300 else /* BDMA instance(s) */ 00301 { 00302 /* Enable Common interrupts*/ 00303 MODIFY_REG(((BDMA_Channel_TypeDef *)hdma->Instance)->CCR, (BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE), (BDMA_CCR_TCIE | BDMA_CCR_TEIE)); 00304 00305 if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL)) 00306 { 00307 /*Enable Half Transfer IT if corresponding Callback is set*/ 00308 ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR |= BDMA_CCR_HTIE; 00309 } 00310 } 00311 00312 if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */ 00313 { 00314 /* Check if DMAMUX Synchronization is enabled*/ 00315 if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U) 00316 { 00317 /* Enable DMAMUX sync overrun IT*/ 00318 hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE; 00319 } 00320 00321 if(hdma->DMAmuxRequestGen != 0U) 00322 { 00323 /* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/ 00324 /* enable the request gen overrun IT*/ 00325 hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE; 00326 } 00327 } 00328 00329 /* Enable the peripheral */ 00330 __HAL_DMA_ENABLE(hdma); 00331 } 00332 else 00333 { 00334 /* Set the error code to busy */ 00335 hdma->ErrorCode = HAL_DMA_ERROR_BUSY; 00336 00337 /* Return error status */ 00338 status = HAL_ERROR; 00339 } 00340 return status; 00341 } 00342 00343 /** 00344 * @brief Change the memory0 or memory1 address on the fly. 00345 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00346 * the configuration information for the specified DMA Stream. 00347 * @param Address: The new address 00348 * @param memory: the memory to be changed, This parameter can be one of 00349 * the following values: 00350 * MEMORY0 / 00351 * MEMORY1 00352 * @note The MEMORY0 address can be changed only when the current transfer use 00353 * MEMORY1 and the MEMORY1 address can be changed only when the current 00354 * transfer use MEMORY0. 00355 * @retval HAL status 00356 */ 00357 HAL_StatusTypeDef HAL_DMAEx_ChangeMemory(DMA_HandleTypeDef *hdma, uint32_t Address, HAL_DMA_MemoryTypeDef memory) 00358 { 00359 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */ 00360 { 00361 if(memory == MEMORY0) 00362 { 00363 /* change the memory0 address */ 00364 ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = Address; 00365 } 00366 else 00367 { 00368 /* change the memory1 address */ 00369 ((DMA_Stream_TypeDef *)hdma->Instance)->M1AR = Address; 00370 } 00371 } 00372 else /* BDMA instance(s) */ 00373 { 00374 if(memory == MEMORY0) 00375 { 00376 /* change the memory0 address */ 00377 ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = Address; 00378 } 00379 else 00380 { 00381 /* change the memory1 address */ 00382 ((BDMA_Channel_TypeDef *)hdma->Instance)->CM1AR = Address; 00383 } 00384 } 00385 00386 return HAL_OK; 00387 } 00388 00389 /** 00390 * @brief Configure the DMAMUX synchronization parameters for a given DMA stream (instance). 00391 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00392 * the configuration information for the specified DMA Stream. 00393 * @param pSyncConfig : pointer to HAL_DMA_MuxSyncConfigTypeDef : contains the DMAMUX synchronization parameters 00394 * @retval HAL status 00395 */ 00396 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxSync(DMA_HandleTypeDef *hdma, HAL_DMA_MuxSyncConfigTypeDef *pSyncConfig) 00397 { 00398 uint32_t syncSignalID = 0; 00399 uint32_t syncPolarity = 0; 00400 00401 /* Check the parameters */ 00402 assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance)); 00403 assert_param(IS_DMAMUX_SYNC_STATE(pSyncConfig->SyncEnable)); 00404 assert_param(IS_DMAMUX_SYNC_EVENT(pSyncConfig->EventEnable)); 00405 assert_param(IS_DMAMUX_SYNC_REQUEST_NUMBER(pSyncConfig->RequestNumber)); 00406 00407 if(pSyncConfig->SyncEnable == ENABLE) 00408 { 00409 assert_param(IS_DMAMUX_SYNC_POLARITY(pSyncConfig->SyncPolarity)); 00410 00411 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */ 00412 { 00413 assert_param(IS_DMA_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID)); 00414 } 00415 else 00416 { 00417 assert_param(IS_BDMA_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID)); 00418 } 00419 syncSignalID = pSyncConfig->SyncSignalID; 00420 syncPolarity = pSyncConfig->SyncPolarity; 00421 } 00422 00423 /*Check if the DMA state is ready */ 00424 if(hdma->State == HAL_DMA_STATE_READY) 00425 { 00426 /* Process Locked */ 00427 __HAL_LOCK(hdma); 00428 00429 /* Disable the synchronization and event generation before applying a new config */ 00430 CLEAR_BIT(hdma->DMAmuxChannel->CCR,(DMAMUX_CxCR_SE | DMAMUX_CxCR_EGE)); 00431 00432 /* Set the new synchronization parameters (and keep the request ID filled during the Init)*/ 00433 MODIFY_REG( hdma->DMAmuxChannel->CCR, \ 00434 (~DMAMUX_CxCR_DMAREQ_ID) , \ 00435 (syncSignalID << DMAMUX_CxCR_SYNC_ID_Pos) | \ 00436 ((pSyncConfig->RequestNumber - 1U) << DMAMUX_CxCR_NBREQ_Pos) | \ 00437 syncPolarity | ((uint32_t)pSyncConfig->SyncEnable << DMAMUX_CxCR_SE_Pos) | \ 00438 ((uint32_t)pSyncConfig->EventEnable << DMAMUX_CxCR_EGE_Pos)); 00439 00440 /* Process Locked */ 00441 __HAL_UNLOCK(hdma); 00442 00443 return HAL_OK; 00444 } 00445 else 00446 { 00447 /* Set the error code to busy */ 00448 hdma->ErrorCode = HAL_DMA_ERROR_BUSY; 00449 00450 /* Return error status */ 00451 return HAL_ERROR; 00452 } 00453 } 00454 00455 /** 00456 * @brief Configure the DMAMUX request generator block used by the given DMA stream (instance). 00457 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00458 * the configuration information for the specified DMA Stream. 00459 * @param pRequestGeneratorConfig : pointer to HAL_DMA_MuxRequestGeneratorConfigTypeDef : 00460 * contains the request generator parameters. 00461 * 00462 * @retval HAL status 00463 */ 00464 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxRequestGenerator (DMA_HandleTypeDef *hdma, HAL_DMA_MuxRequestGeneratorConfigTypeDef *pRequestGeneratorConfig) 00465 { 00466 HAL_StatusTypeDef status; 00467 HAL_DMA_StateTypeDef temp_state = hdma->State; 00468 00469 /* Check the parameters */ 00470 assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance)); 00471 00472 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */ 00473 { 00474 assert_param(IS_DMA_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID)); 00475 } 00476 else 00477 { 00478 assert_param(IS_BDMA_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID)); 00479 } 00480 00481 00482 assert_param(IS_DMAMUX_REQUEST_GEN_POLARITY(pRequestGeneratorConfig->Polarity)); 00483 assert_param(IS_DMAMUX_REQUEST_GEN_REQUEST_NUMBER(pRequestGeneratorConfig->RequestNumber)); 00484 00485 /* check if the DMA state is ready 00486 and DMA is using a DMAMUX request generator block 00487 */ 00488 if(hdma->DMAmuxRequestGen == 0U) 00489 { 00490 /* Set the error code to busy */ 00491 hdma->ErrorCode = HAL_DMA_ERROR_PARAM; 00492 00493 /* error status */ 00494 status = HAL_ERROR; 00495 } 00496 else if(((hdma->DMAmuxRequestGen->RGCR & DMAMUX_RGxCR_GE) == 0U) && (temp_state == HAL_DMA_STATE_READY)) 00497 { 00498 /* RequestGenerator must be disable prior to the configuration i.e GE bit is 0 */ 00499 00500 /* Process Locked */ 00501 __HAL_LOCK(hdma); 00502 00503 /* Set the request generator new parameters */ 00504 hdma->DMAmuxRequestGen->RGCR = pRequestGeneratorConfig->SignalID | \ 00505 ((pRequestGeneratorConfig->RequestNumber - 1U) << DMAMUX_RGxCR_GNBREQ_Pos)| \ 00506 pRequestGeneratorConfig->Polarity; 00507 /* Process Locked */ 00508 __HAL_UNLOCK(hdma); 00509 00510 return HAL_OK; 00511 } 00512 else 00513 { 00514 /* Set the error code to busy */ 00515 hdma->ErrorCode = HAL_DMA_ERROR_BUSY; 00516 00517 /* error status */ 00518 status = HAL_ERROR; 00519 } 00520 00521 return status; 00522 } 00523 00524 /** 00525 * @brief Enable the DMAMUX request generator block used by the given DMA stream (instance). 00526 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00527 * the configuration information for the specified DMA Stream. 00528 * @retval HAL status 00529 */ 00530 HAL_StatusTypeDef HAL_DMAEx_EnableMuxRequestGenerator (DMA_HandleTypeDef *hdma) 00531 { 00532 /* Check the parameters */ 00533 assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance)); 00534 00535 /* check if the DMA state is ready 00536 and DMA is using a DMAMUX request generator block */ 00537 if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0U)) 00538 { 00539 /* Enable the request generator*/ 00540 hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_GE; 00541 00542 return HAL_OK; 00543 } 00544 else 00545 { 00546 return HAL_ERROR; 00547 } 00548 } 00549 00550 /** 00551 * @brief Disable the DMAMUX request generator block used by the given DMA stream (instance). 00552 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00553 * the configuration information for the specified DMA Stream. 00554 * @retval HAL status 00555 */ 00556 HAL_StatusTypeDef HAL_DMAEx_DisableMuxRequestGenerator (DMA_HandleTypeDef *hdma) 00557 { 00558 /* Check the parameters */ 00559 assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance)); 00560 00561 /* check if the DMA state is ready 00562 and DMA is using a DMAMUX request generator block */ 00563 if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0U)) 00564 { 00565 /* Disable the request generator*/ 00566 hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_GE; 00567 00568 return HAL_OK; 00569 } 00570 else 00571 { 00572 return HAL_ERROR; 00573 } 00574 } 00575 00576 /** 00577 * @brief Handles DMAMUX interrupt request. 00578 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00579 * the configuration information for the specified DMA Stream. 00580 * @retval None 00581 */ 00582 void HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef *hdma) 00583 { 00584 /* Check for DMAMUX Synchronization overrun */ 00585 if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U) 00586 { 00587 /* Disable the synchro overrun interrupt */ 00588 hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE; 00589 00590 /* Clear the DMAMUX synchro overrun flag */ 00591 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask; 00592 00593 /* Update error code */ 00594 hdma->ErrorCode |= HAL_DMA_ERROR_SYNC; 00595 00596 if(hdma->XferErrorCallback != NULL) 00597 { 00598 /* Transfer error callback */ 00599 hdma->XferErrorCallback(hdma); 00600 } 00601 } 00602 00603 if(hdma->DMAmuxRequestGen != 0) 00604 { 00605 /* if using a DMAMUX request generator block Check for DMAMUX request generator overrun */ 00606 if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U) 00607 { 00608 /* Disable the request gen overrun interrupt */ 00609 hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE; 00610 00611 /* Clear the DMAMUX request generator overrun flag */ 00612 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask; 00613 00614 /* Update error code */ 00615 hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN; 00616 00617 if(hdma->XferErrorCallback != NULL) 00618 { 00619 /* Transfer error callback */ 00620 hdma->XferErrorCallback(hdma); 00621 } 00622 } 00623 } 00624 } 00625 00626 00627 /** 00628 * @} 00629 */ 00630 00631 /** 00632 * @} 00633 */ 00634 00635 /** @addtogroup DMAEx_Private_Functions 00636 * @{ 00637 */ 00638 00639 /** 00640 * @brief Set the DMA Transfer parameter. 00641 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 00642 * the configuration information for the specified DMA Stream. 00643 * @param SrcAddress: The source memory Buffer address 00644 * @param DstAddress: The destination memory Buffer address 00645 * @param DataLength: The length of data to be transferred from source to destination 00646 * @retval HAL status 00647 */ 00648 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) 00649 { 00650 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */ 00651 { 00652 /* Configure DMA Stream data length */ 00653 ((DMA_Stream_TypeDef *)hdma->Instance)->NDTR = DataLength; 00654 00655 /* Peripheral to Memory */ 00656 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) 00657 { 00658 /* Configure DMA Stream destination address */ 00659 ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = DstAddress; 00660 00661 /* Configure DMA Stream source address */ 00662 ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = SrcAddress; 00663 } 00664 /* Memory to Peripheral */ 00665 else 00666 { 00667 /* Configure DMA Stream source address */ 00668 ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = SrcAddress; 00669 00670 /* Configure DMA Stream destination address */ 00671 ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = DstAddress; 00672 } 00673 } 00674 else /* BDMA instance(s) */ 00675 { 00676 /* Configure DMA Stream data length */ 00677 ((BDMA_Channel_TypeDef *)hdma->Instance)->CNDTR = DataLength; 00678 00679 /* Peripheral to Memory */ 00680 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) 00681 { 00682 /* Configure DMA Stream destination address */ 00683 ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = DstAddress; 00684 00685 /* Configure DMA Stream source address */ 00686 ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = SrcAddress; 00687 } 00688 /* Memory to Peripheral */ 00689 else 00690 { 00691 /* Configure DMA Stream source address */ 00692 ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = SrcAddress; 00693 00694 /* Configure DMA Stream destination address */ 00695 ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = DstAddress; 00696 } 00697 } 00698 } 00699 00700 /** 00701 * @} 00702 */ 00703 00704 #endif /* HAL_DMA_MODULE_ENABLED */ 00705 /** 00706 * @} 00707 */ 00708 00709 /** 00710 * @} 00711 */ 00712