This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

[ble_app_uart] UART overrun

Hello,

I am trying to fix the UART communication error in a peripheral side.

First of all, the setup that I am using is as below.

[SDK] nRF5_SDK_11.0.0_89a8197

[Softdevice] s130_nrf51_2.0.0_softdevice.hex

[Central] nRF51 dongle (PCA10031) to the Master Control Panel in PC

-MEFW nRF51822 0.11.0 with 1M bps UART baud rate & 20 ms Connection Interval

[Peripheral] nRF51822 QFAA (3rd revision) based 3rd party module

-Application firmware: ble_app_uart

(...\Nordic Semiconductor\nRF5_SDK_11.0.0_89a8197\examples\ble_peripheral\ble_app_uart\custom\s130\arm5_no_packs)

-Bandwidth: High (6 packets per an interval)

cf. by default, connections as a Peripheral will be set to high bandwidth. (11.4 BLE role configuration in S130_SDS_v2.0.pdf (page 38))

-Connection Interval: 20 ms

define MIN_CONN_INTERVAL MSEC_TO_UNITS(20, UNIT_1_25_MS)

define MAX_CONN_INTERVAL MSEC_TO_UNITS(20, UNIT_1_25_MS)

-Slave latency: 0

define SLAVE_LATENCY 0

-Maximum character length: 20 characters

define GATT_MTU_SIZE_DEFAULT 23

define BLE_NUS_MAX_DATA_LEN (GATT_MTU_SIZE_DEFAULT - 3)

-Mode: Write command ("ble_nus_c_string_send" function)

-TX FIFO size: 512 bytes

In the peripheral side, an external MCU sends the data to the nRF51822 module via the UART communication with a 57600 baud rate. The sampling rate is 250 Hz, so the interval of the UART RX is 4 ms. For now, an external MCU does NOT support the hardware flow control but the flow control is emulated by the firmware of the MCU, which means that an external MCU reads the RTS pin (P.08) of the nRF51822 module before sending the data, and then send the data only when the RTS is low.

When the MCU sends the 6 bytes data with the 250 Hz sampling rate, I’ve not obtained the UART communication error so far. However, when trying the 9 bytes data with the 250 Hz sampling rate, the UART overrun error occurs in the debug mode as below.

image description

I’ve also monitored the CTS pin of the MCU (=the RTS of the nRF51822) by a logic analyzer as below. After some point, the CTS pin of the MCU goes “high” and the UART overrun error occurs. image description image description

This attached file is the received data in a Master Control Panel. mcp_packets_9bytes_250Hz.xlsx

Regarding the data throughput, the total UART RX data per second is the 2250 bytes/sec. (= 9 bytes x 250 sampling rate) The expected maximum radio TX data throughput for the current setting is 6000 bytes/sec. (= 20 bytes (packet size) x 6 (maximum packet number per a connection interval) / 20 msec (connection interval)) In this calculation, the expected maximum radio TX data throughput per second is larger than the UART RX data per second.

Regarding the processing time, in this link (devzone.nordicsemi.com/.../), the CPU blocked duration for one packet is about 1 msec. The UART RX duration for 9 bytes (= 72 bits) per one sampling is 1.25 msec with 57600 UART baud rate. If there are 5 samplings in the 20 msec interval (250 Hz sampling rate = 4 msec period), the total UART RX duration is 6.25 msec (= 1.25 msec x 5 samplings). For this case with the write command mode, 45 bytes (9 bytes x 5 samplings) can be sent to the radio event handler, so 2 packets (= 40 bytes) are sent in this connection interval and the remained 5 bytes will be sent with 15 bytes of next sample in next connection interval. The CPU blocked duration for 2 packets is about 2 msec according to the above link. Thus the total duration for the UART RX and radio event is about 8.25 msec, which is shorter than the 20 msec connection interval.

I’ve read this link (devzone.nordicsemi.com/.../), which commented that the transmitting speed of ble_over_uart in the SDK is slow, especially for Softdevice central role and recommend the EHAL library (embeddedsoftdev.blogspot.kr/.../ehal-nrf51.html) or nRF52 with DMA, but I wonder why the UART FIFO overrun error occurs even with sufficient data throughput and processing time for the application. Is there any way to work current setup using the ble_over_uart of the SDK with nRF51? Please let me know if I missed or misunderstood something.

Here is the complete project file that I am using. ble_app_uart.zip

Thank you in advance.

[Updated on Aug 10 2016]

Hi, Stefan,

Thanks to your comment about completely blocking UART transfer, I could consider the error “BLE_ERROR_NO_TX_PACKETS”.

When I tried several same experiments, sometimes I’ve experienced a different error as below, which was the error code 0x0304 meaning the “BLE_ERROR_NO_TX_PACKETS”. (I am not sure yet why different errors occurred.)

image description

Thus I’ve modified the “ble_app_uart” code to stop transmitting the data to the stack when receiving the “BLE_ERROR_NO_TX_PACKETS” and to wait until receiving the “BLE_EVT_TX_COMPLETE” . After receiving the “BLE_EVT_TX_COMPLETE”, then transmitting the data to the stack is started again

I added a global variable for the flag to enable or disable the data transfer to the stack. For this modification, I referred to these links.

devzone.nordicsemi.com/.../

devzone.nordicsemi.com/.../

devzone.nordicsemi.com/.../

After the modification, no error occurred sending 9 bytes data with the 250 Hz sampling rate during about 30 minutes.

However, when increasing the data to 15 bytes with the same sampling rate, I obtained the UART_COMMUNICATION_ERROR again. At this case, the data throughput and the processing time are still sufficient.

I've tried checking the actual CI as you advised. However, when hitting the breakpoint (shorter than 5 seconds), I could not find the “m_current_connection_params” variable. The below image is the MCP (left) and the debugger (right) when hitting the breakpoint. Could you let me know why this happened?

image description

Regarding the -O3 compiler option that you mentioned, I am still using -O0 option for debug purpose.

[Updated on Aug 12 2016]

Hi, Stefan,

Thanks again for the good comment!

Unfortunately, the final data throughput that we want is the 6750 bytes/sec (=27 bytes with 250 Hz sampling rate). Actually, I thought that this would be possible using the nRF51822 with the “ble_app_uart” example of the SDK because the calculated maximum RF throughput is much higher, which is the 16000 bytes/sec (=20 bytes packet size x 6 packets per one CI / 7.5ms the shortest CI). Is this correct?

This is a first time for me to use the nRF51822, so I’ve tried increasing the data throughput step by step from the 6 bytes with 250 Hz sampling rate by the 3 bytes step.

As your previous comments, I made some changes on the central side (PCA10031 dongle) to find where the UART error takes place (Central or Peripheral side).

This is a new setting of the central.

[Softdevice] s130_nrf51_2.0.0_softdevice.hex

[Application] ble_app_uart_c with a terminal program in PC

-The stack configuration for high bandwidth (6 packets per a CI) is made thank to Petter Myhre’s help. (devzone.nordicsemi.com/.../)

In several tests with different baud rates and received data sizes, I've found that the change waiting for the "BLE_EVT_TX_COMPLETE" event improved the performance as you said. The below parameters are the configurations that I am using.

[Central]

UART_TX_BUF_SIZE: 512, UART_RX_BUF_SIZE: 256

MIN_CONNECTION_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS)

MAX_CONNECTION_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS)

UART_BAUDRATE_BAUDRATE_Baud57600

[Peripheral]

UART_TX_BUF_SIZE: 256, UART_RX_BUF_SIZE: 512

MIN_CONNECTION_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS)

MAX_CONNECTION_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS)

UART_BAUDRATE_BAUDRATE_Baud57600

As a below figure of the peripheral side, I could see that the data communication works well for 15 bytes with 250 Hz sampling rate (3750 bytes/sec) under my observation about 10 minutes, but not for 18 bytes with 250 Hz sampling rate (4500 bytes/sec).

image description

When calculating durations under the view of one CI, the number of sampling per one CI is 1.875 (=7.5 msec CI / 4 msec sampling period).

Thus the UART RX duration in a CI is about 3.9 msec (= 15 bytes x 8 bits x 1.875/ 57600 baud rate) and the required packet number per a CI is about 1.4 (15 bytes x 1.875/ 20 packets), which takes 1.4 msec at most. (I’m using the 3rd version hardware, so maybe CPU is blocked shorter than 1.4 msec. Is this correct? devzone.nordicsemi.com/.../)

So, the CPU processing margin in a CI is about 2.2 msec (=7.5 msec CI – (3.9 msec UART RX + 1.4 msec Radio TX)). This number might be sufficient for the CPU because the communication works well.

For larger received data throughputs, however I’ve tried the higher baud rate to make more room for the CPU or stack. The strange thing that I experienced is that as below figure of the peripheral side, the CTS gets high in one second and never goes back to low when using 115200 baud rate (only for peripheral side) even with same 15 bytes with 250 Hz sampling rate. I thought that for the same received data throughput, the higher baud rate can guarantee more processing time for CPU or stack but the UART error took place so early.

image description

Do you have any idea what I should consider to use higher baud rates such as 115200?

[Updated on Aug 24 2016]

Hi, Stefan

First of all, thank you for your work.

I’ve tested the “ble_app_uart_test_throughput” that you provided, but using 230400 baud rate still causes the “APP_UART_COMMUNICATION_ERROR” in the debug mode.

The time length for the high CTS depends on the data size. As the below figure, it takes about 0.4 sec for the 250 Hz/6 bytes data (12 kbps) with the 230400 baud rate.

image description

[SDK] nRF5_SDK_11.0.0_89a8197

[Softdevice] s130_nrf51_2.0.1_softdevice.hex (updated from s130_nrf51_2.0.0)

[Central] nRF51 dongle (PCA10031) with “ble_app_uart_c” and a terminal program in PC

  • High bandwidth (6 packets per a CI), 57600 UART baud rate, 7.5 ms Connection Interval

  • -O3 option with “optimize for time”

[Peripheral] nRF51822 QFAA (3rd revision) based 3rd party module with your modified “ble_app_uart_test_throughput”

  • High bandwidth (6 packets per a CI), 230400 UART baud rate, 7.5 ms Connection Interval

  • -O0 option (for debugging)

  • TX buffer size: 64, RX buffer size: 64

The way to increase the RX buffer size to 256 works for the 250 Hz/6 bytes data (12 kbps) with the 230400 baud rate, but the UART transfer is blocked after less than 2 seconds for the 250 Hz/9 bytes data (18 kbps) with the 230400 baud rate and I could find the “APP_UART_COMMUNICATION_ERROR” in the debug mode as below.

image description

image description

First, I wonder which firmware you are using for the central (ble_app_uart_c or MCP). If you use the "ble_app_uart_c", which baud rate are you using?

Second, I could find the modification that you said in the “main.c” file but when I looked at the “app_uart_custom.h” and “app_uart_fifo_custom.c”, I could not find any difference with “app_uart.h” and “app_uart_fifo.c”, respectively. In my view, only one comment and a name of header file were changed. Is this correct?

Parents
  • @YSK

    The ble_app_uart implementation in the SDK does not handle high throughput well. That is not good as I believe the nRF51 can well handle the 54 kbps throughput you are asking for if the implementation was better. I will help you to reach this throughput next week with ble_app_uart. What you have implemented with the BLE_EVT_TX_COMPLETE event is the first improvement. I recently tested the 128kbps throughput on the BLE side, and it works fine. The UART can support 115 kbps and beond. The software implementation in between is the problem, and I believe we can improve it significantly.

Reply
  • @YSK

    The ble_app_uart implementation in the SDK does not handle high throughput well. That is not good as I believe the nRF51 can well handle the 54 kbps throughput you are asking for if the implementation was better. I will help you to reach this throughput next week with ble_app_uart. What you have implemented with the BLE_EVT_TX_COMPLETE event is the first improvement. I recently tested the 128kbps throughput on the BLE side, and it works fine. The UART can support 115 kbps and beond. The software implementation in between is the problem, and I believe we can improve it significantly.

Children
No Data
Related