Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Unused time at the end of every BLE interval much larger than expected

I've been working on maximizing BLE throughput between a nrf52840 dongle and a peripheral device. As I've tried to narrow down variables I've ended up with just using two nordic dev kits so I will just describe the issue I'm seeing with the dev kits.

References I've Used

https://infocenter.nordicsemi.com/topic/sds_s140/SDS/s1xx/ble_data_throughput/ble_data_throughput.html
https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/throughput-and-long-range-demo

https://interrupt.memfault.com/blog/ble-throughput-primer
https://novelbits.io/bluetooth-5-speed-maximum-throughput/
https://punchthrough.com/ble-throughput-part-4/


Hardware

- PCA10040 dev kit acting as a central receiving data

- PCA 10056 dev kit acting as a peripheral sending data

- nrf52840 dongle with sniffer firmware loaded

Software

- Both dev kits are loaded with the (lightly modified) throughput example from nRF5 SDK v17.1
https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.1.0/ble_sdk_app_att_mtu.html


Settings

throughput example:~$ config print
==== Current test configuration ====
Board role: tester
ATT MTU size: 247
Data length: 251
Connection interval: 12 units (aka 15ms)
Connection length ext: on
Preferred PHY: 2 Mbps
GAP event length: 400

Result

[00:02:22.995,361] <info> app: Sent 256 KBytes
[00:02:22.996,704] <info> app: Done.
[00:02:22.996,704] <info> app: =============================
[00:02:22.996,765] <info> app: Time: 1.850 seconds elapsed.
[00:02:22.996,765] <info> app: Throughput: 1134.27 Kbps.
[00:02:22.996,765] <info> app: =============================
[00:02:22.996,765] <info> app: Sent 262300 bytes of ATT payload.
[00:02:22.996,826] <info> app: Retrieving amount of bytes received from peer...
[00:02:23.030,761] <info> app: Peer received 262300 bytes of ATT payload.


Unexpected behavior

The time delta between the end of the last packet sent from the peripheral (slave) to the central (master), and the beginning of the next interval is never less than 2620 usec. (It varies between ~2620 and ~2633 usec). See the screenshot and wireshark capture attached.



nordic_dev_kit_test1.pcapng



Expected behavior


A single packet from the slave looks like this:


In the case of a 2M PHY and no MIC, then we end up with: 244 bytes of data + 18 bytes of overhead = 262 bytes

At 2Mbit this takes 262*8/2 = 1048 usec to send (this agrees with what I'm seeing in the wireshark capture)

The Empty PDU is 2+4+2+3 = 11 bytes long, which takes 44 usec to send (also agrees with capture)

The Inter Frame Spacing is 150 usec (as specified in the v5.0 spec Vol 6 Part B Section 4.1) (also agrees with capture)


So, if a 15ms interval starts with the master sending an empty PDU (which it does), then the remainder of the interval should look like this:

I would expect to be able to fit 10 "round trips" and thus 10 data packets from the slave, and then have 1230 usec of unused time before the beginning of the next interval.

However, this is not what I see. Instead, I see only 9 data packets in each interval with ~2622 usec of unused time. 


Theories

My current working hypothesis is that this is related to the fact that the connMaxTxTime and connMaxRxTime are being set by the bluetooth stack to 2120 usec, which would be the correct value for a 1Mbit phy, but is incorrect for my use case. I have tried a few things to get that number to change but no luck so far.




Any help would be greatly appreciated!

Related