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
  • Please post your questions without the AI generated "summary". It's virtually impossible to get any use _useful_ info out of all this!

  • Dear Ketiljo.

    I must admit I'm unsure what else I would need to provide. I inform you about the platform, setup, and configuration, and as my AI-generated (although post-processed) summary says, we're not sure if the configuration is sufficient or correct at all. Following the examples leaves the HCI_UART with no features, which is our observation. 

    May I ask what is unclear in the question? Would it help if I rephrased it back to human form with my severe dyslexia? I have nevertheless modified the summary in hope that it is more clear. Thanks in advance.

Reply
  • Dear Ketiljo.

    I must admit I'm unsure what else I would need to provide. I inform you about the platform, setup, and configuration, and as my AI-generated (although post-processed) summary says, we're not sure if the configuration is sufficient or correct at all. Following the examples leaves the HCI_UART with no features, which is our observation. 

    May I ask what is unclear in the question? Would it help if I rephrased it back to human form with my severe dyslexia? I have nevertheless modified the summary in hope that it is more clear. Thanks in advance.

Children
No Data
Related