bluekitchen / btstack

Dual-mode Bluetooth stack, with small memory footprint.
http://bluekitchen-gmbh.com
Other
1.68k stars 605 forks source link

Throughput issue with Infineon-CYW20704 #622

Open xihua13104 opened 1 month ago

xihua13104 commented 1 month ago

Describe the bug Hi, I am running BTstack v1.6 with the CYW20704 on an STM32F407 with ENABLE_LE_DATA_LENGTH_EXTENSION on. I'm using the gatt_streamer_server demo to test throughput by connecting from my smartphone (Android-13). However, I am only got a maximum TX data rate of about 16 kB/s with different parameters(GATT MTU size,connection interval,packet size per transmit.....). From the HCI packet log of our device, I noticed that the CYW20704 is only sending one packet (244 bytes) per connection interval (15ms). Is there any way to configure the CYW20704 to send multiple packets per connection interval?

To Reproduce Steps to reproduce the behavior:

  1. Enable ENABLE_LE_DATA_LENGTH_EXTENSION in btstack_config.h
  2. Run example 'gatt_streamer_server'
  3. Connect from remove device 'xiaomi note11' with nrf-connect
  4. Start action 'enable notification on one of the characteristic'

Expected behavior CYW20704 send multiple packets per connection interval, and achieve 30+kB/s TX data rate. for example, if CYW20704 send 2 packets(244 bytes) per connection interval(15ms), we will got a tx data rate: (1000 packet number packet size) / conn interval = (1000 2 244) / 15 = 32.5kB/s

HCI Packet Logs HCI packet log.zip

Environment: (please complete the following information):

Additional context no.

mringwal commented 1 month ago

In LE, each side can close a connection event. It would be good to figure out which side closes the connection event in your case. Do you other devices to test with? E.g. a second setup with the CYW20704 or an ESP32? You can run le_streamer_client on the other device.

Alternatively, an air trace can also show which side stops. Our Raccoon sniffer does not support DLE yet, but others, e.g. Nordic's version support it: https://docs.nordicsemi.com/bundle/nrfutil/page/nrfutil-ble-sniffer/nrfutil-ble-sniffer_0.12.0.html

mringwal commented 1 month ago

There are no direct HCI parameter to control how many packets per connection interval is sent. You may also play with the Min/Max CE parameters, but it seems to be vendor specific how these are used. E.g. the old CSR8510 will send/receive as many ACL packets in each connection interval.

xihua13104 commented 1 month ago

Hi mringwal, Thanks for your quick response. I have captured the air log by nRF BLE sniffer. From the air log, I can see that the master only generates one connection event with the slave in each connection interval, even if there is a lot of free time in this connection interval. Can you help me find out what happened to the master? sniff-android.zip

mringwal commented 1 month ago

Thanks for the logs. The master (your phone) sends an empty pdu which allows the slave (your device) to send one PDU. In this PDU, the "more data" flag is not set, which is unexpected. The Controller (CYW20704) should have multiple buffers that are kept full all the time, which then would let it indicate that it has "more data" to send.

What baud rate do you use between STM32F407 and CYW20704? If you check the HCI log, you can find the number of LE ACL buffers (4-10) and then check if BTstack fills them at the start, providing a new packet when one has been confirmed as sent in the HCI Number Completed Packets events. (you've provided .cfa file above, which is for Teledyne radio sniffer as far as I know).

xihua13104 commented 1 month ago

I use 2M baud rate. And i see there are 15 LE ACL buffer with 251 bytes each. When we start streaming data to Phone, after a short time, the 15 LE ACL buffers are quickly filled up. Then waiting for CYW20704 to report the HCI Number Completed Packets events to give us new buffers to use. Each time CYW20704 only gives us 2 new buffers. The LE ACL buffer is always full, so there is no reason for the CYW20704 to close the connection event.

I got a new HCI Packet Log by create_packet_log.py, please take a look.
COM5_2024858414.zip

mringwal commented 3 weeks ago

In the log, it looks like the HCI Dump might slow down your HCI communication - on start, the 15 buffers should fill up in no time.

You can add #define HCI_DUMP_STDOUT_MAX_SIZE_ACL 200 in btstack_config.h to only print a short summary instead of the full message and/or increase the debug console baud rate or use SEGGER RTT (which is really fast).