cancel
Showing results for 
Search instead for 
Did you mean: 

Get DMA count

francesco
Associate II
Posted on May 29, 2017 at 17:55

Hi all,

I'm using USART with DMA to implement a Modbus rtu slave node.

I want to implement this:

- the USART use DMA to store received characters in a buffer

- a contdown-timer count the time between character to recognise the end of the frame.

- the timer is loaded when new characters are loaded by the DMA. I want to recognize them with a 20kHz ISR that I use to do other stuff: Checking the value of the DMA count I know if new bytes has arrived.

I use the DMA as a sort of FIFO, because:

- I don't know the size of the message

- I don't want to use a ISR for each character to avoid loss of information.

Unfortunately, I didn't find any information about getting DMA count!

Does anyone can help me?

Thank you very much.

#stm32-dma #stm32f4 #modbus
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on May 29, 2017 at 20:28

Using the HAL:

huart1.

hdmarx

->

Instance

->

NDTR

Doing it the hard way, look for the NDTR register in the DMA unit.

Andrei

View solution in original post

11 REPLIES 11
Posted on May 29, 2017 at 20:28

Using the HAL:

huart1.

hdmarx

->

Instance

->

NDTR

Doing it the hard way, look for the NDTR register in the DMA unit.

Andrei

francesco
Associate II
Posted on May 31, 2017 at 09:46

Hi Andrei,

Using the register you say, my routine works.

Thank you very much for your help!

Francesco

Zt Liu
Senior III
Posted on May 31, 2017 at 10:24

as Andrei said, 

If you are using HAL library, 

You may use the following code.

const uint16_t RX_MAX_SIZE = 64;               //some integer which MODBUS RTU would never exceed

static uint16_t receivedBytes = 0;

HAL_UART_Receive_DMA(&huart1, rx_buffer, RX_MAX_SIZE);

....

   /*if your timer have detected stop frame */   

if(stop_frame_detected)

{   

   /*check rx receiving bytes*/

   receivedBytes = RX_MAX_SIZE - __HAL_DMA_GET_COUNTER(huart1.hdmarx);

   /*parse rx cmd*/

}

Posted on May 31, 2017 at 18:39

This is a better answer than mine. Thank you.

Steve H
Associate III
Posted on June 01, 2017 at 14:03

If you can rely on the incoming characters being gapless during a given message, you may find this approach useful:

https://community.st.com/0D50X00009XkhGfSAJ

I use the RX Idle interrupt to detect the end of variable-length RX DMA transactions, hence the (probable) end of messages. In the event of an incomplete message, you can assemble it during successive calls to the idle callback handler.

If you find this approach really useful, you might comment on the feature request so that ST knows that it's wanted by more folks than just one nutcase developer (that being me;-)

Posted on June 01, 2017 at 22:30

ST People.

I was trying to figure out why I've never heard of __HAL_DMA_GET_COUNTER before now. I found that it is not in the HAL documentation, like UM1725.

Is there any reason to NOT use this macro?

Andrei

Posted on June 02, 2017 at 02:57

Wow, UM1725 is such a huge doc.  I always first take a quick view on src and header files, and then move to the manual. 

Posted on June 02, 2017 at 23:53

I implemented the DMA 'timeout feature', detecting the possible end-of-transmission with USART IDLE interrupts. DMA is used in circular mode (for minimizing the chance of data-loss when receiving bytes from devices that transmit data frequently & periodically), and the newly received message is extracted from the DMA buffer. Here is my source code with explanation: 

https://github.com/akospasztor/stm32-dma-uart

 
Posted on June 05, 2017 at 10:27

Hi Akos, hi Stephen,

I read your solution and I found them very interesting.

I have only a question regarding the USART IDLE interrupt: this is a specific feature of a micro? In the documentation of the stm32f4 I don't find it.

Anyway, the function I implemented is pretty similar to your solution, but done in a software way. I have a regulation routine that is time-constant and is called in a ISR working at 20kHz. In this routine I implemented the receiving operation. Reading the data count in DMA register (as suggested) I find if there are new data and in this case I reload a timer. If data arrives before the timer end of count they are of the same frame, in the timer reach zero the data are processed. I use half-duplex line, so the receiving is enabled only after the trasmission of the reply.

Ah, my application is a Modbus node.

I see that in recent MCU like stm32f0 there is a specific parameter to set in the USART peripheral to detect timeout after a character. This is very useful, but (unfortunately) is not present on my device!

Francesco