Post Go back to editing

BF514F UART RX DMA Problem


I need some help on the following. This question was moved from another post to this one as the other post was answered and finalized.


A Blackfin (BF514F) processes a bunch of measurements and then transmits it at 3125000 bps to an ARM. The ARM then replies with a ACK message. The TX to the ARM works fine but receiving from the ARM not so much. At 3125000 bps we have picked up that the DSP misses messages (CRC Fail). With further investigation we have determined that some of the byte's received are corrupt, but only half of the byte (a nibble) and only a few bytes at a time, not all. And only sometimes. I have set the DMA to receive the whole packet to make sure it is not my 1-byte DMA setup that is causing this problem. We have also check the clock rates on the scope and everything seems fine. Can you think of anything else that could cause this?

I have set breakpoints at UART errors to determine if its a break or frame error or even a DMA error. But I get no error breaks. We have also accidentally found that setting the DSP to 921600 bps and the ARM to 912600 (like I said, by accident this worked, or by typo, haha) the communication works fine. But for our application to finish everything in time we will need 3125000. We have used the exact same DSP and ARM on a previous project and it worked on 3125000 bps. The only difference was that the UART driver RX on the DSP was interrupt driven and not DMA driven.


Is there something on the DMA receive Im missing? Could it be another variable corrupting the DMA UART RX buffer, which I have checked and cant trap or find if it is.

I think I know why the 921600 - 912600 bps combination works. I have seen that the DSP UART at 921600 bps has an actual baude rate closer to 912600. So maybe that is why that worked. But at 3125000 the DSP UART has almost no error. As far as we can see the arm has a very good baud rate generator (64 times oversampling).

Any ideas would be welcome thanks.

Kind regards,



  • Hi,

    basically, there should be no difference between core/interrupt driven and DMA UART transfer.

    I have a couple of questions first:

    Do you get any status interrupts (UART_LSR register)?

    What are the settings you do (UART_LCR, UART_DLL/DLH, UART_GCTL)?

    What are your PLL setinngs and the clock in. Yu know the faster the bitrate is set the higher the error (Desired bitrate vs actual bitrate error in %) becomes.

  • Hi Andreas,

    Thanks for the quick reply. Sorry I'm only replying now. Did not get a notification.

    I also thought there would be no difference. I am using the UART DMA Driver that is found in the Analog Devices Blackfin folder. So Im not as in control of the registers as I'd like to be. Im also using the System Services to setup my power and clock settings.

    I have the DSP setup for 400MHz main clock and the SDRAM running at 100MHz.

    I did put in some code to check for any UART or DMA errors. I do not get any UART_LSR error bits set. Neither do I get any DMA errors.

    Setup for 8N1, 8bit word, 1 stop bit, No parity.

    UART_LCR ->0x03

    UART at 3125000 bps:

    UART_DLL -> 0x02;

    UART_DLH -> 0x00;


    Im using a 25 MHz external clock.

    PLL_CTL -> 0x2000;

    PLL_DIV -> 0x0004;

    I did check the bit rate error. According to calculations and the datasheet. At 3125000 the actual bit rate matches the calculated bit rate exactly.

    SCLK -> 100 MHz

    bit rate = 100MHz/(16*2) = 3125000. Setting and actually is equal. So the only difference would be the actually clock drifting with temperature or it being crappy. But we have tested the code on another PCB and got the same results.

    I really cant think of anything else causing this, except maybe long UART lines but I would have thought that I would get error bits being set. I can then only think it is memory being corrupted from the DMA taking the byte and placing it in the actually memory buffer in SDRAM.

    Please let me know if you need more information.

    Kind regards,

  • Hi Quintin,

    Is it possible for ARM to send two STOP bits and then you test the reception at 3.125Mbps? Also, have you also tried to test it with 2.08Mbps, 1.5625Mbps or even 6.25Mbps (just few datapoints)?



  • Hi Prashant,

    I will test the two STOP bits, we can set the ARM to do that thanks. Will let you know as soon as we have done that. I have tested the communications at different baud rates. Even 115200 bps.

    Thanks again for the quick replies. I'll report back as soon as we have the two STOP bits going and tested.

    Kind regards,


  • Hi all,

    I just want to admit something,

    I found out that I never actually set the line status events parameter to "TRUE" and that's for never getting any UART error interrupts. The moment I realized that and set it to "TRUE", I started getting overrun errors. Meaning the 1-byte DMA receive scheme is not going to work for us. The DMA was taxed to much and could net get to empty the bytes out of the UART before the next one came in.

    I then came up with a relatively easy way of using the Analog UART DMA driver in only TX mode and then using my own code (interrupt driven RX) to do the RX in interrupt driven mode.

    This has resolved my issues and I dont get any more line errors or missed packets. I have now also cranked the speed up to 3.125 Mbps. I will just for interest sake also test it on 6.25 Mbps later on. But for our application the 3.125 Mbps is fast and stable enough.

    I would still like to put a bit more time into finding out exactly why the 1-byte DMA receive was not quick enough but for now I'm taking it that because I'm also using the DMA to transfer data from a ADC to the SDRAM it was just too busy to get to the UART data.Maybe using different banks on the SDRAM would help? Or maybe using the DMA for 1-byte RX is just not practical and should be avoided?

    Kind regards and thanks for everyone's input.


  • Hi Quintin, 

    Just came across this (a few years later!), just wondering if you might be able to elaborate on how you managed to operate the UART with the TX running in DMA mode, and the Rx in normal interrupt driven mode.

    I am also finding that byte-by-byte DMA is not fast enough to keep up with submitting 1 byte buffers each time a new byte is received.

    Many thanks, 


  • Hi Connor,

    Can you please provide more information on below points to assist you better on this,

    1.Which processor are you using?
    2.Are you facing any issues while debugging on UART ?

    Please let us know if you are looking for any other information.

    Anand Selvaraj.

  • Hi Anand, 

    We are using an SC573, with UART IO running on the ARM core, and aren't debugging over UART, but sending and receiving MIDI - this post seemed relevant however.

    We're not running at a super fast baud rate, 31250 which is the standard for MIDI transmission, however the DMA engine seemed to miss bytes when attempting to do byte-by-byte DMA.

    We now have a simple solution that seems to work, using only interrupt for Tx and Rx. 

    For Tx, if the ETFI interrupt is masked and TEMT is set we write the first byte to the THR, then unmask the ETFI interrupt. In the Interrupt handler, if there are more bytes to write and THRE is set we again fill the THR. When no more bytes are available to write, we mask the ETFI interrupt.

    For RX we simply read the RBR if DR is set.

    As stated this works reliably with no lost data at 31250 baud.

    I would be curious however if there is a way of getting DMA working for transmission to reduce interrupt volume.

    Many thanks,


  • Hi Connor,

    We would suggest you to refer the FAQ which talks about "Example project which helps to understand UART DMA mode operation in SC58x processors" and example code available in the below mentioned link. Please use this as a reference and modify to ADSP-SC573.

    >> Please find the UART DMA example codes in the ADSP-SC5xx board support package. Please download and install the board support package in the below link.

    Once the BSP is installed, the UART example code is available in the below mentioned path.
    [Installation Directory]\Analog Devices\ADSP-SC5xx_EZ-KIT_Lite-Rel2.0.2\ADSP-SC5xx_EZ-KIT\Examples\Power_On_Self_Test\common\source

    Anand Selvaraj.