cancel
Showing results for 
Search instead for 
Did you mean: 

Continously Receiving UART Data and Transferring to DMA without Generating Interrupts With Variable Length Data on the STM32L475RE

EGold.3
Associate II

I am working on a portion of code that handles some UART messages that come in periodically from an LCD. The reception of a message over UART from this screen will generate a response based on the parsing of the message received.

It is part of a larger app, and is not a critical portion of the app execution. Therefore it is not desired to have this generate interrupts- in case of the LCD going haywire and overwhelming the app with messages which tie up the CPU and interferes with the code flow that needs to execute

The messages coming from the LCD are of variable length. I know the maximum possible message length, but that is all. I was using the HAL call (working on STM32L475RE):

HAL_UARTEx_ReceiveToIdle_DMA()

Which was effective since it can receive to either a max length or the RX line going idle. The issue is, i seem to only make this work when I enable the DMA nd UART interrupts and have a callback function which handles the DMA transfer complete interrupt, therefore breaking the desired principle of not using interrupts.

Is there a possible way to continously receive UART data and transfer it to some buffer using DMA without needing to generate interrupts? What I'd really desire is to have some function in the main loop that checks if the DMA buffer has been populated since the last call, and then parse and handle this newly received data- essentially what a callback function would be doing without interrupt generation

9 REPLIES 9

You could make a circular DMA buffer of adequate size, and 16-bit width, USART RX data goes in as it arrives and you periodically sweep it for new content.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
TDK
Guru

You can set up a circular DMA buffer to get the data and monitor the DMA NDTR register periodically to check for new data.

This method is not supported by HAL directly, but the hardware can certainly do it. You could start with the HAL functions to set up a circular DMA buffer and disable the interrupts, or you could code it yourself.

If you feel a post has answered your question, please click "Accept as Solution".

And i Could just kick this off with a call to HAL_UART_Receive_DMA() in the intialization for the UART/DMA?

What’s the utility of using the DMA in circular mode versus normal?

It's always on and doesn't need to be restarted, which means overruns can't happen. The downside is that you need to manage a circular buffer.
If you feel a post has answered your question, please click "Accept as Solution".

You wanted​ no interrupts, and presumably you don't want to lose/miss any data either.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I'd probably low-level it, depending on how much junk is in the L4 HAL, really don't want it setting interrupts, callbacks, or blocking.

Should be able to configure once and the leave to collect data.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I see, so once I kick off the DMA transfer from UART through a call to like HAL_UART_Receive_DMA() in circular mode I never have to invoke it again?

Yes or you can stop it and then need new invoke...

But without Interrupt you cant handle data multi overwrite...