STM32F4xx_HAL_Driver  1.8.3
stm32f4xx_hal_dma.c
Go to the documentation of this file.
1 
96 /* Includes ------------------------------------------------------------------*/
97 #include "stm32f4xx_hal.h"
98 
108 #ifdef HAL_DMA_MODULE_ENABLED
109 
110 /* Private types -------------------------------------------------------------*/
111 typedef struct
112 {
113  __IO uint32_t ISR;
114  __IO uint32_t Reserved0;
115  __IO uint32_t IFCR;
116 } DMA_Base_Registers;
117 
118 /* Private variables ---------------------------------------------------------*/
119 /* Private constants ---------------------------------------------------------*/
123  #define HAL_TIMEOUT_DMA_ABORT 5U /* 5 ms */
127 /* Private macros ------------------------------------------------------------*/
128 /* Private functions ---------------------------------------------------------*/
132 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
133 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
134 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma);
135 
140 /* Exported functions ---------------------------------------------------------*/
170 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
171 {
172  uint32_t tmp = 0U;
173  uint32_t tickstart = HAL_GetTick();
174  DMA_Base_Registers *regs;
175 
176  /* Check the DMA peripheral state */
177  if(hdma == NULL)
178  {
179  return HAL_ERROR;
180  }
181 
182  /* Check the parameters */
183  assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
184  assert_param(IS_DMA_CHANNEL(hdma->Init.Channel));
185  assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
186  assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
187  assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
188  assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
189  assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
190  assert_param(IS_DMA_MODE(hdma->Init.Mode));
191  assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
192  assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode));
193  /* Check the memory burst, peripheral burst and FIFO threshold parameters only
194  when FIFO mode is enabled */
195  if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE)
196  {
197  assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold));
198  assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst));
199  assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst));
200  }
201 
202  /* Change DMA peripheral state */
203  hdma->State = HAL_DMA_STATE_BUSY;
204 
205  /* Allocate lock resource */
206  __HAL_UNLOCK(hdma);
207 
208  /* Disable the peripheral */
209  __HAL_DMA_DISABLE(hdma);
210 
211  /* Check if the DMA Stream is effectively disabled */
212  while((hdma->Instance->CR & DMA_SxCR_EN) != RESET)
213  {
214  /* Check for the Timeout */
215  if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
216  {
217  /* Update error code */
218  hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
219 
220  /* Change the DMA state */
222 
223  return HAL_TIMEOUT;
224  }
225  }
226 
227  /* Get the CR register value */
228  tmp = hdma->Instance->CR;
229 
230  /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */
231  tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
232  DMA_SxCR_PL | DMA_SxCR_MSIZE | DMA_SxCR_PSIZE | \
233  DMA_SxCR_MINC | DMA_SxCR_PINC | DMA_SxCR_CIRC | \
234  DMA_SxCR_DIR | DMA_SxCR_CT | DMA_SxCR_DBM));
235 
236  /* Prepare the DMA Stream configuration */
237  tmp |= hdma->Init.Channel | hdma->Init.Direction |
238  hdma->Init.PeriphInc | hdma->Init.MemInc |
239  hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
240  hdma->Init.Mode | hdma->Init.Priority;
241 
242  /* the Memory burst and peripheral burst are not used when the FIFO is disabled */
243  if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
244  {
245  /* Get memory burst and peripheral burst */
246  tmp |= hdma->Init.MemBurst | hdma->Init.PeriphBurst;
247  }
248 
249  /* Write to DMA Stream CR register */
250  hdma->Instance->CR = tmp;
251 
252  /* Get the FCR register value */
253  tmp = hdma->Instance->FCR;
254 
255  /* Clear Direct mode and FIFO threshold bits */
256  tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
257 
258  /* Prepare the DMA Stream FIFO configuration */
259  tmp |= hdma->Init.FIFOMode;
260 
261  /* The FIFO threshold is not used when the FIFO mode is disabled */
262  if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
263  {
264  /* Get the FIFO threshold */
265  tmp |= hdma->Init.FIFOThreshold;
266 
267  /* Check compatibility between FIFO threshold level and size of the memory burst */
268  /* for INCR4, INCR8, INCR16 bursts */
269  if (hdma->Init.MemBurst != DMA_MBURST_SINGLE)
270  {
271  if (DMA_CheckFifoParam(hdma) != HAL_OK)
272  {
273  /* Update error code */
274  hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
275 
276  /* Change the DMA state */
277  hdma->State = HAL_DMA_STATE_READY;
278 
279  return HAL_ERROR;
280  }
281  }
282  }
283 
284  /* Write to DMA Stream FCR */
285  hdma->Instance->FCR = tmp;
286 
287  /* Initialize StreamBaseAddress and StreamIndex parameters to be used to calculate
288  DMA steam Base Address needed by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */
289  regs = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
290 
291  /* Clear all interrupt flags */
292  regs->IFCR = 0x3FU << hdma->StreamIndex;
293 
294  /* Initialize the error code */
295  hdma->ErrorCode = HAL_DMA_ERROR_NONE;
296 
297  /* Initialize the DMA state */
298  hdma->State = HAL_DMA_STATE_READY;
299 
300  return HAL_OK;
301 }
302 
309 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
310 {
311  DMA_Base_Registers *regs;
312 
313  /* Check the DMA peripheral state */
314  if(hdma == NULL)
315  {
316  return HAL_ERROR;
317  }
318 
319  /* Check the DMA peripheral state */
320  if(hdma->State == HAL_DMA_STATE_BUSY)
321  {
322  /* Return error status */
323  return HAL_BUSY;
324  }
325 
326  /* Check the parameters */
327  assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
328 
329  /* Disable the selected DMA Streamx */
330  __HAL_DMA_DISABLE(hdma);
331 
332  /* Reset DMA Streamx control register */
333  hdma->Instance->CR = 0U;
334 
335  /* Reset DMA Streamx number of data to transfer register */
336  hdma->Instance->NDTR = 0U;
337 
338  /* Reset DMA Streamx peripheral address register */
339  hdma->Instance->PAR = 0U;
340 
341  /* Reset DMA Streamx memory 0 address register */
342  hdma->Instance->M0AR = 0U;
343 
344  /* Reset DMA Streamx memory 1 address register */
345  hdma->Instance->M1AR = 0U;
346 
347  /* Reset DMA Streamx FIFO control register */
348  hdma->Instance->FCR = 0x00000021U;
349 
350  /* Get DMA steam Base Address */
351  regs = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
352 
353  /* Clean all callbacks */
354  hdma->XferCpltCallback = NULL;
355  hdma->XferHalfCpltCallback = NULL;
356  hdma->XferM1CpltCallback = NULL;
357  hdma->XferM1HalfCpltCallback = NULL;
358  hdma->XferErrorCallback = NULL;
359  hdma->XferAbortCallback = NULL;
360 
361  /* Clear all interrupt flags at correct offset within the register */
362  regs->IFCR = 0x3FU << hdma->StreamIndex;
363 
364  /* Reset the error code */
365  hdma->ErrorCode = HAL_DMA_ERROR_NONE;
366 
367  /* Reset the DMA state */
368  hdma->State = HAL_DMA_STATE_RESET;
369 
370  /* Release Lock */
371  __HAL_UNLOCK(hdma);
372 
373  return HAL_OK;
374 }
375 
407 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
408 {
409  HAL_StatusTypeDef status = HAL_OK;
410 
411  /* Check the parameters */
412  assert_param(IS_DMA_BUFFER_SIZE(DataLength));
413 
414  /* Process locked */
415  __HAL_LOCK(hdma);
416 
417  if(HAL_DMA_STATE_READY == hdma->State)
418  {
419  /* Change DMA peripheral state */
420  hdma->State = HAL_DMA_STATE_BUSY;
421 
422  /* Initialize the error code */
423  hdma->ErrorCode = HAL_DMA_ERROR_NONE;
424 
425  /* Configure the source, destination address and the data length */
426  DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
427 
428  /* Enable the Peripheral */
429  __HAL_DMA_ENABLE(hdma);
430  }
431  else
432  {
433  /* Process unlocked */
434  __HAL_UNLOCK(hdma);
435 
436  /* Return error status */
437  status = HAL_BUSY;
438  }
439  return status;
440 }
441 
451 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
452 {
453  HAL_StatusTypeDef status = HAL_OK;
454 
455  /* calculate DMA base and stream number */
456  DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
457 
458  /* Check the parameters */
459  assert_param(IS_DMA_BUFFER_SIZE(DataLength));
460 
461  /* Process locked */
462  __HAL_LOCK(hdma);
463 
464  if(HAL_DMA_STATE_READY == hdma->State)
465  {
466  /* Change DMA peripheral state */
467  hdma->State = HAL_DMA_STATE_BUSY;
468 
469  /* Initialize the error code */
470  hdma->ErrorCode = HAL_DMA_ERROR_NONE;
471 
472  /* Configure the source, destination address and the data length */
473  DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
474 
475  /* Clear all interrupt flags at correct offset within the register */
476  regs->IFCR = 0x3FU << hdma->StreamIndex;
477 
478  /* Enable Common interrupts*/
479  hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
480 
481  if(hdma->XferHalfCpltCallback != NULL)
482  {
483  hdma->Instance->CR |= DMA_IT_HT;
484  }
485 
486  /* Enable the Peripheral */
487  __HAL_DMA_ENABLE(hdma);
488  }
489  else
490  {
491  /* Process unlocked */
492  __HAL_UNLOCK(hdma);
493 
494  /* Return error status */
495  status = HAL_BUSY;
496  }
497 
498  return status;
499 }
500 
513 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
514 {
515  /* calculate DMA base and stream number */
516  DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
517 
518  uint32_t tickstart = HAL_GetTick();
519 
520  if(hdma->State != HAL_DMA_STATE_BUSY)
521  {
522  hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
523 
524  /* Process Unlocked */
525  __HAL_UNLOCK(hdma);
526 
527  return HAL_ERROR;
528  }
529  else
530  {
531  /* Disable all the transfer interrupts */
532  hdma->Instance->CR &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
533  hdma->Instance->FCR &= ~(DMA_IT_FE);
534 
535  if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
536  {
537  hdma->Instance->CR &= ~(DMA_IT_HT);
538  }
539 
540  /* Disable the stream */
541  __HAL_DMA_DISABLE(hdma);
542 
543  /* Check if the DMA Stream is effectively disabled */
544  while((hdma->Instance->CR & DMA_SxCR_EN) != RESET)
545  {
546  /* Check for the Timeout */
547  if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
548  {
549  /* Update error code */
550  hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
551 
552  /* Change the DMA state */
554 
555  /* Process Unlocked */
556  __HAL_UNLOCK(hdma);
557 
558  return HAL_TIMEOUT;
559  }
560  }
561 
562  /* Clear all interrupt flags at correct offset within the register */
563  regs->IFCR = 0x3FU << hdma->StreamIndex;
564 
565  /* Change the DMA state*/
566  hdma->State = HAL_DMA_STATE_READY;
567 
568  /* Process Unlocked */
569  __HAL_UNLOCK(hdma);
570  }
571  return HAL_OK;
572 }
573 
580 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
581 {
582  if(hdma->State != HAL_DMA_STATE_BUSY)
583  {
584  hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
585  return HAL_ERROR;
586  }
587  else
588  {
589  /* Set Abort State */
590  hdma->State = HAL_DMA_STATE_ABORT;
591 
592  /* Disable the stream */
593  __HAL_DMA_DISABLE(hdma);
594  }
595 
596  return HAL_OK;
597 }
598 
610 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
611 {
612  HAL_StatusTypeDef status = HAL_OK;
613  uint32_t mask_cpltlevel;
614  uint32_t tickstart = HAL_GetTick();
615  uint32_t tmpisr;
616 
617  /* calculate DMA base and stream number */
618  DMA_Base_Registers *regs;
619 
620  if(HAL_DMA_STATE_BUSY != hdma->State)
621  {
622  /* No transfer ongoing */
623  hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
624  __HAL_UNLOCK(hdma);
625  return HAL_ERROR;
626  }
627 
628  /* Polling mode not supported in circular mode and double buffering mode */
629  if ((hdma->Instance->CR & DMA_SxCR_CIRC) != RESET)
630  {
631  hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
632  return HAL_ERROR;
633  }
634 
635  /* Get the level transfer complete flag */
636  if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
637  {
638  /* Transfer Complete flag */
639  mask_cpltlevel = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;
640  }
641  else
642  {
643  /* Half Transfer Complete flag */
644  mask_cpltlevel = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
645  }
646 
647  regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
648  tmpisr = regs->ISR;
649 
650  while(((tmpisr & mask_cpltlevel) == RESET) && ((hdma->ErrorCode & HAL_DMA_ERROR_TE) == RESET))
651  {
652  /* Check for the Timeout (Not applicable in circular mode)*/
653  if(Timeout != HAL_MAX_DELAY)
654  {
655  if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
656  {
657  /* Update error code */
658  hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
659 
660  /* Change the DMA state */
661  hdma->State = HAL_DMA_STATE_READY;
662 
663  /* Process Unlocked */
664  __HAL_UNLOCK(hdma);
665 
666  return HAL_TIMEOUT;
667  }
668  }
669 
670  /* Get the ISR register value */
671  tmpisr = regs->ISR;
672 
673  if((tmpisr & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET)
674  {
675  /* Update error code */
676  hdma->ErrorCode |= HAL_DMA_ERROR_TE;
677 
678  /* Clear the transfer error flag */
679  regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex;
680  }
681 
682  if((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
683  {
684  /* Update error code */
685  hdma->ErrorCode |= HAL_DMA_ERROR_FE;
686 
687  /* Clear the FIFO error flag */
688  regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;
689  }
690 
691  if((tmpisr & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET)
692  {
693  /* Update error code */
694  hdma->ErrorCode |= HAL_DMA_ERROR_DME;
695 
696  /* Clear the Direct Mode error flag */
697  regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex;
698  }
699  }
700 
701  if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
702  {
703  if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != RESET)
704  {
705  HAL_DMA_Abort(hdma);
706 
707  /* Clear the half transfer and transfer complete flags */
708  regs->IFCR = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << hdma->StreamIndex;
709 
710  /* Change the DMA state */
711  hdma->State= HAL_DMA_STATE_READY;
712 
713  /* Process Unlocked */
714  __HAL_UNLOCK(hdma);
715 
716  return HAL_ERROR;
717  }
718  }
719 
720  /* Get the level transfer complete flag */
721  if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
722  {
723  /* Clear the half transfer and transfer complete flags */
724  regs->IFCR = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << hdma->StreamIndex;
725 
726  hdma->State = HAL_DMA_STATE_READY;
727 
728  /* Process Unlocked */
729  __HAL_UNLOCK(hdma);
730  }
731  else
732  {
733  /* Clear the half transfer and transfer complete flags */
734  regs->IFCR = (DMA_FLAG_HTIF0_4) << hdma->StreamIndex;
735  }
736 
737  return status;
738 }
739 
747 {
748  uint32_t tmpisr;
749  __IO uint32_t count = 0U;
750  uint32_t timeout = SystemCoreClock / 9600U;
751 
752  /* calculate DMA base and stream number */
753  DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
754 
755  tmpisr = regs->ISR;
756 
757  /* Transfer Error Interrupt management ***************************************/
758  if ((tmpisr & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET)
759  {
760  if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
761  {
762  /* Disable the transfer error interrupt */
763  hdma->Instance->CR &= ~(DMA_IT_TE);
764 
765  /* Clear the transfer error flag */
766  regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex;
767 
768  /* Update error code */
769  hdma->ErrorCode |= HAL_DMA_ERROR_TE;
770  }
771  }
772  /* FIFO Error Interrupt management ******************************************/
773  if ((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
774  {
775  if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
776  {
777  /* Clear the FIFO error flag */
778  regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;
779 
780  /* Update error code */
781  hdma->ErrorCode |= HAL_DMA_ERROR_FE;
782  }
783  }
784  /* Direct Mode Error Interrupt management ***********************************/
785  if ((tmpisr & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET)
786  {
787  if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
788  {
789  /* Clear the direct mode error flag */
790  regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex;
791 
792  /* Update error code */
793  hdma->ErrorCode |= HAL_DMA_ERROR_DME;
794  }
795  }
796  /* Half Transfer Complete Interrupt management ******************************/
797  if ((tmpisr & (DMA_FLAG_HTIF0_4 << hdma->StreamIndex)) != RESET)
798  {
799  if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
800  {
801  /* Clear the half transfer complete flag */
802  regs->IFCR = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
803 
804  /* Multi_Buffering mode enabled */
805  if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET)
806  {
807  /* Current memory buffer used is Memory 0 */
808  if((hdma->Instance->CR & DMA_SxCR_CT) == RESET)
809  {
810  if(hdma->XferHalfCpltCallback != NULL)
811  {
812  /* Half transfer callback */
813  hdma->XferHalfCpltCallback(hdma);
814  }
815  }
816  /* Current memory buffer used is Memory 1 */
817  else
818  {
819  if(hdma->XferM1HalfCpltCallback != NULL)
820  {
821  /* Half transfer callback */
822  hdma->XferM1HalfCpltCallback(hdma);
823  }
824  }
825  }
826  else
827  {
828  /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
829  if((hdma->Instance->CR & DMA_SxCR_CIRC) == RESET)
830  {
831  /* Disable the half transfer interrupt */
832  hdma->Instance->CR &= ~(DMA_IT_HT);
833  }
834 
835  if(hdma->XferHalfCpltCallback != NULL)
836  {
837  /* Half transfer callback */
838  hdma->XferHalfCpltCallback(hdma);
839  }
840  }
841  }
842  }
843  /* Transfer Complete Interrupt management ***********************************/
844  if ((tmpisr & (DMA_FLAG_TCIF0_4 << hdma->StreamIndex)) != RESET)
845  {
846  if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
847  {
848  /* Clear the transfer complete flag */
849  regs->IFCR = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;
850 
851  if(HAL_DMA_STATE_ABORT == hdma->State)
852  {
853  /* Disable all the transfer interrupts */
854  hdma->Instance->CR &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
855  hdma->Instance->FCR &= ~(DMA_IT_FE);
856 
857  if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
858  {
859  hdma->Instance->CR &= ~(DMA_IT_HT);
860  }
861 
862  /* Clear all interrupt flags at correct offset within the register */
863  regs->IFCR = 0x3FU << hdma->StreamIndex;
864 
865  /* Change the DMA state */
866  hdma->State = HAL_DMA_STATE_READY;
867 
868  /* Process Unlocked */
869  __HAL_UNLOCK(hdma);
870 
871  if(hdma->XferAbortCallback != NULL)
872  {
873  hdma->XferAbortCallback(hdma);
874  }
875  return;
876  }
877 
878  if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET)
879  {
880  /* Current memory buffer used is Memory 0 */
881  if((hdma->Instance->CR & DMA_SxCR_CT) == RESET)
882  {
883  if(hdma->XferM1CpltCallback != NULL)
884  {
885  /* Transfer complete Callback for memory1 */
886  hdma->XferM1CpltCallback(hdma);
887  }
888  }
889  /* Current memory buffer used is Memory 1 */
890  else
891  {
892  if(hdma->XferCpltCallback != NULL)
893  {
894  /* Transfer complete Callback for memory0 */
895  hdma->XferCpltCallback(hdma);
896  }
897  }
898  }
899  /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
900  else
901  {
902  if((hdma->Instance->CR & DMA_SxCR_CIRC) == RESET)
903  {
904  /* Disable the transfer complete interrupt */
905  hdma->Instance->CR &= ~(DMA_IT_TC);
906 
907  /* Change the DMA state */
908  hdma->State = HAL_DMA_STATE_READY;
909 
910  /* Process Unlocked */
911  __HAL_UNLOCK(hdma);
912  }
913 
914  if(hdma->XferCpltCallback != NULL)
915  {
916  /* Transfer complete callback */
917  hdma->XferCpltCallback(hdma);
918  }
919  }
920  }
921  }
922 
923  /* manage error case */
924  if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
925  {
926  if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != RESET)
927  {
928  hdma->State = HAL_DMA_STATE_ABORT;
929 
930  /* Disable the stream */
931  __HAL_DMA_DISABLE(hdma);
932 
933  do
934  {
935  if (++count > timeout)
936  {
937  break;
938  }
939  }
940  while((hdma->Instance->CR & DMA_SxCR_EN) != RESET);
941 
942  /* Change the DMA state */
943  hdma->State = HAL_DMA_STATE_READY;
944 
945  /* Process Unlocked */
946  __HAL_UNLOCK(hdma);
947  }
948 
949  if(hdma->XferErrorCallback != NULL)
950  {
951  /* Transfer error callback */
952  hdma->XferErrorCallback(hdma);
953  }
954  }
955 }
956 
967 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)(DMA_HandleTypeDef *_hdma))
968 {
969 
970  HAL_StatusTypeDef status = HAL_OK;
971 
972  /* Process locked */
973  __HAL_LOCK(hdma);
974 
975  if(HAL_DMA_STATE_READY == hdma->State)
976  {
977  switch (CallbackID)
978  {
980  hdma->XferCpltCallback = pCallback;
981  break;
982 
984  hdma->XferHalfCpltCallback = pCallback;
985  break;
986 
988  hdma->XferM1CpltCallback = pCallback;
989  break;
990 
992  hdma->XferM1HalfCpltCallback = pCallback;
993  break;
994 
996  hdma->XferErrorCallback = pCallback;
997  break;
998 
1000  hdma->XferAbortCallback = pCallback;
1001  break;
1002 
1003  default:
1004  /* Return error status */
1005  status = HAL_ERROR;
1006  break;
1007  }
1008  }
1009  else
1010  {
1011  /* Return error status */
1012  status = HAL_ERROR;
1013  }
1014 
1015  /* Release Lock */
1016  __HAL_UNLOCK(hdma);
1017 
1018  return status;
1019 }
1020 
1030 {
1031  HAL_StatusTypeDef status = HAL_OK;
1032 
1033  /* Process locked */
1034  __HAL_LOCK(hdma);
1035 
1036  if(HAL_DMA_STATE_READY == hdma->State)
1037  {
1038  switch (CallbackID)
1039  {
1041  hdma->XferCpltCallback = NULL;
1042  break;
1043 
1045  hdma->XferHalfCpltCallback = NULL;
1046  break;
1047 
1049  hdma->XferM1CpltCallback = NULL;
1050  break;
1051 
1053  hdma->XferM1HalfCpltCallback = NULL;
1054  break;
1055 
1057  hdma->XferErrorCallback = NULL;
1058  break;
1059 
1061  hdma->XferAbortCallback = NULL;
1062  break;
1063 
1065  hdma->XferCpltCallback = NULL;
1066  hdma->XferHalfCpltCallback = NULL;
1067  hdma->XferM1CpltCallback = NULL;
1068  hdma->XferM1HalfCpltCallback = NULL;
1069  hdma->XferErrorCallback = NULL;
1070  hdma->XferAbortCallback = NULL;
1071  break;
1072 
1073  default:
1074  status = HAL_ERROR;
1075  break;
1076  }
1077  }
1078  else
1079  {
1080  status = HAL_ERROR;
1081  }
1082 
1083  /* Release Lock */
1084  __HAL_UNLOCK(hdma);
1085 
1086  return status;
1087 }
1088 
1115 {
1116  return hdma->State;
1117 }
1118 
1126 {
1127  return hdma->ErrorCode;
1128 }
1129 
1151 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
1152 {
1153  /* Clear DBM bit */
1154  hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);
1155 
1156  /* Configure DMA Stream data length */
1157  hdma->Instance->NDTR = DataLength;
1158 
1159  /* Memory to Peripheral */
1160  if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1161  {
1162  /* Configure DMA Stream destination address */
1163  hdma->Instance->PAR = DstAddress;
1164 
1165  /* Configure DMA Stream source address */
1166  hdma->Instance->M0AR = SrcAddress;
1167  }
1168  /* Peripheral to Memory */
1169  else
1170  {
1171  /* Configure DMA Stream source address */
1172  hdma->Instance->PAR = SrcAddress;
1173 
1174  /* Configure DMA Stream destination address */
1175  hdma->Instance->M0AR = DstAddress;
1176  }
1177 }
1178 
1185 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
1186 {
1187  uint32_t stream_number = (((uint32_t)hdma->Instance & 0xFFU) - 16U) / 24U;
1188 
1189  /* lookup table for necessary bitshift of flags within status registers */
1190  static const uint8_t flagBitshiftOffset[8U] = {0U, 6U, 16U, 22U, 0U, 6U, 16U, 22U};
1191  hdma->StreamIndex = flagBitshiftOffset[stream_number];
1192 
1193  if (stream_number > 3U)
1194  {
1195  /* return pointer to HISR and HIFCR */
1196  hdma->StreamBaseAddress = (((uint32_t)hdma->Instance & (uint32_t)(~0x3FFU)) + 4U);
1197  }
1198  else
1199  {
1200  /* return pointer to LISR and LIFCR */
1201  hdma->StreamBaseAddress = ((uint32_t)hdma->Instance & (uint32_t)(~0x3FFU));
1202  }
1203 
1204  return hdma->StreamBaseAddress;
1205 }
1206 
1213 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma)
1214 {
1215  HAL_StatusTypeDef status = HAL_OK;
1216  uint32_t tmp = hdma->Init.FIFOThreshold;
1217 
1218  /* Memory Data size equal to Byte */
1219  if(hdma->Init.MemDataAlignment == DMA_MDATAALIGN_BYTE)
1220  {
1221  switch (tmp)
1222  {
1223  case DMA_FIFO_THRESHOLD_1QUARTERFULL:
1224  case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
1225  if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
1226  {
1227  status = HAL_ERROR;
1228  }
1229  break;
1230  case DMA_FIFO_THRESHOLD_HALFFULL:
1231  if (hdma->Init.MemBurst == DMA_MBURST_INC16)
1232  {
1233  status = HAL_ERROR;
1234  }
1235  break;
1236  case DMA_FIFO_THRESHOLD_FULL:
1237  break;
1238  default:
1239  break;
1240  }
1241  }
1242 
1243  /* Memory Data size equal to Half-Word */
1244  else if (hdma->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
1245  {
1246  switch (tmp)
1247  {
1248  case DMA_FIFO_THRESHOLD_1QUARTERFULL:
1249  case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
1250  status = HAL_ERROR;
1251  break;
1252  case DMA_FIFO_THRESHOLD_HALFFULL:
1253  if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
1254  {
1255  status = HAL_ERROR;
1256  }
1257  break;
1258  case DMA_FIFO_THRESHOLD_FULL:
1259  if (hdma->Init.MemBurst == DMA_MBURST_INC16)
1260  {
1261  status = HAL_ERROR;
1262  }
1263  break;
1264  default:
1265  break;
1266  }
1267  }
1268 
1269  /* Memory Data size equal to Word */
1270  else
1271  {
1272  switch (tmp)
1273  {
1274  case DMA_FIFO_THRESHOLD_1QUARTERFULL:
1275  case DMA_FIFO_THRESHOLD_HALFFULL:
1276  case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
1277  status = HAL_ERROR;
1278  break;
1279  case DMA_FIFO_THRESHOLD_FULL:
1280  if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
1281  {
1282  status = HAL_ERROR;
1283  }
1284  break;
1285  default:
1286  break;
1287  }
1288  }
1289 
1290  return status;
1291 }
1292 
1297 #endif /* HAL_DMA_MODULE_ENABLED */
HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
Initialize the DMA according to the specified parameters in the DMA_InitTypeDef and create the associ...
HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
DeInitializes the DMA peripheral.
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
Aborts the DMA Transfer.
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
Aborts the DMA Transfer in Interrupt mode.
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
Start the DMA Transfer with interrupt enabled.
HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
UnRegister callbacks.
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
Handles DMA interrupt request.
HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
Starts the DMA Transfer.
HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
Polling for transfer complete.
HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void(*pCallback)(DMA_HandleTypeDef *_hdma))
Register callbacks.
uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
Return the DMA error code.
HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
Returns the DMA state.
uint32_t HAL_GetTick(void)
Provides a tick value in millisecond.
This file contains all the functions prototypes for the HAL module driver.
HAL_DMA_StateTypeDef
HAL DMA State structures definition.
@ HAL_DMA_STATE_RESET
@ HAL_DMA_STATE_TIMEOUT
@ HAL_DMA_STATE_READY
@ HAL_DMA_STATE_ABORT
@ HAL_DMA_STATE_BUSY
HAL_DMA_LevelCompleteTypeDef
HAL DMA Error Code structure definition.
@ HAL_DMA_FULL_TRANSFER
HAL_DMA_CallbackIDTypeDef
HAL DMA Error Code structure definition.
@ HAL_DMA_XFER_M1CPLT_CB_ID
@ HAL_DMA_XFER_ABORT_CB_ID
@ HAL_DMA_XFER_ERROR_CB_ID
@ HAL_DMA_XFER_HALFCPLT_CB_ID
@ HAL_DMA_XFER_CPLT_CB_ID
@ HAL_DMA_XFER_M1HALFCPLT_CB_ID
@ HAL_DMA_XFER_ALL_CB_ID
DMA handle Structure definition.
void(* XferAbortCallback)(struct __DMA_HandleTypeDef *hdma)
DMA_InitTypeDef Init
void(* XferCpltCallback)(struct __DMA_HandleTypeDef *hdma)
void(* XferErrorCallback)(struct __DMA_HandleTypeDef *hdma)
__IO HAL_DMA_StateTypeDef State
void(* XferHalfCpltCallback)(struct __DMA_HandleTypeDef *hdma)
DMA_Stream_TypeDef * Instance
void(* XferM1HalfCpltCallback)(struct __DMA_HandleTypeDef *hdma)
void(* XferM1CpltCallback)(struct __DMA_HandleTypeDef *hdma)