You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

715 lines
25 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_hal_dma_ex.c
  4. * @author MCD Application Team
  5. * @brief DMA Extension HAL module driver
  6. * This file provides firmware functions to manage the following
  7. * functionalities of the DMA Extension peripheral:
  8. * + Extended features functions
  9. *
  10. @verbatim
  11. ==============================================================================
  12. ##### How to use this driver #####
  13. ==============================================================================
  14. [..]
  15. The DMA Extension HAL driver can be used as follows:
  16. (+) Start a multi buffer transfer using the HAL_DMA_MultiBufferStart() function
  17. for polling mode or HAL_DMA_MultiBufferStart_IT() for interrupt mode.
  18. (+) Configure the DMA_MUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
  19. (+) Configure the DMA_MUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function.
  20. Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used
  21. to respectively enable/disable the request generator.
  22. (+) To handle the DMAMUX Interrupts, the function HAL_DMAEx_MUX_IRQHandler should be called from
  23. the DMAMUX IRQ handler i.e DMAMUX1_OVR_IRQHandler or DMAMUX2_OVR_IRQHandler .
  24. As only one interrupt line is available for all DMAMUX channels and request generators , HAL_DMA_MUX_IRQHandler should be
  25. called with, as parameter, the appropriate DMA handle as many as used DMAs in the user project
  26. (exception done if a given DMA is not using the DMAMUX SYNC block neither a request generator)
  27. -@- In Memory-to-Memory transfer mode, Multi (Double) Buffer mode is not allowed.
  28. -@- When Multi (Double) Buffer mode is enabled, the transfer is circular by default.
  29. -@- In Multi (Double) buffer mode, it is possible to update the base address for
  30. the AHB memory port on the fly (DMA_SxM0AR or DMA_SxM1AR) when the stream is enabled.
  31. -@- Multi (Double) buffer mode is possible with DMA and BDMA instances.
  32. @endverbatim
  33. ******************************************************************************
  34. * @attention
  35. *
  36. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics.
  37. * All rights reserved.</center></h2>
  38. *
  39. * This software component is licensed by ST under BSD 3-Clause license,
  40. * the "License"; You may not use this file except in compliance with the
  41. * License. You may obtain a copy of the License at:
  42. * opensource.org/licenses/BSD-3-Clause
  43. *
  44. ******************************************************************************
  45. */
  46. /* Includes ------------------------------------------------------------------*/
  47. #include "stm32h7xx_hal.h"
  48. /** @addtogroup STM32H7xx_HAL_Driver
  49. * @{
  50. */
  51. /** @defgroup DMAEx DMAEx
  52. * @brief DMA Extended HAL module driver
  53. * @{
  54. */
  55. #ifdef HAL_DMA_MODULE_ENABLED
  56. /* Private types -------------------------------------------------------------*/
  57. /* Private variables ---------------------------------------------------------*/
  58. /* Private Constants ---------------------------------------------------------*/
  59. /* Private macros ------------------------------------------------------------*/
  60. /* Private functions ---------------------------------------------------------*/
  61. /** @addtogroup DMAEx_Private_Functions
  62. * @{
  63. */
  64. static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
  65. /**
  66. * @}
  67. */
  68. /* Exported functions ---------------------------------------------------------*/
  69. /** @addtogroup DMAEx_Exported_Functions
  70. * @{
  71. */
  72. /** @addtogroup DMAEx_Exported_Functions_Group1
  73. *
  74. @verbatim
  75. ===============================================================================
  76. ##### Extended features functions #####
  77. ===============================================================================
  78. [..] This section provides functions allowing to:
  79. (+) Configure the source, destination address and data length and
  80. Start MultiBuffer DMA transfer
  81. (+) Configure the source, destination address and data length and
  82. Start MultiBuffer DMA transfer with interrupt
  83. (+) Change on the fly the memory0 or memory1 address.
  84. (+) Configure the DMA_MUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
  85. (+) Configure the DMA_MUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function.
  86. (+) Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used
  87. to respectively enable/disable the request generator.
  88. (+) Handle DMAMUX interrupts using HAL_DMAEx_MUX_IRQHandler : should be called from
  89. the DMAMUX IRQ handler i.e DMAMUX1_OVR_IRQHandler or DMAMUX2_OVR_IRQHandler
  90. @endverbatim
  91. * @{
  92. */
  93. /**
  94. * @brief Starts the multi_buffer DMA Transfer.
  95. * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
  96. * the configuration information for the specified DMA Stream.
  97. * @param SrcAddress: The source memory Buffer address
  98. * @param DstAddress: The destination memory Buffer address
  99. * @param SecondMemAddress: The second memory Buffer address in case of multi buffer Transfer
  100. * @param DataLength: The length of data to be transferred from source to destination
  101. * @retval HAL status
  102. */
  103. HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
  104. {
  105. HAL_StatusTypeDef status = HAL_OK;
  106. __IO uint32_t *ifcRegister_Base; /* DMA Stream Interrupt Clear register */
  107. /* Check the parameters */
  108. assert_param(IS_DMA_BUFFER_SIZE(DataLength));
  109. assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
  110. /* Memory-to-memory transfer not supported in double buffering mode */
  111. if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
  112. {
  113. hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
  114. status = HAL_ERROR;
  115. }
  116. else
  117. {
  118. /* Process Locked */
  119. __HAL_LOCK(hdma);
  120. if(HAL_DMA_STATE_READY == hdma->State)
  121. {
  122. /* Change DMA peripheral state */
  123. hdma->State = HAL_DMA_STATE_BUSY;
  124. /* Initialize the error code */
  125. hdma->ErrorCode = HAL_DMA_ERROR_NONE;
  126. if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
  127. {
  128. /* Enable the Double buffer mode */
  129. ((DMA_Stream_TypeDef *)hdma->Instance)->CR |= DMA_SxCR_DBM;
  130. /* Configure DMA Stream destination address */
  131. ((DMA_Stream_TypeDef *)hdma->Instance)->M1AR = SecondMemAddress;
  132. /* Calculate the interrupt clear flag register (IFCR) base address */
  133. ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 8U));
  134. /* Clear all flags */
  135. *ifcRegister_Base = 0x3FUL << (hdma->StreamIndex & 0x1FU);
  136. }
  137. else /* BDMA instance(s) */
  138. {
  139. /* Enable the Double buffer mode */
  140. ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR |= (BDMA_CCR_DBM | BDMA_CCR_CIRC);
  141. /* Configure DMA Stream destination address */
  142. ((BDMA_Channel_TypeDef *)hdma->Instance)->CM1AR = SecondMemAddress;
  143. /* Calculate the interrupt clear flag register (IFCR) base address */
  144. ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 4U));
  145. /* Clear all flags */
  146. *ifcRegister_Base = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
  147. }
  148. if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
  149. {
  150. /* Configure the source, destination address and the data length */
  151. DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
  152. /* Clear the DMAMUX synchro overrun flag */
  153. hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
  154. if(hdma->DMAmuxRequestGen != 0U)
  155. {
  156. /* Clear the DMAMUX request generator overrun flag */
  157. hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
  158. }
  159. }
  160. /* Enable the peripheral */
  161. __HAL_DMA_ENABLE(hdma);
  162. }
  163. else
  164. {
  165. /* Set the error code to busy */
  166. hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
  167. /* Return error status */
  168. status = HAL_ERROR;
  169. }
  170. }
  171. return status;
  172. }
  173. /**
  174. * @brief Starts the multi_buffer DMA Transfer with interrupt enabled.
  175. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
  176. * the configuration information for the specified DMA Stream.
  177. * @param SrcAddress: The source memory Buffer address
  178. * @param DstAddress: The destination memory Buffer address
  179. * @param SecondMemAddress: The second memory Buffer address in case of multi buffer Transfer
  180. * @param DataLength: The length of data to be transferred from source to destination
  181. * @retval HAL status
  182. */
  183. HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
  184. {
  185. HAL_StatusTypeDef status = HAL_OK;
  186. __IO uint32_t *ifcRegister_Base; /* DMA Stream Interrupt Clear register */
  187. /* Check the parameters */
  188. assert_param(IS_DMA_BUFFER_SIZE(DataLength));
  189. assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
  190. /* Memory-to-memory transfer not supported in double buffering mode */
  191. if(hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
  192. {
  193. hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
  194. return HAL_ERROR;
  195. }
  196. /* Process locked */
  197. __HAL_LOCK(hdma);
  198. if(HAL_DMA_STATE_READY == hdma->State)
  199. {
  200. /* Change DMA peripheral state */
  201. hdma->State = HAL_DMA_STATE_BUSY;
  202. /* Initialize the error code */
  203. hdma->ErrorCode = HAL_DMA_ERROR_NONE;
  204. if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
  205. {
  206. /* Enable the Double buffer mode */
  207. ((DMA_Stream_TypeDef *)hdma->Instance)->CR |= DMA_SxCR_DBM;
  208. /* Configure DMA Stream destination address */
  209. ((DMA_Stream_TypeDef *)hdma->Instance)->M1AR = SecondMemAddress;
  210. /* Calculate the interrupt clear flag register (IFCR) base address */
  211. ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 8U));
  212. /* Clear all flags */
  213. *ifcRegister_Base = 0x3FUL << (hdma->StreamIndex & 0x1FU);
  214. }
  215. else /* BDMA instance(s) */
  216. {
  217. /* Enable the Double buffer mode */
  218. ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR |= (BDMA_CCR_DBM | BDMA_CCR_CIRC);
  219. /* Configure DMA Stream destination address */
  220. ((BDMA_Channel_TypeDef *)hdma->Instance)->CM1AR = SecondMemAddress;
  221. /* Calculate the interrupt clear flag register (IFCR) base address */
  222. ifcRegister_Base = (uint32_t *)((uint32_t)(hdma->StreamBaseAddress + 4U));
  223. /* Clear all flags */
  224. *ifcRegister_Base = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
  225. }
  226. /* Configure the source, destination address and the data length */
  227. DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
  228. if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
  229. {
  230. /* Clear the DMAMUX synchro overrun flag */
  231. hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
  232. if(hdma->DMAmuxRequestGen != 0U)
  233. {
  234. /* Clear the DMAMUX request generator overrun flag */
  235. hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
  236. }
  237. }
  238. if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
  239. {
  240. /* Enable Common interrupts*/
  241. 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));
  242. ((DMA_Stream_TypeDef *)hdma->Instance)->FCR |= DMA_IT_FE;
  243. if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
  244. {
  245. /*Enable Half Transfer IT if corresponding Callback is set*/
  246. ((DMA_Stream_TypeDef *)hdma->Instance)->CR |= DMA_IT_HT;
  247. }
  248. }
  249. else /* BDMA instance(s) */
  250. {
  251. /* Enable Common interrupts*/
  252. MODIFY_REG(((BDMA_Channel_TypeDef *)hdma->Instance)->CCR, (BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE), (BDMA_CCR_TCIE | BDMA_CCR_TEIE));
  253. if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
  254. {
  255. /*Enable Half Transfer IT if corresponding Callback is set*/
  256. ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR |= BDMA_CCR_HTIE;
  257. }
  258. }
  259. if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
  260. {
  261. /* Check if DMAMUX Synchronization is enabled*/
  262. if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
  263. {
  264. /* Enable DMAMUX sync overrun IT*/
  265. hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
  266. }
  267. if(hdma->DMAmuxRequestGen != 0U)
  268. {
  269. /* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/
  270. /* enable the request gen overrun IT*/
  271. hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
  272. }
  273. }
  274. /* Enable the peripheral */
  275. __HAL_DMA_ENABLE(hdma);
  276. }
  277. else
  278. {
  279. /* Set the error code to busy */
  280. hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
  281. /* Return error status */
  282. status = HAL_ERROR;
  283. }
  284. return status;
  285. }
  286. /**
  287. * @brief Change the memory0 or memory1 address on the fly.
  288. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
  289. * the configuration information for the specified DMA Stream.
  290. * @param Address: The new address
  291. * @param memory: the memory to be changed, This parameter can be one of
  292. * the following values:
  293. * MEMORY0 /
  294. * MEMORY1
  295. * @note The MEMORY0 address can be changed only when the current transfer use
  296. * MEMORY1 and the MEMORY1 address can be changed only when the current
  297. * transfer use MEMORY0.
  298. * @retval HAL status
  299. */
  300. HAL_StatusTypeDef HAL_DMAEx_ChangeMemory(DMA_HandleTypeDef *hdma, uint32_t Address, HAL_DMA_MemoryTypeDef memory)
  301. {
  302. if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
  303. {
  304. if(memory == MEMORY0)
  305. {
  306. /* change the memory0 address */
  307. ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = Address;
  308. }
  309. else
  310. {
  311. /* change the memory1 address */
  312. ((DMA_Stream_TypeDef *)hdma->Instance)->M1AR = Address;
  313. }
  314. }
  315. else /* BDMA instance(s) */
  316. {
  317. if(memory == MEMORY0)
  318. {
  319. /* change the memory0 address */
  320. ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = Address;
  321. }
  322. else
  323. {
  324. /* change the memory1 address */
  325. ((BDMA_Channel_TypeDef *)hdma->Instance)->CM1AR = Address;
  326. }
  327. }
  328. return HAL_OK;
  329. }
  330. /**
  331. * @brief Configure the DMAMUX synchronization parameters for a given DMA stream (instance).
  332. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
  333. * the configuration information for the specified DMA Stream.
  334. * @param pSyncConfig : pointer to HAL_DMA_MuxSyncConfigTypeDef : contains the DMAMUX synchronization parameters
  335. * @retval HAL status
  336. */
  337. HAL_StatusTypeDef HAL_DMAEx_ConfigMuxSync(DMA_HandleTypeDef *hdma, HAL_DMA_MuxSyncConfigTypeDef *pSyncConfig)
  338. {
  339. uint32_t syncSignalID = 0;
  340. uint32_t syncPolarity = 0;
  341. /* Check the parameters */
  342. assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance));
  343. assert_param(IS_DMAMUX_SYNC_STATE(pSyncConfig->SyncEnable));
  344. assert_param(IS_DMAMUX_SYNC_EVENT(pSyncConfig->EventEnable));
  345. assert_param(IS_DMAMUX_SYNC_REQUEST_NUMBER(pSyncConfig->RequestNumber));
  346. if(pSyncConfig->SyncEnable == ENABLE)
  347. {
  348. assert_param(IS_DMAMUX_SYNC_POLARITY(pSyncConfig->SyncPolarity));
  349. if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
  350. {
  351. assert_param(IS_DMA_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID));
  352. }
  353. else
  354. {
  355. assert_param(IS_BDMA_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID));
  356. }
  357. syncSignalID = pSyncConfig->SyncSignalID;
  358. syncPolarity = pSyncConfig->SyncPolarity;
  359. }
  360. /*Check if the DMA state is ready */
  361. if(hdma->State == HAL_DMA_STATE_READY)
  362. {
  363. /* Process Locked */
  364. __HAL_LOCK(hdma);
  365. /* Disable the synchronization and event generation before applying a new config */
  366. CLEAR_BIT(hdma->DMAmuxChannel->CCR,(DMAMUX_CxCR_SE | DMAMUX_CxCR_EGE));
  367. /* Set the new synchronization parameters (and keep the request ID filled during the Init)*/
  368. MODIFY_REG( hdma->DMAmuxChannel->CCR, \
  369. (~DMAMUX_CxCR_DMAREQ_ID) , \
  370. (syncSignalID << DMAMUX_CxCR_SYNC_ID_Pos) | \
  371. ((pSyncConfig->RequestNumber - 1U) << DMAMUX_CxCR_NBREQ_Pos) | \
  372. syncPolarity | ((uint32_t)pSyncConfig->SyncEnable << DMAMUX_CxCR_SE_Pos) | \
  373. ((uint32_t)pSyncConfig->EventEnable << DMAMUX_CxCR_EGE_Pos));
  374. /* Process Locked */
  375. __HAL_UNLOCK(hdma);
  376. return HAL_OK;
  377. }
  378. else
  379. {
  380. /* Set the error code to busy */
  381. hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
  382. /* Return error status */
  383. return HAL_ERROR;
  384. }
  385. }
  386. /**
  387. * @brief Configure the DMAMUX request generator block used by the given DMA stream (instance).
  388. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
  389. * the configuration information for the specified DMA Stream.
  390. * @param pRequestGeneratorConfig : pointer to HAL_DMA_MuxRequestGeneratorConfigTypeDef :
  391. * contains the request generator parameters.
  392. *
  393. * @retval HAL status
  394. */
  395. HAL_StatusTypeDef HAL_DMAEx_ConfigMuxRequestGenerator (DMA_HandleTypeDef *hdma, HAL_DMA_MuxRequestGeneratorConfigTypeDef *pRequestGeneratorConfig)
  396. {
  397. HAL_StatusTypeDef status;
  398. HAL_DMA_StateTypeDef temp_state = hdma->State;
  399. /* Check the parameters */
  400. assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance));
  401. if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
  402. {
  403. assert_param(IS_DMA_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
  404. }
  405. else
  406. {
  407. assert_param(IS_BDMA_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
  408. }
  409. assert_param(IS_DMAMUX_REQUEST_GEN_POLARITY(pRequestGeneratorConfig->Polarity));
  410. assert_param(IS_DMAMUX_REQUEST_GEN_REQUEST_NUMBER(pRequestGeneratorConfig->RequestNumber));
  411. /* check if the DMA state is ready
  412. and DMA is using a DMAMUX request generator block
  413. */
  414. if(hdma->DMAmuxRequestGen == 0U)
  415. {
  416. /* Set the error code to busy */
  417. hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
  418. /* error status */
  419. status = HAL_ERROR;
  420. }
  421. else if(((hdma->DMAmuxRequestGen->RGCR & DMAMUX_RGxCR_GE) == 0U) && (temp_state == HAL_DMA_STATE_READY))
  422. {
  423. /* RequestGenerator must be disable prior to the configuration i.e GE bit is 0 */
  424. /* Process Locked */
  425. __HAL_LOCK(hdma);
  426. /* Set the request generator new parameters */
  427. hdma->DMAmuxRequestGen->RGCR = pRequestGeneratorConfig->SignalID | \
  428. ((pRequestGeneratorConfig->RequestNumber - 1U) << DMAMUX_RGxCR_GNBREQ_Pos)| \
  429. pRequestGeneratorConfig->Polarity;
  430. /* Process Locked */
  431. __HAL_UNLOCK(hdma);
  432. return HAL_OK;
  433. }
  434. else
  435. {
  436. /* Set the error code to busy */
  437. hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
  438. /* error status */
  439. status = HAL_ERROR;
  440. }
  441. return status;
  442. }
  443. /**
  444. * @brief Enable the DMAMUX request generator block used by the given DMA stream (instance).
  445. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
  446. * the configuration information for the specified DMA Stream.
  447. * @retval HAL status
  448. */
  449. HAL_StatusTypeDef HAL_DMAEx_EnableMuxRequestGenerator (DMA_HandleTypeDef *hdma)
  450. {
  451. /* Check the parameters */
  452. assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance));
  453. /* check if the DMA state is ready
  454. and DMA is using a DMAMUX request generator block */
  455. if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0U))
  456. {
  457. /* Enable the request generator*/
  458. hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_GE;
  459. return HAL_OK;
  460. }
  461. else
  462. {
  463. return HAL_ERROR;
  464. }
  465. }
  466. /**
  467. * @brief Disable the DMAMUX request generator block used by the given DMA stream (instance).
  468. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
  469. * the configuration information for the specified DMA Stream.
  470. * @retval HAL status
  471. */
  472. HAL_StatusTypeDef HAL_DMAEx_DisableMuxRequestGenerator (DMA_HandleTypeDef *hdma)
  473. {
  474. /* Check the parameters */
  475. assert_param(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance));
  476. /* check if the DMA state is ready
  477. and DMA is using a DMAMUX request generator block */
  478. if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0U))
  479. {
  480. /* Disable the request generator*/
  481. hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_GE;
  482. return HAL_OK;
  483. }
  484. else
  485. {
  486. return HAL_ERROR;
  487. }
  488. }
  489. /**
  490. * @brief Handles DMAMUX interrupt request.
  491. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
  492. * the configuration information for the specified DMA Stream.
  493. * @retval None
  494. */
  495. void HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef *hdma)
  496. {
  497. /* Check for DMAMUX Synchronization overrun */
  498. if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
  499. {
  500. /* Disable the synchro overrun interrupt */
  501. hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
  502. /* Clear the DMAMUX synchro overrun flag */
  503. hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
  504. /* Update error code */
  505. hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
  506. if(hdma->XferErrorCallback != NULL)
  507. {
  508. /* Transfer error callback */
  509. hdma->XferErrorCallback(hdma);
  510. }
  511. }
  512. if(hdma->DMAmuxRequestGen != 0)
  513. {
  514. /* if using a DMAMUX request generator block Check for DMAMUX request generator overrun */
  515. if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
  516. {
  517. /* Disable the request gen overrun interrupt */
  518. hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
  519. /* Clear the DMAMUX request generator overrun flag */
  520. hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
  521. /* Update error code */
  522. hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
  523. if(hdma->XferErrorCallback != NULL)
  524. {
  525. /* Transfer error callback */
  526. hdma->XferErrorCallback(hdma);
  527. }
  528. }
  529. }
  530. }
  531. /**
  532. * @}
  533. */
  534. /**
  535. * @}
  536. */
  537. /** @addtogroup DMAEx_Private_Functions
  538. * @{
  539. */
  540. /**
  541. * @brief Set the DMA Transfer parameter.
  542. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
  543. * the configuration information for the specified DMA Stream.
  544. * @param SrcAddress: The source memory Buffer address
  545. * @param DstAddress: The destination memory Buffer address
  546. * @param DataLength: The length of data to be transferred from source to destination
  547. * @retval HAL status
  548. */
  549. static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
  550. {
  551. if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
  552. {
  553. /* Configure DMA Stream data length */
  554. ((DMA_Stream_TypeDef *)hdma->Instance)->NDTR = DataLength;
  555. /* Peripheral to Memory */
  556. if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
  557. {
  558. /* Configure DMA Stream destination address */
  559. ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = DstAddress;
  560. /* Configure DMA Stream source address */
  561. ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = SrcAddress;
  562. }
  563. /* Memory to Peripheral */
  564. else
  565. {
  566. /* Configure DMA Stream source address */
  567. ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = SrcAddress;
  568. /* Configure DMA Stream destination address */
  569. ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = DstAddress;
  570. }
  571. }
  572. else /* BDMA instance(s) */
  573. {
  574. /* Configure DMA Stream data length */
  575. ((BDMA_Channel_TypeDef *)hdma->Instance)->CNDTR = DataLength;
  576. /* Peripheral to Memory */
  577. if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
  578. {
  579. /* Configure DMA Stream destination address */
  580. ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = DstAddress;
  581. /* Configure DMA Stream source address */
  582. ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = SrcAddress;
  583. }
  584. /* Memory to Peripheral */
  585. else
  586. {
  587. /* Configure DMA Stream source address */
  588. ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = SrcAddress;
  589. /* Configure DMA Stream destination address */
  590. ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = DstAddress;
  591. }
  592. }
  593. }
  594. /**
  595. * @}
  596. */
  597. #endif /* HAL_DMA_MODULE_ENABLED */
  598. /**
  599. * @}
  600. */
  601. /**
  602. * @}
  603. */
  604. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/