esp-hosted
esp-hosted copied to clipboard
Wifi/BT co-existance mode for A2DP streaming
I'm looking for Wifi/BT co-existance solution for A2DP streaming. In another issue, you mentioned that you already tested this setup. I would appreciate any information on that. Especially how to configure the bluetooth component to get reliable streaming without dropouts. Is there a firmware that I could adapt and test? Any flavor - NG or FG - would be of interest to me. I'm using only SPI for transport.
This is the original post from the other issue:
As you had only asked BLE + Wi-Fi, I did not mention, but we also have tested Wi-Fi + A2DP (music streaming) Classic BT at the same time, without any stuttering of Bluetooth.
In this case, the Wi-Fi throughput is a little reduced from peak throughput. Basically, bandwidth and time is shared in between Wi-Fi & Bluetooth.
Originally posted by @mantriyogesh in https://github.com/espressif/esp-hosted/issues/164#issuecomment-1270027017
Hello @clwe
Yes you can use ESP-Hosted-FG SPI only for this. We will need to create separate binaries for co-ex setup where we had optimised Wi-Fi + Classic BT A2DP working.
As ESP32 has single radio, which is time shared, the default scheduling may get you Classic BT with Glitches. With the optimised binaries and scheduling, Classic BT will be always preferred on the radio over Wi-Fi, which will give smooth A2DP experience.
Can you please let us know if ESP-Hosted-FG solution is already working for you with master or release 0.0.5? Once that is working (Wi-Fi alone & Classic BT A2DP alone), please let us know. We will create special binaries for you then.
Hello @mantriyogesh
Wifi alone is working for me on the current master branch. I tested the A2DP example as a standalone firmware and can confirm that it works. I was trying to work my way through integrating the A2DP example into the ESP-Hosted-FG firmware with no success yet. It is not impossible to do, but needs some development time. If there is anything ready at hand I would be very thankful.
-
Can you please let us know what Bluetooth stack you are using on Linux for A2DP? We had tested A2DP with Bluez stack earlier. Bluez version, Kernel version, Linux distribution type (e.g. debian) would be helpful to know
-
A2DP also need some additional software in Linux, apart from Bluetooth stack like pulseaudio and kernel module of pulseaudio. Service or daemon logs of 'bluetooth' i.e. Bluez will help to know some obvious issues. 'service Bluetooth status' (it really depends on which Linux distribution you use, if systemctl or service commands are supported. For now I assumed debian /ubuntu based distribution which generally people use)
-
Getting the higher layer config like pulseaudio etc is out of scope of ESP-Hosted, but we can help as much as we can/know.
-
Can you please exactly point till what point you have integrated the A2DP with ESP-Hosted and any specific errors or questions that you face?
- Our platform is a Debian based Linux distribution running on an embedded board. Bluez is v.5.43, but could be updated if necessary, the Kernel version is 4.14.
- Thanks for pointing this out, we are ready to install additional software.
- Thanks again, no problem, we will deal with that at a later point in time, I guess.
- In
sdkconfig
I made the following changes:
CONFIG_BT_BLUEDROID_ENABLED=y
CONFIG_BLUEDROID_ENABLED=y
CONFIG_CLASSIC_BT_ENABLED=y
CONFIG_A2DP_ENABLE=y
CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y
I then tried to add the A2DP initialization code from the A2DP example firmware to the bluetooth_initialize()
in slave_bt.c
in esp-hosted.
esp_bluedroid_init();
esp_bluedroid_enable();
esp_bt_dev_set_device_name("ESP32");
esp_a2d_register_callback(a2dp_callback);
esp_a2d_source_register_data_callback(data_callback);
esp_a2d_source_init();
a2dp_callback
and data_callback
are empty stubs returning 0 or doing nothing.
Maybe not emptying/filling the input/output queues is the problem?
I get the following crash log from the serial connection:
I (13) boot: ESP-IDF v5.0.1 2nd stage bootloader
I (13) boot: compile time 23:13:23
I (13) boot: chip revision: v3.0
I (15) boot.esp32: SPI Speed : 40MHz
I (20) boot.esp32: SPI Mode : DIO
I (24) boot.esp32: SPI Flash Size : 4MB
I (29) boot: Enabling RNG early entropy source...
I (34) boot: Partition Table:
I (38) boot: ## Label Usage Type ST Offset Length
I (45) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (53) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (60) boot: 2 factory factory app 00 00 00010000 00177000
I (68) boot: End of partition table
I (72) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=45a7ch (285308) map
I (183) esp_image: segment 1: paddr=00055aa4 vaddr=3ffbdb60 size=05248h ( 21064) load
I (192) esp_image: segment 2: paddr=0005acf4 vaddr=40080000 size=05324h ( 21284) load
I (201) esp_image: segment 3: paddr=00060020 vaddr=400d0020 size=104bd4h (1067988) map
I (587) esp_image: segment 4: paddr=00164bfc vaddr=40085324 size=19508h (103688) load
I (645) boot: Loaded app from partition at offset 0x10000
I (645) boot: Disabling RNG early entropy source...
I (657) cpu_start: Pro cpu up.
I (657) cpu_start: Starting app cpu, entry point is 0x400813f4
0x400813f4: call_start_cpu1 at /home/clemens/esp/esp-idf/components/esp_system/port/cpu_start.c:142
I (651) cpu_start: App cpu up.
I (673) cpu_start: Pro cpu start user code
I (673) cpu_start: cpu freq: 240000000 Hz
I (673) cpu_start: Application information:
I (678) cpu_start: Project name: network_adapter
I (684) cpu_start: App version: 588ca77-dirty
I (689) cpu_start: Compile time: Apr 1 2023 23:13:17
I (695) cpu_start: ELF file SHA256: 00f4bacaa4d01862...
I (701) cpu_start: ESP-IDF: v5.0.1
I (706) cpu_start: Min chip rev: v0.0
I (711) cpu_start: Max chip rev: v3.99
I (716) cpu_start: Chip rev: v3.0
I (721) heap_init: Initializing. RAM available for dynamic allocation:
I (728) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (734) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (740) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (746) heap_init: At 3FFD0548 len 0000FAB8 (62 KiB): DRAM
I (752) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (758) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (765) heap_init: At 4009E82C len 000017D4 (5 KiB): IRAM
I (772) spi_flash: detected chip: generic
I (776) spi_flash: flash io: dio
W (780) spi_flash: Detected size(8192k) larger than the size in the binary image header(4096k). Using the size in the binary image header.
I (794) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (808) NETWORK_ADAPTER: *********************************************************************
I (814) NETWORK_ADAPTER: ESP-Hosted-FG Firmware version :: 0.0.5
I (822) NETWORK_ADAPTER: Transport used :: SPI only
I (830) NETWORK_ADAPTER: *********************************************************************
I (838) NETWORK_ADAPTER: Supported features are:
I (842) NETWORK_ADAPTER: - WLAN over SPI
I (846) ESP_BT: - BT/BLE
I (848) ESP_BT: - HCI Over SPI
I (850) ESP_BT: - BT/BLE dual mode
I (854) NETWORK_ADAPTER: capabilities: 0xf8
I (870) BTDM_INIT: BT controller compile version [60aae55]
I (872) system_api: Base MAC address is not set
I (872) system_api: read default base MAC address from EFUSE
I (878) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07
W (1300) BT_BTC: A2DP Enable without AVRC
I (1308) NETWORK_ADAPTER: ESP Bluetooth MAC addr: ac: b:fb:6c:fa:3a
I (1310) bt_tx: 0x3ffd1302 04 0e 04 05 52 0c 00 |....R..|
assert failed: xQueueGenericSend queue.c:827 (pxQueue)
Backtrace: 0x40081f06:0x3ffd4e20 0x40091635:0x3ffd4e40 0x40098969:0x3ffd4e60 0x40091e97:0x3ffd4f80 0x400d92bc:0x3ffd4fc0 0x400d938e:0x3ffd4ff0 0x4015273a:0x3ffd5030 0x40141b32:0x3ffd5050 0x4001791d:0x3ffd5070 0x401423b5:0x3ffd5090 0x40142492:0x3ffd50d0 0x400188f5:0x3ffd5100 0x40141d7b:0x3ffd5140 0x4005185b:0x3ffd5160 0x4005244d:0x3ffd5180 0x40052a59:0x3ffd51a0 0x40085028:0x3ffd51c0 0x40019d11:0x3ffd51f0 0x40055b4d:0x3ffd5210 0x401403e3:0x3ffd5230 0x40140a41:0x3ffd5250 0x40094d59:0x3ffd5280
0x40081f06: panic_abort at /home/clemens/esp/esp-idf/components/esp_system/panic.c:423
0x40091635: esp_system_abort at /home/clemens/esp/esp-idf/components/esp_system/esp_system.c:153
0x40098969: __assert_func at /home/clemens/esp/esp-idf/components/newlib/assert.c:78
0x40091e97: xQueueGenericSend at /home/clemens/esp/esp-idf/components/freertos/FreeRTOS-Kernel/queue.c:827 (discriminator 1)
0x400d92bc: send_to_host_queue at /home/clemens/workspace/code/github/bela/esp-hosted-versions/esp-hosted-bela/esp_hosted_fg/esp/esp_driver/network_adapter_a2dp_source/main/app_main.c:464
0x400d938e: host_rcv_pkt at /home/clemens/workspace/code/github/bela/esp-hosted-versions/esp-hosted-bela/esp_hosted_fg/esp/esp_driver/network_adapter_a2dp_source/main/slave_bt.c:82
0x4015273a: vhci_send at ??:?
0x40141b32: r_eif_send at ??:?
0x401423b5: hci_tx_start at hci_tl.c:?
0x40142492: r_hci_tl_send at ??:?
0x40141d7b: r_hci_send_2_host_hack at ??:?
0x40085028: ke_task_schedule at ke_task.c:?
0x401403e3: r_rw_schedule at ??:?
0x40140a41: btdm_controller_task at ??:?
0x40094d59: vPortTaskWrapper at /home/clemens/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:154
You don't need to add any code. Bluetooth stack (Bluez) at Host should be enough. We are making use of standard HCI interface. So BT stack runs on host and BT controller running over ESP.
Bluez exposes HCI interface already and hence Classic BT will be directly supported over Linux using Bluez.
Bluetooth controller from ESP32 chip expose Classic BT OR BLE OR dual mode(both).
You just need to install pulseaudio and you should directly be able to use 'bluetoothctl' command at Linux user space.
I would suggest to get simple Bluetooth streaming (A2DP music streaming) first. This should be straightforward without any code change at both ESP and Host side ESP-HOSTED code.
You can later customise how you want, once sample A2DP is tested. (may not even be needed for general use cases)
https://raspberrypi.stackexchange.com/questions/28811/raspbian-jessie-how-do-i-properly-setup-a2dp-with-bluez5-and-pulseaudio
Example with Raspberry Pi
Thanks! I initially assumed that the firmware is generic and can be used with different profiles implemented by the host but found no documentation how bluez would accomplish that. I.e., I read through bluetooth-for-linux-developers-study-guide and found no information regarding A2DP. Unfortunately I cannot connect to devices with A2DP protocol now. (A basic connection to a phone works).
[NEW] Device B8:69:C2:DD:D0:D0 JBL GO
[bluetooth]# connect B8:69:C2:DD:D0:D0
Attempting to connect to B8:69:C2:DD:D0:D0
[CHG] Device B8:69:C2:DD:D0:D0 Connected: yes
[CHG] Device B8:69:C2:DD:D0:D0 UUIDs: 00001108-0000-1000-8000-00805f9b34fb
[CHG] Device B8:69:C2:DD:D0:D0 UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
[CHG] Device B8:69:C2:DD:D0:D0 UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device B8:69:C2:DD:D0:D0 UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device B8:69:C2:DD:D0:D0 UUIDs: 0000111e-0000-1000-8000-00805f9b34fb
[CHG] Device B8:69:C2:DD:D0:D0 UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device B8:69:C2:DD:D0:D0 ServicesResolved: yes
Failed to connect: org.bluez.Error.Failed
[CHG] Device B8:69:C2:DD:D0:D0 RSSI: -37
[CHG] Device B8:69:C2:DD:D0:D0 ServicesResolved: no
[CHG] Device B8:69:C2:DD:D0:D0 Connected: no
[bluetooth]# exit
[DEL] Controller AC:0B:FB:6C:FA:3A xxxx [default]
root@xxxx:~/workspace/# bluetoothctl --version
5.43
systemctl status bluetooth
show the following:
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2023-04-23 12:24:44 UTC; 53min ago
Docs: man:bluetoothd(8)
Main PID: 658 (bluetoothd)
Status: "Running"
Tasks: 1 (limit: 4915)
CGroup: /system.slice/bluetooth.service
└─658 /usr/lib/bluetooth/bluetoothd
Apr 23 12:24:44 bela bluetoothd[658]: Failed to obtain handles for "Service Changed" characteristic
Apr 23 12:24:44 bela bluetoothd[658]: Sap driver initialization failed.
Apr 23 12:24:44 bela bluetoothd[658]: sap-server: Operation not permitted (1)
Apr 23 12:25:58 bela bluetoothd[658]: a2dp-sink profile connect failed for B8:69:C2:DD:D0:D0: Protocol not available
Apr 23 12:58:25 bela bluetoothd[658]: a2dp-sink profile connect failed for B8:69:C2:DD:D0:D0: Protocol not available
It seems that at least with my old bluez version I cannot connect to a bluetooth speaker. In this case a "JBL Go" speaker. I can establish a connection to my phone. I think before installing the pulseaudio plugin, I could establish a basic data transfer connection to my laptop. But I'm not totally sure about it, since I was testing different platforms a while ago.
pulseaudio-module-bluetooth
is installed. I will try to update bluez by compiling it.
After updating to bluez v.5.66 the behavior stays the same but I get different error messages from systemctl logs:
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2023-04-23 13:33:50 UTC; 1min 53s ago
Docs: man:bluetoothd(8)
Main PID: 748 (bluetoothd)
Status: "Running"
Tasks: 1 (limit: 4915)
CGroup: /system.slice/bluetooth.service
└─748 /usr/libexec/bluetooth/bluetoothd
Apr 23 13:33:50 bela bluetoothd[748]: src/plugin.c:plugin_init() Failed to init vcp plugin
Apr 23 13:33:50 bela bluetoothd[748]: profiles/audio/mcp.c:mcp_init() D-Bus experimental not enabled
Apr 23 13:33:50 bela bluetoothd[748]: src/plugin.c:plugin_init() Failed to init mcp plugin
Apr 23 13:33:50 bela bluetoothd[748]: profiles/audio/bap.c:bap_init() D-Bus experimental not enabled
Apr 23 13:33:50 bela bluetoothd[748]: src/plugin.c:plugin_init() Failed to init bap plugin
Apr 23 13:33:50 bela bluetoothd[748]: Bluetooth management interface 1.14 initialized
Apr 23 13:33:50 bela bluetoothd[748]: src/adapter.c:reset_adv_monitors_complete() Failed to reset Adv Monitors: Unknown Command (0x01)
Apr 23 13:33:51 bela bluetoothd[748]: src/device.c:store_device_info_cb() Unable set contents for /var/lib/bluetooth/AC:0B:FB:6C:FA:3A/04:ED:33:C0:E8:D2/info: (Failed to create file '/var/lib/bluetooth/AC:0B:FB:6C:FA:3A/04:ED:33:C0:E8:D
Apr 23 13:34:29 bela bluetoothd[748]: src/service.c:btd_service_connect() a2dp-sink profile connect failed for 04:ED:33:C0:E8:D2: Protocol not available
Apr 23 13:34:29 bela bluetoothd[748]: src/service.c:btd_service_connect() a2dp-source profile connect failed for 04:ED:33:C0:E8:D2: Protocol not available
Protocol not available is typical pulseaudio config issue. Please try to Google about this issue.
If scan is working the HCI connection is verified end to end. Basically ESP-Hosted is fine. But user space apps like pulseaudio may need some attention till the point it gets working. Worth to kill pulseaudio , force kill if not killed, re-start pulseaudio from terminal. Sudo service Bluetooth restart
Just suggestion - Try to do switch off the scan when you do not need to scan to let bandwidth (radio) open for other messages.
https://youtu.be/g14aEjnjRLw Jump to 18.42
Thanks alot! It seems the culprit was pulseaudio not being started at all. I can at least connect to a speaker now. Now I just need to figure out how to configure pulseaudio for a root user (system wide) install, since we do not have users on our embedded device.
there are multiple ways to start the application on boot once like registration of new service or init.d or rc.local or rc start scripts etc, one or many of which your Linux would be supporting (you may be well aware of those ways)
But, I think there would be standard daemon pulseaudio would have registered on you Linux already, which might not be running correctly (may be getting killed while booting), fixing that might be better option in my opinion.
any updates further?
Thanks for your help! I finally integrated bluez with bluez-alsa, since we have a headless embedded system without a pulseaudio-server. That works just fine out of the box (but needs to be compiled). I didn't notice dropouts of the bluetooth audio stream, when I was connected via wifi at the same time, even while downloading a big file. Maybe I need further testing. Is there some arbitration between BT/Wifi already implemented?
Are you using Classic BT or BLE?
We used to use the rf fix in earlier ESP-IDF versions. but not tested in latest IDF. So I am not entirely sure if latest IDFs have any fixes for it. Even in earlier IDFs default algorithm was in place to do rf scheduling, which may have any changes.
Anyway in case you feel some issues, do let us know.
But please do keep in mind, RF is shared in between Bluetooth and Wi-Fi. Bluetooth (specially Classic BT) is latency sensitive and hence might be given priority than Wi-Fi (Wi-Fi can be worked out with TCP re-transmissions etc in case of RF unavailability for longer times).