Skip to main content
bully
Senior
July 16, 2021
Question

UART with Circular DMA mode polling - NDTR gives wrong (full) value on wrap in circular buffer

  • July 16, 2021
  • 3 replies
  • 1946 views

Hello,

I'm experimenting with DMA, following a lot of examples. I'm reading DMA counter to determine if there are any new bytes received in circular buffer.

I use CubeIDE on STM32f779. I have following code :

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
 uint16_t i, pos, start=0, length, length_all=0;
 static uint16_t old_pos = 1;
// uint16_t currCNDTR = __HAL_DMA_GET_COUNTER(huart->hdmarx);
 uint16_t currCNDTR;
 
 currCNDTR = (uint16_t)huart->hdmarx->Instance->NDTR;
 
...

It works ok until circular buffer wraps - in this case I have to assemble received message from two parts. But the problem is that currCNDTR (have tried several different options, but no go...) returns value of circular buffer size and therefore I have only 1 part, since NDTR should be different that buffer size (only if received bytes align with buffer size, but this is not the case).

It is interesting that reading from NDTR register inside debugging session I get "normal" value. There must be something wrong with a way how I read that register...

Any advice ?

Thanks in advance.

This topic has been closed for replies.

3 replies

TDK
July 19, 2021

That's how NDTR works in circular mode. You can read about how it works in the reference manual. There is no bug here.

Note that if you're using DMA, it's typically better to poll NDTR rather than relying on a callback from HAL_UART_RxCpltCallback, which only happens when the buffer completes.

"If you feel a post has answered your question, please click ""Accept as Solution""."
bully
bullyAuthor
Senior
July 20, 2021

Hello,

thanks for the info... I'm polling NDTR and the problem shows when bytes are received going beyond the size of circular buffer. I know that more bytes are received, but NDTR stays at 0 (I guess it should start from buffer size again)...

waclawek.jan
Super User
July 19, 2021

>It is interesting that reading from NDTR register inside debugging session I get "normal" value. 

What do you mean by this, that you've seen NDTR being zero while in circular mode?

Also, caveat emptor.

JW

bully
bullyAuthor
Senior
July 20, 2021

Hello,

I meant that my code above has read value of NDTR of 0, while debugger showed proper non zero value....

Thanks for the link, now I understand why some examples take extra time delay between reading NDTR and reading bytes out of buffer,,,

waclawek.jan
Super User
July 20, 2021

Interesting, but I'm not sure it's a problem. RM talks about automatic reload of NDTR in circular mode, but I don't remember reading that it won't be 0 for a moment before the reload.

JW