cancel
Showing results for 
Search instead for 
Did you mean: 

Missing bytes in UART frame through dma

Manon S
Associate II

Hi,

​I implemented a UART communication using the DMA feature on a STM32L4 microcontroller.

DMA RxCallback is called on UART Idle line detection interrupt as I d'ont know the length of the incomming frame. The baudrate is 230400 and I receive a frame every 8 seconds.

That's when things get tricky : I miss at least a byte on almost every frame, I can't figure out why. Any suggestion on where I should look for a problem ?

Is there any reported issue on the DMA state machine that would provoque it to miss a byte in the UART RX register ?

Thank you,

Manon

4 REPLIES 4

How do you knwo that bytes are missing? Do you observe the incoming bytes on the wire with an oscilloscope/logic analyzer (LA)? Which data are missing - the first, the last? How many data are you receiving, how big is the buffer, how exactly do you know how many data arrived, how are you managing the DMA?

JW

Well the HAL implementation is overly complicated and prone to race conditions.

You could try an pin down the issue by using 16-bit DMA transfers/buffers, and mark the buffer so you can see the data received and compare that to the amount you determine was received.

I'd use Circular DMA so that I didn't need to repeatedly initialize it, and sweep it and do timeout management in the 1 KHz task.

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

​Hi,

Thanks for your answers.

Well, yes, I know exactly what I receive on the uart as we developped the transmitter and I checked with an oscilloscope the data. The missing data index was random. DMA is in circular mode, and the buffer is big enough to contain at least 5 frames (but I tested with bigger and smaller buffer). Currently the buffer size is 256 bytes. The reception is managed on interrupt, not in the 1kHz task.

And, I don't use the HAL drivers, only the Low Layer.

But, I was wrong with the frequency of the reception that was problematic. Let me explain : when I receive a frame every 8 seconds I don't miss any bytes contrary to what I stated. I do when this frequency rises. In worst case scenario, I can have an incoming frame every 6ms, and I miss bytes in every frame. That led me to look for a timing issue and I figured that I need to delay RxCallback (after idle interrupt) for 20ms to have complete frames. It's a bit long considering the max frequency of incoming frame, dare I say…

So now, I am looking for a solution to reduce this latency.

Happy new year and all the best for you and your loved ones

Manon S
Associate II

​Hi again,

For others interest, if they have the same issue as I do, I implemented a way to get around the issue.

Instead of managing the frames on idle state of the uart, I kind of use multibuffer method of the DMA ("kind of" because it doesn't exist for STM32L4). I enable half transfer interrupt as well as transfer complete interrupt and manage each half buffers as if it was two buffers. When one of these interrupt is hit, I copy the whole (half)buffer into another bigger buffer that I can later cut into all of my frames. This buffer stays in memory in case the last frame was not complete in the half dma buffer. Hope that's clear.

This method is not revolutionary (not sure of that spelling !), but in my early stage tests it seems to work. I also can easily control my microcontroller consumption whatever the incoming frame frequency is. However, I still have another sort of latency in my code, but I might live with that if I am sure to get all of my frames ;)