nRF5340 (NORA-B126) as HCI controller for LE Audio on Raspberry Pi CM4 — pairs OK, no audio with Sony WF-1000XM6

TLDR:

I'm working on getting LE Audio working on a Raspberry Pi CM4 setup and running into some frustrating issues. I've got a u-blox NORA-B126 module (with the nRF5340 chip) connected over UART with hardware flow control acting as my Bluetooth controller.The good news is that pairing and bonding works perfectly - I can successfully connect with my Sony WF-1000XM6 earbuds and Creative Zen Hybrid Pro headphones without any problems there.But here's where I'm stuck: even though the devices pair fine, I'm not getting any actual LE Audio media sessions established. No ASE or ISO connections are being created, so there's no audio streaming happening at all. I'm starting to suspect that my nRF5340 controller configuration might not be complete. I'm wondering if my prj.conf file and device overlays aren't properly set up to give BlueZ everything it needs to bring up the LE Audio services like BAP, ASCS, PACS, and ISO support.


Hardware

  • Host: Raspberry Pi Compute Module 4 (CM4) on custom carrier

  • Controller: u-blox NORA-B126 (nRF5340)

  • HCI transport: H:4 over UART with RTS/CTS (HW flow control)

Firmware on nRF5340

  • Build: Based on samples/bluetooth/hci_uart

  • Cores: NET core runs controller; APP core runs empty_app_core

  • NCS / Zephyr: 3.1.0

  • DeviceTree / overlay: configures UART pins + flow control (see below)

  • prj.conf: controller-only with ISO options (see below)

Linux host stack

  • BlueZ: 5.82 with LE Audio enabled (BAP/ASCS/PACS)

  • PipeWire: 1.4.2 + WirePlumber  0.5.8, LC3 codec present

  • Kernel: 6.12.34+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.12.34-1+rpt1 (2025-06-26) aarch64 GNU/Linux

  • Tools: bluetoothctl, btmgmt, btmon

What works

  • hci_uart boots; controller enumerates as hci0

  • Pairing/bonding succeeds with Sony WF-1000XM6 (and Creative)

  • LE connection is maintained; standard LE control procedures succeed

What doesn’t

  • No LE Audio/ASE setup → PipeWire/WirePlumber never creates an LE Audio card

  • We see no ISO data path being brought up; media playback attempts don’t start an ASE

Repro steps (host)

  1. btmon (in a separate shell)

  2. bluetoothd -n -d (disable service first)

  3. bluetoothctl

    • power on

    • scan on → find WF-1000XM6

    • pair <addr> → succeeds

    • connect <addr> → connects

    • info <addr> → shows LE connection;

  4. PipeWire/WirePlumber started normally; LC3 available

(We can attach the btmon trace if helpful.)

Current configs

prj.conf (NET core / controller)

# =============================================================================
# NORDIC SOFTDEVICE CONTROLLER - LE AUDIO CONFIGURATION
# Target: Headset/Earbud connectivity
# =============================================================================

# =============================================================================
# CONSOLE / UART / SERIAL CONFIGURATION
# =============================================================================

CONFIG_CONSOLE=n
CONFIG_STDOUT_CONSOLE=n
CONFIG_UART_CONSOLE=n

CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y

# =============================================================================
# BLUETOOTH CORE CONFIGURATION
# =============================================================================

CONFIG_BT=y
CONFIG_BT_MAX_CONN=2

# =============================================================================
# HCI RAW MODE CONFIGURATION
# =============================================================================

# Raw HCI over UART (H:4)
CONFIG_BT_HCI_RAW=y
CONFIG_BT_HCI_RAW_H4=y
CONFIG_BT_HCI_RAW_H4_ENABLE=y

# =============================================================================
# HCI BUFFER CONFIGURATION
# =============================================================================

CONFIG_BT_BUF_ACL_TX_SIZE=255
CONFIG_BT_BUF_ACL_RX_SIZE=255
CONFIG_BT_BUF_CMD_TX_SIZE=255
CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255

# =============================================================================
# CONTROLLER SELECTION AND BASE FEATURES
# =============================================================================

# Nordic SoftDevice Controller (SDC)
CONFIG_BT_LL_SOFTDEVICE=y 
CONFIG_BT_LLL_VENDOR_NORDIC=y
CONFIG_BT_CTLR=y

CONFIG_BT_CTLR_ASSERT_HANDLER=y

# =============================================================================
# PHY CONFIGURATION
# =============================================================================

CONFIG_BT_CTLR_PHY_2M=y
CONFIG_BT_CTLR_PHY_CODED=n  
CONFIG_BT_PHY_UPDATE=y

# =============================================================================
# CONNECTION FEATURES
# =============================================================================

# Encryption
CONFIG_BT_CTLR_LE_ENC=y

# RSSI & Channel Selection
CONFIG_BT_CTLR_CONN_RSSI=y
CONFIG_BT_CTLR_CHAN_SEL_2=y

# Data Length
CONFIG_BT_CTLR_DATA_LENGTH_MAX=155

# RX Buffers
CONFIG_BT_CTLR_RX_BUFFERS=4 

# =============================================================================
# BLUETOOTH ROLES
# =============================================================================

CONFIG_BT_CENTRAL=y    
CONFIG_BT_PERIPHERAL=y  

# =============================================================================
# EXTENDED ADVERTISING
# =============================================================================

CONFIG_BT_EXT_ADV=y
CONFIG_BT_CTLR_ADV_EXT=y
CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=1650
CONFIG_BT_CTLR_ADV_SET=1 
CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=191
CONFIG_BT_EXT_ADV_MAX_ADV_SET=1

# =============================================================================
# ISO - BROADCAST (BIS) CONFIGURATION
# =============================================================================

CONFIG_BT_ISO_BROADCASTER=n 
CONFIG_BT_ISO_SYNC_RECEIVER=n 
CONFIG_BT_CTLR_ADV_ISO=n
CONFIG_BT_CTLR_SYNC_ISO=n

# =============================================================================
# ISO - CONNECTED (CIS) CONFIGURATION
# =============================================================================

CONFIG_BT_ISO_CENTRAL=y
CONFIG_BT_ISO_PERIPHERAL=n 
CONFIG_BT_CTLR_CENTRAL_ISO=y
CONFIG_BT_CTLR_PERIPHERAL_ISO=y

# CIS Configuration Parameters
CONFIG_BT_CTLR_CONN_ISO_GROUPS=1 
CONFIG_BT_CTLR_CONN_ISO_STREAMS=2 
CONFIG_BT_CTLR_CONN_ISO_STREAMS_PER_GROUP=2 
CONFIG_BT_CTLR_CONN_ISO_PDU_LEN_MAX=251 
CONFIG_BT_CTLR_CONN_ISO_LOW_LATENCY_POLICY=y 

# =============================================================================
# ISO CHANNEL AND BUFFER CONFIGURATION
# =============================================================================

# ISO Channel Configuration
CONFIG_BT_ISO_MAX_CHAN=4
CONFIG_BT_ISO_MAX_CIG=1 

# Host-side ISO Buffers
#CONFIG_BT_ISO_TX_BUF_COUNT=8
#CONFIG_BT_ISO_RX_BUF_COUNT=8
# CONFIG_BT_ISO_TX_MTU=155  
# CONFIG_BT_ISO_RX_MTU=155  

# Controller ISO Buffers
CONFIG_BT_CTLR_ISO_TX_BUFFERS=8
CONFIG_BT_CTLR_ISO_RX_BUFFERS=8
CONFIG_BT_CTLR_ISO_TX_BUFFER_SIZE=128  

CONFIG_BT_CTLR_ISO_TX_SDU_LEN_MAX=155  


# ISOAL Configuration
CONFIG_BT_CTLR_ISOAL_SOURCES=2 
CONFIG_BT_CTLR_ISOAL_SINKS=2 
CONFIG_BT_CTLR_ISOAL_PSN_IGNORE=y 

# =============================================================================
# SCHEDULER AND RESERVATION (SDC SPECIFIC)
# =============================================================================

CONFIG_BT_CTLR_SDC_CENTRAL_ACL_EVENT_SPACING_DEFAULT=10000 
CONFIG_BT_CTLR_SDC_MAX_CONN_EVENT_LEN_DEFAULT=2500
CONFIG_BT_CTLR_SDC_CIG_RESERVED_TIME_US=5000  
CONFIG_BT_CTLR_SDC_TX_PACKET_COUNT=3
CONFIG_BT_CTLR_SDC_RX_PACKET_COUNT=3 

# SDC memory optimizations:
#CONFIG_BT_CTLR_SDC_PERIPHERAL_COUNT=0 

# =============================================================================
# CONTROL PROCEDURES
# =============================================================================

# CONFIG_BT_CTLR_LLCP_LOCAL_PROC_CTX_BUF_NUM=2  

# =============================================================================
# SYSTEM CONFIGURATION
# =============================================================================

CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512

# Stack sizes
# CONFIG_ISR_STACK_SIZE=768 
# CONFIG_IDLE_STACK_SIZE=256 
# CONFIG_MAIN_STACK_SIZE=384  
# CONFIG_HEAP_MEM_POOL_SIZE=2048  

# =============================================================================
# MEMORY OPTIMIZATION
# =============================================================================

CONFIG_SIZE_OPTIMIZATIONS=y 
#CONFIG_COMPILER_OPTIMIZE_FOR_SIZE=y 
# CONFIG_ASSERT=n  # Consider for production (currently =y)
CONFIG_NO_RUNTIME_CHECKS=y 
CONFIG_PRINTK=n 
CONFIG_BOOT_BANNER=n 


# TODO - Host stuff that should not be here. but 
CONFIG_BT_SMP=y
CONFIG_BT_BAP_UNICAST_CLIENT=y
CONFIG_BT_BAP_UNICAST_CLIENT=y
CONFIG_BT_ASCS=y
#CONFIG_BT_PACS=y
CONFIG_BT_AUDIO=y

DeviceTree overlay (UART + flow control)

/* SPDX-License-Identifier: Apache-2.0 */



&uart0 {
	compatible = "nordic,nrf-uarte";
    status = "okay";
    current-speed = <1000000>;
    hw-flow-control;
    pinctrl-0 = <&uart0_default>;
    pinctrl-1 = <&uart0_sleep>;
    pinctrl-names = "default", "sleep";
};
&pinctrl {
    uart0_default: uart0_default {
        group1 {
            psels = <NRF_PSEL(UART_TX, 1,  5)>,  /* nRF TX  -> Pi GPIO13 (RXD5) */
                    <NRF_PSEL(UART_RTS, 1, 15)>; /* P1.13 = nRF RTS -> Pi CTS5 (GPIO14) */
        };
        group2 {
            psels = <NRF_PSEL(UART_RX, 1, 11)>;  /* nRF RX  <- Pi GPIO12 (TXD5) */
            bias-pull-up;
        };
        group3 {
            psels = <NRF_PSEL(UART_CTS, 1, 13)>; /* P1.15 = nRF CTS <- Pi RTS5 (GPIO15) */
            bias-pull-down;
        };
    };

    uart0_sleep: uart0_sleep {
        group1 {
            psels = <NRF_PSEL(UART_TX, 1,  5)>,  /* nRF TX  -> Pi GPIO13 (RXD5) */
                    <NRF_PSEL(UART_RTS, 1, 15)>; /* P1.13 = nRF RTS -> Pi CTS5 (GPIO14) */
        };
        group2 {
            psels = <NRF_PSEL(UART_RX, 1, 11)>;  /* nRF RX  <- Pi GPIO12 (TXD5) */
            bias-pull-up;
        };
        group3 {
            psels = <NRF_PSEL(UART_CTS, 1, 13)>; /* P1.15 = nRF CTS <- Pi RTS5 (GPIO15) */
            bias-pull-down;
        };
    };

};

&bt_hci_sdc {
	status = "okay";
};

What we’d like guidance on

  1. Minimal Kconfig for LE Audio (CIS) when using nRF5340 as a pure HCI controller with BlueZ as the host:

    • Which SoftDevice Controller (SDC) symbols must be enabled for ISO/CIS?

    • Are there additional options required so BlueZ can perform BAP/ASCS/PACS and ISO setup over HCI?

  2. Architecture choice:For stability today, do you recommend:

    • a) HCI-offload (Linux handles BAP/ASCS/LC3, nRF5340 is controller only), or

    • b) the nRF5340 LE Audio APP/NET samples (with I2S/PCM on the SoC) and a simpler interface to Linux?
      We’ve previously succeeded with APP/NET + I2S, but would prefer BlueZ-driven LE Audio if it’s fully supported.

  3. Interoperability: Any known issues (current NCS/SDC) with Sony WF-1000XM6 unicast sink scenarios when driven via HCI from Linux?

  4. HCI commands: Does the nRF5340 controller require any vendor-specific HCI (e.g., data path configuration) for ISO when the host is BlueZ/PipeWire? If yes, which ones should be enabled/invoked?

  5. UART transport best practices: Recommended baud rate/flow control and buffering for H:4 with ISO traffic on nRF5340 to avoid dropped packets. We are struggling with RTS/CTS hanging. Should we use USB instead?

  6. Expected trace: Could you share a short btmon example of a successful ASE/ISO bring-up (unicast sink) so we can compare where ours diverges?

Notes

  • We’re focusing on Sony WF-1000XM6 first (we’re aware of various Creative quirks).

  • BlueZ, PipeWire, and WirePlumber are configured for LE Audio/LC3 and appear healthy; the missing piece seems to be controller capabilities/config for ISO.

Thanks in advance for pointing out the required Kconfig/SDC options and whether HCI-offload is expected to work smoothly for LE Audio unicast sink today on the nRF5340.

Parents
  • Hello, 

    Minimal Kconfig for LE Audio (CIS) when using nRF5340 as a pure HCI controller with BlueZ as the host:

    • Which SoftDevice Controller (SDC) symbols must be enabled for ISO/CIS?

    • Are there additional options required so BlueZ can perform BAP/ASCS/PACS and ISO setup over HCI?

    Using the prj.conf for IPC radio in the nRF5340 Audio application is a good starting point to get ISO/CIS working in other projects. See for example bap_unicast_client.zip (attached) where I included IPC radio firmware as the network core image for the bap_unicast_client sample and modified the sample configuration to use IPC radio instead of hci_ipc. 

    bap_unicast_client.zip

    Regarding the use case where the nRF5340 is only the controller, you should have some forwarding firmware on the application core to relay HCI traffic between the net core and the BlueZ host. 

    Architecture choice:For stability today, do you recommend:

    • a) HCI-offload (Linux handles BAP/ASCS/LC3, nRF5340 is controller only), or

    • b) the nRF5340 LE Audio APP/NET samples (with I2S/PCM on the SoC) and a simpler interface to Linux?
      We’ve previously succeeded with APP/NET + I2S, but would prefer BlueZ-driven LE Audio if it’s fully supported.

    We offer full support for the configuration where nRF5340 is used for the host and controller. That being said, I know there are other people who use a similar setup as you. Please see this case from another DevZone user, who was using the (now deprecated) dedicated LE Audio controller, and got it working with a sample (broadcast_audio_source, now renamed to bap_broadcast_source) from Zephyr and some additional Kconfig symbols you can find in the ticket. In your case, the starting application would be bap_unicast_client.

    b) Regarding what is supported by BlueZ, please find answers from BlueZ documentation and source code directly. 

    Interoperability: Any known issues (current NCS/SDC) with Sony WF-1000XM6 unicast sink scenarios when driven via HCI from Linux?

    As far as I can tell from searching for Sony WF-1000XM6 it is not yet released. For WF-1000XM5, there was an issue with nRF Connect SDK v2.6.0 about no audio playback on either of the buds which was resolved by adding some extra Kconfig symbols to the project. You can find the relevant case here:  nRF5340 Audio DK [GATEWAY][UNICAST_CLIENT] -- Unable to stream audio to earbud from the DK . 
    Note that they are using the nRF5340 Audio application, so the relevancy of it depends a lot on how similar your project is to that.  

    HCI commands: Does the nRF5340 controller require any vendor-specific HCI (e.g., data path configuration) for ISO when the host is BlueZ/PipeWire? If yes, which ones should be enabled/invoked?

    VS HCI commands are needed for timestamp reading, i.e. when syncing peripheral devices. 

    Regarding if certain VS commands are needed when using another host (than the Zephyr host) this is unclear.

    UART transport best practices: Recommended baud rate/flow control and buffering for H:4 with ISO traffic on nRF5340 to avoid dropped packets. We are struggling with RTS/CTS hanging. Should we use USB instead?

    For uncompressed audio, USB or I2S is recommended. 

    In your case the audio would be compressed since it is moving from the host to the controller. So you would have to choose a baud rate which is sufficient to handle the bit rate for the encoded audio. What this baud is depends on what your codec configuration setting is.

    Based on previous experience, most implementations don't use flow control, so if you are having issues when flow control is enabled, please share some more details on your configuration and possible related symptoms. 

    Expected trace: Could you share a short btmon example of a successful ASE/ISO bring-up (unicast sink) so we can compare where ours diverges?

    We have not done any internal data collection on this setup, unfortunately. 

    That being said, another DevZone user got a similar setup working with the (now deprecated) dedicated LE Audio controller. The configurations which solved their setup are identical or similar to configurations needed with the SoftDevice Controller. Please check out their ticket here:  Use native_posix and nrf5340 audio DK controller  

    Best regards,

    Maria

Reply
  • Hello, 

    Minimal Kconfig for LE Audio (CIS) when using nRF5340 as a pure HCI controller with BlueZ as the host:

    • Which SoftDevice Controller (SDC) symbols must be enabled for ISO/CIS?

    • Are there additional options required so BlueZ can perform BAP/ASCS/PACS and ISO setup over HCI?

    Using the prj.conf for IPC radio in the nRF5340 Audio application is a good starting point to get ISO/CIS working in other projects. See for example bap_unicast_client.zip (attached) where I included IPC radio firmware as the network core image for the bap_unicast_client sample and modified the sample configuration to use IPC radio instead of hci_ipc. 

    bap_unicast_client.zip

    Regarding the use case where the nRF5340 is only the controller, you should have some forwarding firmware on the application core to relay HCI traffic between the net core and the BlueZ host. 

    Architecture choice:For stability today, do you recommend:

    • a) HCI-offload (Linux handles BAP/ASCS/LC3, nRF5340 is controller only), or

    • b) the nRF5340 LE Audio APP/NET samples (with I2S/PCM on the SoC) and a simpler interface to Linux?
      We’ve previously succeeded with APP/NET + I2S, but would prefer BlueZ-driven LE Audio if it’s fully supported.

    We offer full support for the configuration where nRF5340 is used for the host and controller. That being said, I know there are other people who use a similar setup as you. Please see this case from another DevZone user, who was using the (now deprecated) dedicated LE Audio controller, and got it working with a sample (broadcast_audio_source, now renamed to bap_broadcast_source) from Zephyr and some additional Kconfig symbols you can find in the ticket. In your case, the starting application would be bap_unicast_client.

    b) Regarding what is supported by BlueZ, please find answers from BlueZ documentation and source code directly. 

    Interoperability: Any known issues (current NCS/SDC) with Sony WF-1000XM6 unicast sink scenarios when driven via HCI from Linux?

    As far as I can tell from searching for Sony WF-1000XM6 it is not yet released. For WF-1000XM5, there was an issue with nRF Connect SDK v2.6.0 about no audio playback on either of the buds which was resolved by adding some extra Kconfig symbols to the project. You can find the relevant case here:  nRF5340 Audio DK [GATEWAY][UNICAST_CLIENT] -- Unable to stream audio to earbud from the DK . 
    Note that they are using the nRF5340 Audio application, so the relevancy of it depends a lot on how similar your project is to that.  

    HCI commands: Does the nRF5340 controller require any vendor-specific HCI (e.g., data path configuration) for ISO when the host is BlueZ/PipeWire? If yes, which ones should be enabled/invoked?

    VS HCI commands are needed for timestamp reading, i.e. when syncing peripheral devices. 

    Regarding if certain VS commands are needed when using another host (than the Zephyr host) this is unclear.

    UART transport best practices: Recommended baud rate/flow control and buffering for H:4 with ISO traffic on nRF5340 to avoid dropped packets. We are struggling with RTS/CTS hanging. Should we use USB instead?

    For uncompressed audio, USB or I2S is recommended. 

    In your case the audio would be compressed since it is moving from the host to the controller. So you would have to choose a baud rate which is sufficient to handle the bit rate for the encoded audio. What this baud is depends on what your codec configuration setting is.

    Based on previous experience, most implementations don't use flow control, so if you are having issues when flow control is enabled, please share some more details on your configuration and possible related symptoms. 

    Expected trace: Could you share a short btmon example of a successful ASE/ISO bring-up (unicast sink) so we can compare where ours diverges?

    We have not done any internal data collection on this setup, unfortunately. 

    That being said, another DevZone user got a similar setup working with the (now deprecated) dedicated LE Audio controller. The configurations which solved their setup are identical or similar to configurations needed with the SoftDevice Controller. Please check out their ticket here:  Use native_posix and nrf5340 audio DK controller  

    Best regards,

    Maria

Children
No Data
Related