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