This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2540: Tx throughput issue with UART using DMA on CC2540

Part Number: CC2540


UART using DMA - Tx Throughput Issue with BLE Stack 1.4.0

 

Background

We have an embedded CC2540 running BLE Stack 1.4.0 on our system that has a host processor that communicates with the CC2540 over either UART or USB depending on whether the host processor's hardware supports UART or USB.  This port is referred to as the Management Port. The Management Port always operates at 115,200 baud.

The CC2540, whether in the UART configuration or the USB configuration, aggressively scans the environment for other BLE devices and for every BLE advertisement or scan response that it receives, packages it in a well known format of around 50-bytes or so and ships this off to the host processor over the 115,200 baud serial link.

Every 20 seconds, two different management packets, referred to as the First Management packet and the Second Management packet, are sent back to back, to the host processor over the same 115,200 baud link.

Problem Statement

It has been observed that on the BLE Devices with UART configuration we miss a significant number of these management packets. However on the USB configuration, we receive every single management packet. The table below conveys this:

 

First Management Packet

Configuration

Expected Number of First Management Packets

Actual Number of First Management Packets

%age Loss of First Management Packets

USB

3011

2060

31.5%

UART

3012

3012

0%


Second Management Packet

Configuration

Expected Number of Second Management Packets

Actual Number of Second Management Packets

%age Loss of First Management Packets

USB

3011

618

79.48%

UART

3012

3012

0%


In looking through the HAL UART code, and the Tx driver specifically in _hal_uart_dma.c, it was surprising and very disconcerting to see that the Tx routine, HalUARTWriteDMA(), uses ISR rather than DMA. Apparently there are "issues" with DMA in the context of this code. Here are a couple of snippets from the code:

 

line 8 of _hal_uart_dma.c:

A known defect is that when flow control is enabled, the function HalUARTPollTxTrigDMA() can prematurely invoke HAL_DMA_MAN_TRIGGER(HAL_DMA_CH_TX) and clobber that last byte of one txBuf[] block transfer with the first byte of the next txBuf[] block transfer.  Additionally, Tx can become permanently stalled during heavy use and/or simultaeous heavy radio traffic when using DMA for the Tx and hardware flow control.

 

line 199 of _hal_uart_dma.c

// For known defects described above in the moduel description, prefer to drive the Tx by ISR vice
// DMA unless H/W flow control is not used and full-throughput on Tx is absolutely essential.

 

I also checked for changes in HalUARTWriteDMA(), between BLE Stack 1.4.0 and either BLE Stack 1.4.1 or BLE Stack 1.4.2, but found nothing.

The caveats in the code about not using DMA for Tx sound dire.  We would prefer to use DMA. But, one of the comments above is disturbing, "Additionally, Tx can become permanently stalled during heavy use and/or simultaneous heavy radio traffic when using DMA for the Tx and hardware flow control." 

Here are my questions:

  1. We do not use flow control in our hardware configuration, so are the above messages applicable to our setup?
  2. When the management port is over USB, operating at 115,200 baud, we do not see any dropped packets.  When the management port is a UART port handled by ISR, operating at 115,200 baud we see almost 32% of First Management paket and 80% of Second Management packet being dropped.  What is the expected throughput on UART port handled by an ISR?
  3. I changed the port configuration to use DMA instead of ISR by changing the following line:

        #define HAL_UART_TX_BY_ISR 0

        and increased the DMA Tx Buffer to be 256 instead of 128.

    Now, When the management port is a UART port handled as DMA, we see a 10% drop in management packets.  Why is this behavior not equivalent to the USB port, since in theory, the DMA should be able to operate at 115,200 baud, much like USB?
  4. Keeping in mind that we do not use flow control and if I shift to using DMA, what are the chances that the Tx will get permanently stalled? 
  5. Can I detect a stalled Tx, when using DMA, and reset the UART to resume normal operation?
  6. Bottom line, how can I get the UART to operate at 115,200 baud?

 

I would really appreciate your help in this matter.

Regards,
KK

  • Hi KK,

    Since you are not using flow control, I don't think the code comments apply to you, but I will investigate that further. While I am looking into some of your more specific questions, I had a couple questions that may help with debugging this:

    You say you enabled DMA and saw a 10% drop in management packets. Is that on both the first packet and the second?

    Can you tell me more about your host device? Is it the same device for both UART and USB?

    How are you checking where the packets are dropped? Do you check the return value of HalUARTWrite?

    On the CC2540, which DMA channel are you using? Have you enabled power savings? Are you using encryption? Before you write to UART are you checking to see if the DMA is busy?
  • I appreciate your quick response!

    RachelP said:
    You say you enabled DMA and saw a 10% drop in management packets. Is that on both the first packet and the second?

    Yes.  It's roughly 10% for both first and second management packets.

    RachelP said:
    Can you tell me more about your host device? Is it the same device for both UART and USB?

    The host device is different for both the UART and USB device. In reality the choice of UART or USB is dependent on whether the host supports two UARTs or a single UART with USB.  We use the other UART on the CC2540 for a different purpose.

    RachelP said:
    How are you checking where the packets are dropped? Do you check the return value of HalUARTWrite?

    I have added counters to check the return value of HalUARTWrite() but in this case I am checking the number of packets received on the host.

    RachelP said:
    On the CC2540, which DMA channel are you using? Have you enabled power savings? Are you using encryption? Before you write to UART are you checking to see if the DMA is busy?

    I am using the HAL UART drivers provided by TI, as is.  When I shifted to using DMA for Tx (instead of ISR as is the default even if you specify DMA), I set HAL_UART_DMA  to 2.  On the CC2540 we do not enable power savings.  We do not use encryption.  At the application level I just call HalUARTWrite() and do not check if the DMA is busy, since that is not a requirement.  The call to HalUARTWrite() which in turn calls HalUARTWriteDMA() enqueues the data to be sent out into a buffer, if there is sufficient space in the buffer, and the DMA engine picks it up from this buffer. 

    I look forward to your response.

    Regards,
    KK

  • Hi KK,

    Thank you for that additional information. Please let me know what your counters tell you. HalUARTWriteDMA will return 0 if the buffer is full. The DMA enforces an all or nothing policy so if there is not enough space left, you won't send anything.

    I also would like a little more information about how you are checking the number of packets received on the host. Are you checking the contents of the UART buffers or are you checking at a higher level? Do you have a serial port monitor to use to check what is actually being sent?
  • Hi Rachel,

    RachelP said:
    Thank you for that additional information. Please let me know what your counters tell you. HalUARTWriteDMA will return 0 if the buffer is full. The DMA enforces an all or nothing policy so if there is not enough space left, you won't send anything.

    True.  The counters (based on the return value of HalUARTWrite) show a lot more packets being dropped with ISR (used for Tx with the DMA setting) and a lot less when using DMA for Tx with the DMA setting.  However, I need your confirmation that by switching to DMA for Tx with the DMA setting will not cause stalls as mentioned in the comments the file, given that we do not use flow control.  Secondly, DMA seems to use a much larger buffer than ISR, i.e., if we specify 128 as the size of the Tx buffer, it allocates double the quantity.  However, if ISR cannot get us to the requirement of 115,200 baud, then we will probably have to switch to DMA.

    RachelP said:
    I also would like a little more information about how you are checking the number of packets received on the host. Are you checking the contents of the UART buffers or are you checking at a higher level? Do you have a serial port monitor to use to check what is actually being sent?

    I check the number of packets sent from the BLE against the number of packets received by the host.  I have not used a serial port monitor.

    Regards,
    KK

  • Hi KK,

    We've been looking into this issue but cannot come up with a reason for the discrepancy between UART and USB. When you transmit over UART is the device still in scan mode?

    Can you reproduce this on a TI dev kit? If you can provide instructions to recreate this behavior using Simple Observer, it will help to speed up this investigation.
  • Hi Rachel,

    RachelP said:
    We've been looking into this issue but cannot come up with a reason for the discrepancy between UART and USB. When you transmit over UART is the device still in scan mode?

    Yes, the device could be in scan mode when I'm transmitting over the UART.  Is that a problem?  

    If Tx on UART uses ISR would you expect UART and USB (which probably uses DMA?) to have the same throughput.  What is the maximum speed that the Tx by ISR can handle?  Do you have a test setup, using the TI dev kit, that shows the maximum throughput of the UART Tx using ISR?

    In an earlier message in this thread you had mentioned that you would investigate whether the Tx by DMA has the possibility of clobbering data or stalling when flow control is not in use.  What is the conclusion?  How would we know if either of these conditions has occurred?  What is the corrective action that we need to take, if we do indeed get into this situation?

    Regards,
    KK

  • Hi Rachel,

    Would you please help close this post for my customer.

    Would you please provide feedback on your investigation on whether the Tx by DMA has the possibility of clobbering data or stalling when flow control is not in use?

    Kannan would like to know what is the best case scenario on UART transmitting at 115, 2k Baud BPS with ISR not DMA?

    Thank you!

    Best Regards,

    Peter