stm32h7xx_hal_dma_ex.c 25 KB

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