cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 slave uart DMA circular buffer

francescatodiego
Associate II
Posted on June 09, 2014 at 19:00

I have to

write new driver for 

uart

slave

interface

with

a

STM32F407

For RX I thought I

enable DMA

in

circular

buffer

  mode.

The device is always ready to receive and w

ith HC

and

TC

DMA

interrupt I

can

download the RX data

from the receiver buffer.

But with message rx tail or if the length of the received message can't trigger a DMA interrupt how I can solve ?

Someone

has already solved

a

similar

situation

Thanks

#stm32-usart-dma
5 REPLIES 5
Posted on June 09, 2014 at 21:02

Your TX routine would have to use normal mode and describe linear regions of the ring buffer, and split the wrapping condition. If there is no data to send you'd simple need to poll the buffer occasionally (say 1 KHz task), and restart the next transaction.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
jpeacock2399
Associate II
Posted on June 09, 2014 at 21:31

If the incoming message is variable length then you need a method to detect an idle period after the last character is received.  ST recommends using a timer attached to the RX incoming bit stream.  Set up the time to reset on every edge change, with a timeout period sufficient to guarantee an end of message idle period.

As long as incoming data arrives the timer is constantly being reset, meaning the RX line is active and DMA is storing data.  When the incoming data stops, there are no bit transitions and eventually the timer overflows, signaling an idle period.  Once the timer overflows you can stop the DMA and process the data in the buffer.

I use this on a high speed (460Kbaud) RS-485 serial line, USART1 along with timer TIM9, the TIM9 CH1 input connected to USART1 RX input pin.  I set the TIM9 to reset on capture, with a timeout based on selected baud rate.  Be sure to use a timer that can reset on capture input pin, not all have this capability.

I use Modbus as the line protocol, which defines an inter-message gap time.  The timeout is determined by the baud rate, with a minimum time, as defined in the Modbus standard.  With a time gap you don't have to detect framing characters for the message.

  Jack Peacock
francescatodiego
Associate II
Posted on June 09, 2014 at 23:26

thanks for the

quick

answers

The idea of

​​polling

the

buffer

seems to be the

easiest

.

going

even

at high speeds

eg

.

460kbps

every 1ms

I receive

46bytes

with

128 or 256 bytes

buffer

should

be safe enough

to be able to

flush the buffer

before

DMA write overflow at 1ms sampling rate

In fact even

I was thinking

to the Jack solution

My idea was

to

trigger

the timer

with

RXNE

interrupt

but the documentation

warns that

if you use the

DMA

is not possible to

activate

the

interrupt

RXNEIE

(

sich!

)

Jack describe a good solution

but I must

change the

hw

...

I have to think

olavi
Associate III
Posted on June 17, 2014 at 17:21

I went on an even simpler route by using just the ''plain old'' DMA to transfer the RX data into a circular buffer without any interrupts.  With the higher speeds (several MBd) this seems to be the only alternative.

There is no generic way to detemine the buffer size.  Obviously it has to be large enough to tolerate the burst loads.   If a rapid response to short UART messages is required, a time based polling, such as 1 ms or 10 ms, can be used to determine if enough data has been received.  The usage of the NDTR register is essential in that routine.

You can find more details in a tutorial I have written about this  subject at

http://www.emblocks.org/wiki/tutorials/f401_f429_disco/serial

marko239955_st
Associate II
Posted on December 11, 2015 at 00:17