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:
- We do not use flow control in our hardware configuration, so are the above messages applicable to our setup?
- 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?
- I changed the port configuration to use DMA instead of ISR by changing the following line:
#define HAL_UART_TX_BY_ISR 0
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?
and increased the DMA Tx Buffer to be 256 instead of 128. - 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?
- Can I detect a stalled Tx, when using DMA, and reset the UART to resume normal operation?
- 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