Skip to main content
h2_it
Associate
May 6, 2014
Question

DMA reads from USART1 without RXNE set

  • May 6, 2014
  • 16 replies
  • 3269 views
Posted on May 06, 2014 at 12:11

Hi community,

I use the USART1 in STM32F100C4 to receive serial data in DMA mode. Because the data comes in packets with less than 16 bytes I start the DMA mode every time, when new data is expected. This works most of the time well.

But in some cases, DMA is not new started, because data is not of interest and DMA reads only 16 bytes to the memory. then DMA stops the transfer.

Next time data is expected, DMA is new started in the same manner like before:

  DMA_Cmd(DMAChannel_USART1_RX, DISABLE);

  DMAChannel_USART1_RX->CNDTR = 16;

  DMA_Cmd(DMAChannel_USART1_RX, ENABLE);

But now immediatly after DMA is enabled, the last data in USART1_DR is read to the memory althougt RXNE is cleared!

It seems, this undesirable data is only read after DMAChannel_USART1_RX->CNDTR has count to 0 in last DMA session and more data is unread received.

A resolution to that problem is allmost when I restart DMA mode like above. But I prefer to know the reason for this problem rather I solve it in this kind.

Thanks for your help,

Best reards,

Herbert

#usart1-dma-rx
This topic has been closed for replies.

16 replies

h2_it
h2_itAuthor
Associate
May 12, 2014
Posted on May 12, 2014 at 11:49

Hello Jan,

yes, your error appeares with timer in DMA mode but is comparibel. A. Paiva but has exactly the same problem then I had.

Like you said, it seems, that the DMA controller saves the event in an internal latch and this can't be cleared with disable of DMA.

I have tried some work around without success before this solution:

USART_DMAReq_Rx is disabled after each receive of a string. And then before awaiting a new string:

  USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);    // Enable  usart1 DMA Rx request

  DMA_Cmd(DMAChannel_USART1_RX, DISABLE);

  DMAChannel_USART1_RX->CNDTR = RXBUFFSIZEU1;       // refresh DMA counter

  DMA_Cmd(DMAChannel_USART1_RX, ENABLE);

 

  USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);    // Enable  usart1 DMA Tx request

This solution works!

I have also reported the problem to ST support like you, but I made a greater mistake then you: < 1000 pcs ... I await a answer until now ;-).

Greetings

Herbert

waclawek.jan
Super User
May 12, 2014
Posted on May 12, 2014 at 12:19

I assume you have enabled DMA before the snippet you posted (as you disable it explicitly in the 2nd line). So, in case there is a ''hanging'' DMA ''trigger'', it will perform the extra one transfer before you disable and re-initialize it again, isn't it?

JW

h2_it
h2_itAuthor
Associate
May 12, 2014
Posted on May 12, 2014 at 15:55

Sorry Jan,

I forgot, before the snippet i send:

  USART1->CR1 |= USART_CR1_UE | USART_CR1_RE | USART_CR1_TE; // USART1 freigeben (RX, TX und UE)

and after receiving of the answers:

  DMA_Cmd(DMAChannel_USART1_RX, DISABLE);           // DMA-Transfer Empfang stoppen

  DMA_Cmd(DMAChannel_USART1_TX, DISABLE);           // DMA-Transfer Senden stoppen

With this configuration no undesirable characters land in my buffer.

Greetings

Herbert

waclawek.jan
Super User
May 12, 2014
Posted on May 12, 2014 at 17:44

I made a couple of experiments, results summed up in the above [DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/AllItems.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/How%20to%20clear%20pending%20DMA%20request]thread.

I don't know whether (and if so, how) it is pertinent to the case of USART.

JW

h2_it
h2_itAuthor
Associate
May 12, 2014
Posted on May 12, 2014 at 19:36

Hi Jan,

the errors (USART, Timer) seems to correspond. If I disable and enable the USART_DMAReq_Rx my error disappeares. If you disable and enable TIMx_DIER_CC1DE your error disappeares.

In both cases DMA request enable is switched off/on.

Ok, this should be the solution, but I wished ST would confirm that or tell us the correkt reason for it.

Greetings

Herbert

Amel NASRI
ST Technical Moderator
June 23, 2014
Posted on June 23, 2014 at 17:36

Ok, this should be the solution, but I wished ST would confirm that or tell us the correkt reason for it.

The workaround that you have already suggested is correct: in fact you have to disable the DMA request on peripheral side.

If there is a DMA request pending, it will be served as soon as the DMA is enabled. The pending DMA request is cleared if you reset the DMAR bit in the USART_CR3 register.

In case of a timer, it will be the reset of CC1DE bit in TIM_DIER register.

This is not a limitation, but it needs to be clarified. This will be done in the next release of

http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00046011.pdf

.

Thanks for reporting this case & sorry for answer's delay.

Best Regards

-Mayla-

To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.