AnsweredAssumed Answered

DMA uart XferCpltCallback problem

Question asked by Tanaz Javanmardi on Jun 9, 2018
Latest reply on Jun 11, 2018 by T J

Hi
I use DMA in Interrupt mode to receive data from UART Periph to memory. data is transfered (my destination memory is occupied correctly)but my DMAReceiptComplete() callback function is never called.

/*--------------------------------------------------------------------------main.c------------------------------------------------------------------------*/

/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
#include <myboard_hal_bsp.h>
#include "string.h"
/* Private variables ---------------------------------------------------------*/
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart2_tx;

 


char *msg = "HI Hello STM32 Lovers! This message is transferred in DMA Mode.\r\n";
uint8_t buf[2] = "";
void DMAReceiptComplete(DMA_HandleTypeDef *hdma);

 

int main(void){
    HAL_Init();
    MyBoard_BSP_Init();

 

    //USART1
    hdma_usart1_rx.Instance = DMA1_Channel5;
    hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
    hdma_usart1_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
    hdma_usart1_rx.XferCpltCallback = &DMAReceiptComplete;

 

    HAL_DMA_Init(&hdma_usart1_rx);
    /* DMA interrupt init */
    HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
    HAL_DMA_Start_IT(&hdma_usart1_rx, (uint32_t)&huart1.Instance->DR, (uint32_t)buf, 2);
    //Enable UART in DMA mode
    huart1.Instance->CR3 |= USART_CR3_DMAR;

 

    //USART2
    hdma_usart2_tx.Instance = DMA1_Channel7;
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart2_tx.Init.MemInc = DMA_MINC_DISABLE;
    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
    HAL_DMA_Init(&hdma_usart2_tx);
    __HAL_LINKDMA(&huart2, hdmatx, hdma_usart2_tx);

 

    /* DMA interrupt init */
    HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
    /* Peripheral interrupt init */
    HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
    //Enable UART in DMA mode ( receive or transmit DMAR DMAT)
    huart2.Instance->CR3 |= USART_CR3_DMAT;
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);

 

    while(1);
     return 0;
}

 

void DMAReceiptComplete(DMA_HandleTypeDef *hdma) {
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
    if (hdma->Instance == DMA1_Channel5){ //now we should enable usart2 i think
        HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buf, 2);

 

    }
}

 

void DMA1_Channel5_IRQHandler(void){
    HAL_DMA_IRQHandler(&hdma_usart1_rx);
}

 

void USART1_IRQHandler (void){
    HAL_UART_IRQHandler(&huart1);
}

 

void DMA1_Channel7_IRQHandler(void){
    HAL_DMA_IRQHandler(&hdma_usart2_tx);
}

 

void USART2_IRQHandler (void){
    HAL_UART_IRQHandler(&huart2);
}


void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart){
    ;
}

 

Is it a bug or I made mistake somewhere?

Outcomes