Skip to main content
Hicham Chaabane
Associate II
March 27, 2018
Solved

DMA doesn't copy data from UART RDR

  • March 27, 2018
  • 7 replies
  • 1733 views
Posted on March 27, 2018 at 12:55

Hello,

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_

Device

Handle.Init.BaudRate = 9600;

_t_

Device

Handle.Init.WordLength = UART_WORDLENGTH_8B;

_t_

Device

Handle.Init.StopBits = UART_STOPBITS_1;

_t_

Device

Handle.Init.Parity = UART_PARITY_NONE;

_t_

Device

Handle.Init.Mode = UART_MODE_TX_RX;

_t_

Device

Handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;// UART_HWCONTROL_RTS_CTS;

_t_

Device

Handle.Init.OverSampling = UART_OVERSAMPLING_16;

_t_

Device

Handle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

_t_

Device

Handle.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);

HAL_NVIC_EnableIRQ(USART3_IRQn);

}

Here is how I setup my DMA

  __HAL_RCC_DMA1_CLK_ENABLE();

_t_DeviceRxDmaStreamHandle.Instance =

DMA1_Channel3

;

_t_

Device

RxDmaStreamHandle.Init.Direction = DMA_PERIPH_TO_MEMORY;

_t_

Device

RxDmaStreamHandle.Init.PeriphInc = DMA_PINC_DISABLE;

_t_

Device

RxDmaStreamHandle.Init.MemInc = DMA_MINC_ENABLE;

_t_

Device

RxDmaStreamHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

_t_

Device

RxDmaStreamHandle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

_t_

Device

RxDmaStreamHandle.Init.Mode = DMA_NORMAL; 

_t_

Device

RxDmaStreamHandle.Init.Priority = DMA_PRIORITY_HIGH;

if(HAL_DMA_Init(&_t_

Device

RxDmaStreamHandle) != HAL_OK)

{

assert_failed((uint8_t*)__FILE__, __LINE__);

}

// linking DMA channel with the UART RX

  __HAL_LINKDMA(&_t_

Device

Handle, hdmarx, _t_

Device

RxDmaStreamHandle);

// defining memory address, size...etc

HAL_UART_Receive_DMA(&_t_

Device

Handle, __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

regards

#dma #stm32l4 #hal #uart
This topic has been closed for replies.
Best answer by waclawek.jan
Posted on March 29, 2018 at 10:58

Looking at Cube's sources it appears you are supposed to fill the required setting of CSELR into .Request field of the init struct.

JW

7 replies

Tilen MAJERLE
ST Employee
March 27, 2018
Posted on March 27, 2018 at 13:38

Hello

c.malki

‌

which channel and stream setup do you use?

Best regards,

Tilen

Hicham Chaabane
Associate II
March 27, 2018
Posted on March 27, 2018 at 14:02

Hi Tilen,

Sorry I forget to mention that.

I use 

DMA1_Channel3 for Rx and DMA1_Channel2 for Tx. and STM32L475

I added them in my post

waclawek.jan
Super User
March 27, 2018
Posted on March 27, 2018 at 23:34

And the respective field in DMA_CSELR is set properly?

JW

Hicham Chaabane
Associate II
March 29, 2018
Posted on March 29, 2018 at 10:38

The CSELR register is set to 0 which is not good !

Based on the manual, the bits 11:8 should be set to 0010 to map the DMA to USART3_RX.

I'm trying to figure it out but the only place where the DMA_CSELR is set is in the HAL_DMA_Init()

/* Reset request selection for DMA1 Channelx */

DMA1_CSELR->CSELR &= ~(DMA_CSELR_C1S << hdma->ChannelIndex);

/* Configure request selection for DMA1 Channelx */

DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << (hdma->ChannelIndex));

looking into this function, it seems that that both variables Init.Request and hdma->ChannelIndex are set inside the DMA init function aswell !

Any idea how to set this properly ?

Thx