AnsweredAssumed Answered

DMA doesn't copy data from UART RDR

Question asked by Hicham Chaabane on Mar 27, 2018
Latest reply on Apr 4, 2018 by Hicham Chaabane



I have ported an exisiting code for a UART peripheral that uses DMA to copy the data from stm32F4 to an stm32L4


When I send a character through the UART bus, and wait for the IDLE line detection interrupt to accure, I got the following :


char received in the RDR (receive data register), but is not copied in the DMA Rx buffer that I defined previous


Here how I setup the UART


_t_DeviceHandle.Instance = USART3;
_t_DeviceHandle.Init.BaudRate = 9600;
_t_DeviceHandle.Init.WordLength = UART_WORDLENGTH_8B;
_t_DeviceHandle.Init.StopBits = UART_STOPBITS_1;
_t_DeviceHandle.Init.Parity = UART_PARITY_NONE;
_t_DeviceHandle.Init.Mode = UART_MODE_TX_RX;
_t_DeviceHandle.Init.OverSampling = UART_OVERSAMPLING_16;
_t_DeviceHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
_t_DeviceHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&_t_DeviceHandle) != HAL_OK)
_Error_Handler(__FILE__, __LINE__);
/* Configure USART interrupt */
HAL_NVIC_SetPriority(USART3_IRQn, 5, 0U);


Here is how I setup my DMA






_t_DeviceRxDmaStreamHandle.Instance = DMA1_Channel3 ;
_t_DeviceRxDmaStreamHandle.Init.Direction = DMA_PERIPH_TO_MEMORY;
_t_DeviceRxDmaStreamHandle.Init.PeriphInc = DMA_PINC_DISABLE;
_t_DeviceRxDmaStreamHandle.Init.MemInc = DMA_MINC_ENABLE;
_t_DeviceRxDmaStreamHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
_t_DeviceRxDmaStreamHandle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
_t_DeviceRxDmaStreamHandle.Init.Mode = DMA_NORMAL; 
_t_DeviceRxDmaStreamHandle.Init.Priority = DMA_PRIORITY_HIGH;
if(HAL_DMA_Init(&_t_DeviceRxDmaStreamHandle) != HAL_OK)
assert_failed((uint8_t*)__FILE__, __LINE__);

// linking DMA channel with the UART RX

  __HAL_LINKDMA(&_t_DeviceHandle, hdmarx, _t_DeviceRxDmaStreamHandle);


// defining memory address, size...etc

HAL_UART_Receive_DMA(&_t_DeviceHandle, __au8_StorageBuffer, __u16_MaxDataLength);



I checked the DMA register and they seemed correct :

CCR3->EN  = 1 // channel is enabled

CCR3->TCIE = 1 // transfert complete interrupt  is enabled

CCR3->TEIE = 1 // error interrupt enabled

CCR3->DIR = 0 // from peripheral to memory

CPAR3 has the UART RDR address

CMAR3 has the Rx buffer address.


I'm not sure what I missed here. Any suggesting on how I can debug this further ?


Thank you