cancel
Showing results for 
Search instead for 
Did you mean: 

UART with DMA and new line detection

andy2
Associate II
Posted on September 23, 2015 at 04:39

Hi all, in my project which takes data from a device from UART, and I have made it use the DMA to save the info.  The callbacks HAL_UART_RxCpltCallback and HAL_UART_RxHalfCpltCallback are called and working well.  However, I have to detect the new line character to do some action according to the data, what is the best approach to this?  I am using STM32F051, and the UART_IT_LBD interrupt looks interesting but cannot get it to fire.

Sorry if this is a silly question, but I really do not know which direction to go at the moment.
5 REPLIES 5
knielsen
Associate II
Posted on September 23, 2015 at 09:42

The DMA writes the data into a memory buffer. You can just loop over the characters in that buffer after receiving your data, and do the processing you need.

But I am guessing that you want to process the newline before your DMA transfer has completed - maybe you do not know how many characters will be received.

For this, DMA does not seem appropriate. The simplest is a polling loop that reads and processes a character at a time. Or use the UART receive interrupt to process each character in an interrupt routine as they are received.

It is possible to scan the DMA buffer while DMA reception is still on-going, but it will be tricky to get right, and will require a deep understanding on the details and timings of the peripherals involved.

knielsen
Associate II
Posted on September 23, 2015 at 09:44

The UART_IT_LBD interrupt does not do what you want. It is not related to newline characters, it detects an abnormal condition on the serial line.

keaven
Associate II
Posted on September 23, 2015 at 16:50

That is what I have done myself.

I start the UART RX with DMA in circular mode.  I have a thread that check the DMA buffer for new data which I copy into a bigger circular buffer where I can process asynchronously.  This second buffer is where I parse my packet, validate or search for a specific character.

It worked very well at 460kbps.  It you don't want to use the 1/4, 1/2 , 3/4 and full DMA interrupt you can use the macro __HAL_DMA_GET_COUNTER(hUART1.hdmarx) to get the number of bytes to empty the buffer to determine if new bytes are available.  That is what I am using because I can receive command less than 1/4 of the DMA buffer length.

Hope this help you out.
andy2
Associate II
Posted on September 24, 2015 at 08:38

Thank you everyone.  I read about the __HAL_DMA_GET_COUNTER MACRO before, however, it is strange that it does not exist anywhere in the project.  I generate my project using the CubeMX tool.

keaven
Associate II
Posted on September 25, 2015 at 16:52

I am sorry, I am not using STCubeMx to generate my code so I don't know what does the code look like.  I am using the application only to validate my pins assignation and the clocks configuration.

The macro is in the file stm32f (4/7)xx_hal_dma.h .  It is returning the value of the register DMA_SxNDTR .