Skip to main content
Graduate
January 19, 2024
Solved

HAL_DMA_Start_IT - CALL back

  • January 19, 2024
  • 2 replies
  • 6481 views

hi,

DMA setting is in NORMAL mode 

i am getting output GPIO-C Port  via tim2_up .

HAL_DMA_Start_IT(&hdma_tim2_up, (uint32_t)pixelclock, (uint32_t)&(GPIOC->ODR), 2);

it's working fine but i need to enable call back once data is  transferred  .

the following  Xfercpltcallback is ""not working "".

 

void XferCpltCallback(DMA_HandleTypeDef *hdma)

{

flag++;

}

which  call back i need to use  for DMA data transfer completion 

 

 

 

 

 

 

    This topic has been closed for replies.
    Best answer by Pierre_Paris

    Hello @MMARI.1 ,

    Can you please share your DMA configuration ?

    Here is an extract from the STM32CubeF1 FW under the root STM32Cube_FW_F1_V1.8.0\Projects\STM3210E_EVAL\Examples\DMA\DMA_FLASHToRAM :

    static void DMA_Config(void)
    {
     /*## -1- Enable DMA1 clock #################################################*/
     __HAL_RCC_DMA1_CLK_ENABLE();
    
     /*##-2- Select the DMA functional Parameters ###############################*/
     DmaHandle.Init.Direction = DMA_MEMORY_TO_MEMORY; /* M2M transfer mode */
     DmaHandle.Init.PeriphInc = DMA_PINC_ENABLE; /* Peripheral increment mode Enable */
     DmaHandle.Init.MemInc = DMA_MINC_ENABLE; /* Memory increment mode Enable */
     DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; /* Peripheral data alignment : Word */
     DmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; /* memory data alignment : Word */
     DmaHandle.Init.Mode = DMA_NORMAL; /* Normal DMA mode */
     DmaHandle.Init.Priority = DMA_PRIORITY_HIGH; /* priority level : high */
    
     /*##-3- Select the DMA instance to be used for the transfer : DMA1_Channel1 #*/
     DmaHandle.Instance = DMA_INSTANCE;
    
     /*##-4- Initialize the DMA stream ##########################################*/
     if(HAL_DMA_Init(&DmaHandle) != HAL_OK)
     {
     /* Initialization Error */
     Error_Handler(); 
     }
    
     /*##-5- Select Callbacks functions called after Transfer complete and Transfer error */
     HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_CPLT_CB_ID, TransferComplete);
     HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_ERROR_CB_ID, TransferError);
    
     /*##-6- Configure NVIC for DMA transfer complete/error interrupts ##########*/
     /* Set Interrupt Group Priority */
     HAL_NVIC_SetPriority(DMA_INSTANCE_IRQ, 0, 0);
    
     /* Enable the DMA STREAM global Interrupt */
     HAL_NVIC_EnableIRQ(DMA_INSTANCE_IRQ);
    
     /*##-7- Start the DMA transfer using the interrupt mode ####################*/
     /* Configure the source, destination and buffer size DMA fields and Start DMA Channel transfer */
     /* Enable All the DMA interrupts */
     if (HAL_DMA_Start_IT(&DmaHandle, (uint32_t)&aSRC_Const_Buffer, (uint32_t)&aDST_Buffer, BUFFER_SIZE) != HAL_OK)
     {
     /* Transfer Error */
     Error_Handler();
     }
    }

     Have you respected the 7 steps ?

    Best Regards,

    Pierre

    2 replies

    ST Employee
    January 19, 2024

    Hello @MMARI.1 ,

    Can you please share your DMA configuration ?

    Here is an extract from the STM32CubeF1 FW under the root STM32Cube_FW_F1_V1.8.0\Projects\STM3210E_EVAL\Examples\DMA\DMA_FLASHToRAM :

    static void DMA_Config(void)
    {
     /*## -1- Enable DMA1 clock #################################################*/
     __HAL_RCC_DMA1_CLK_ENABLE();
    
     /*##-2- Select the DMA functional Parameters ###############################*/
     DmaHandle.Init.Direction = DMA_MEMORY_TO_MEMORY; /* M2M transfer mode */
     DmaHandle.Init.PeriphInc = DMA_PINC_ENABLE; /* Peripheral increment mode Enable */
     DmaHandle.Init.MemInc = DMA_MINC_ENABLE; /* Memory increment mode Enable */
     DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; /* Peripheral data alignment : Word */
     DmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; /* memory data alignment : Word */
     DmaHandle.Init.Mode = DMA_NORMAL; /* Normal DMA mode */
     DmaHandle.Init.Priority = DMA_PRIORITY_HIGH; /* priority level : high */
    
     /*##-3- Select the DMA instance to be used for the transfer : DMA1_Channel1 #*/
     DmaHandle.Instance = DMA_INSTANCE;
    
     /*##-4- Initialize the DMA stream ##########################################*/
     if(HAL_DMA_Init(&DmaHandle) != HAL_OK)
     {
     /* Initialization Error */
     Error_Handler(); 
     }
    
     /*##-5- Select Callbacks functions called after Transfer complete and Transfer error */
     HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_CPLT_CB_ID, TransferComplete);
     HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_ERROR_CB_ID, TransferError);
    
     /*##-6- Configure NVIC for DMA transfer complete/error interrupts ##########*/
     /* Set Interrupt Group Priority */
     HAL_NVIC_SetPriority(DMA_INSTANCE_IRQ, 0, 0);
    
     /* Enable the DMA STREAM global Interrupt */
     HAL_NVIC_EnableIRQ(DMA_INSTANCE_IRQ);
    
     /*##-7- Start the DMA transfer using the interrupt mode ####################*/
     /* Configure the source, destination and buffer size DMA fields and Start DMA Channel transfer */
     /* Enable All the DMA interrupts */
     if (HAL_DMA_Start_IT(&DmaHandle, (uint32_t)&aSRC_Const_Buffer, (uint32_t)&aDST_Buffer, BUFFER_SIZE) != HAL_OK)
     {
     /* Transfer Error */
     Error_Handler();
     }
    }

     Have you respected the 7 steps ?

    Best Regards,

    Pierre

    MMARI.1Author
    Graduate
    January 20, 2024

     

    DMA configuration Memory to Perpheral

     

    static void MX_DMA_Init(void)

    {

     

    /* DMA controller clock enable */

    __HAL_RCC_DMA1_CLK_ENABLE();

     

    /* DMA interrupt init */

    /* DMA1_Channel2_IRQn interrupt configuration */

    HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);

     

    }

     

    void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)

    {

    if(htim_base->Instance==TIM2)

    {

    /* USER CODE BEGIN TIM2_MspInit 0 */

     

    /* USER CODE END TIM2_MspInit 0 */

    /* Peripheral clock enable */

    __HAL_RCC_TIM2_CLK_ENABLE();

     

    /* TIM2 DMA Init */

    /* TIM2_UP Init */

    hdma_tim2_up.Instance = DMA1_Channel2;

    hdma_tim2_up.Init.Direction = DMA_MEMORY_TO_PERIPH;

    hdma_tim2_up.Init.PeriphInc = DMA_PINC_DISABLE;

    hdma_tim2_up.Init.MemInc = DMA_MINC_ENABLE;

    hdma_tim2_up.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;

    hdma_tim2_up.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;

    hdma_tim2_up.Init.Mode = DMA_NORMAL;

    hdma_tim2_up.Init.Priority = DMA_PRIORITY_LOW;

    if (HAL_DMA_Init(&hdma_tim2_up) != HAL_OK)

    {

    Error_Handler();

    }

     

    __HAL_LINKDMA(htim_base,hdma[TIM_DMA_ID_UPDATE],hdma_tim2_up);

     

    /* USER CODE BEGIN TIM2_MspInit 1 */

     

    /* USER CODE END TIM2_MspInit 1 */

    }

     

    }

     

     

     

    Super User
    January 19, 2024

    hdma->XferCpltCallback gets called from HAL_DMA_IRQHandler which should be called from within the actual DMA IRQ handler. Are you doing that? It should be in your stm32fxxx_it.c file.

    MMARI.1Author
    Graduate
    January 20, 2024

     Now callback is happening via stm32fxxx_it.c ->HAL_DMA_IRQHandler

     

     

    void DMA1_Channel2_IRQHandler(void)

    {

    /* USER CODE BEGIN DMA1_Channel2_IRQn 0 */

     

    /* USER CODE END DMA1_Channel2_IRQn 0 */

    HAL_DMA_IRQHandler(&hdma_tim2_up);

    /* USER CODE BEGIN DMA1_Channel2_IRQn 1 */

    flag++;

     

    /* USER CODE END DMA1_Channel2_IRQn 1 */

    }