cancel
Showing results for 
Search instead for 
Did you mean: 

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

bully
Senior

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.

5 REPLIES 5
TDK
Guru

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".

>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

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

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

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