cancel
Showing results for 
Search instead for 
Did you mean: 

When reading USART, DMA instantaneously completes

Misha K
Associate III
Posted on May 15, 2018 at 13:48

Please see code below.

I'm trying to read from USART using DMA. 

Please see the last line DMA1_Channel3->CCR |= DMA_CCR_EN;

When I step over that line, 

CNDTR instantaneously resets to zero like it has finished reading, also destination buffer is populated by multiple instances of the same char that was in USART1->RDR.

It looks like DMA believes that the same char is constantly arriving into RDR and available for transfer.

I don't expect any actual USART transmission at that time.

What am I doing wrong please?

void ScheduleUsartDmaRead(){

USART1->CR1 &= ~USART_CR1_TE;

USART1->CR1 |= USART_CR1_RE;

USART1->CR1 |= USART_CR1_UE; // enable usart

DMA1_Channel3->CCR &= ~DMA_CCR_EN; // disable DMA to set registers

DMA1_Channel3->CCR &= ~DMA_CCR_DIR; // peripheral to memory

DMA1->IFCR = DMA_FLAG_GL3; // clear flags

DMA1_Channel3->CNDTR = usartBufferSize; // set buffer size

DMA1_Channel3->CPAR = (uint32_t)(&(USART1->RDR)); // USART register address

DMA1_Channel3->CMAR = (uint32_t)(usartInBuffer); // memory address

DMA1_Channel3->CCR |= DMA_CCR_EN; // start DMA

}
1 ACCEPTED SOLUTION

Accepted Solutions
Misha K
Associate III
Posted on May 15, 2018 at 15:20

Answering my own question.

I used same DMA channel for USART and SPI.

I was thinking that when processing USART it was enough to disable SPI and point DMA->

CPAR to USART register.

Surprisingly just disabling SPI is not enough, I also had to clear its RXDMAEN and TXDMAEN flags.

View solution in original post

2 REPLIES 2
Posted on May 15, 2018 at 14:47

What STM32 part is being used here?

Not looking to dig into others register level code, try using the HAL/LL until you have it working

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Misha K
Associate III
Posted on May 15, 2018 at 15:20

Answering my own question.

I used same DMA channel for USART and SPI.

I was thinking that when processing USART it was enough to disable SPI and point DMA->

CPAR to USART register.

Surprisingly just disabling SPI is not enough, I also had to clear its RXDMAEN and TXDMAEN flags.