Can nRF5340 keep two links simultaneously? One BLE audio link with another nRF5340, one custom BLE link with Smart Phone for configuration

Hi,

I have kept following BLE audio since the nRF5340 audio DK was available. Recently, we came up with an idea of developing a broadcasting system. While we demoed the idea to potential customer, they required to control the BLE audio nodes with phone app, such as volume up, mute, etc. Is it possible to make a nRF5340 keep connected with 2 devices at the same time, one is on BLE audio, and another is a phone with normal BLE support? If not simultaneously, could be in the same firmware?

Thank you

Junmin

Parents
  • Hello Junmin,

    While we demoed the idea to potential customer, they required to control the BLE audio nodes with phone app, such as volume up, mute, etc. Is it possible to make a nRF5340 keep connected with 2 devices at the same time, one is on BLE audio, and another is a phone with normal BLE support? If not simultaneously, could be in the same firmware?

    Do I understand you correctly that you would like to make a broadcaster (BIS), that also connects to a phone over regular BLE connection (ACL connection) in order to control the broadcast's volume etc.?

    If I have understood you correctly, the answer is:
    Yes - you can add a peripheral or central role to the nRF5340 LE Audio reference application, no problem.
    The current controller is able to hold 2 concurrent ACL connections (regular BLE connections) in addition to the 1 or 2 BIS channels.

    If I have not understood you correctly, could you share a quick diagram for your intended topology, so that I can better understand what you would like to achieve?

    Best regards,
    Karl

  • Hello Karl,

    You understood me pretty well, thank you.

    Actually, in addition to broadcaster volume control, we'd like to control receiver volume independently also, but that's the same thing as broadcaster if we can add a peripheral or central role to receivers. I'll try you suggestion next week.

    Thank you for positive feedback before weekend.Smile

    Have a great weekend

    Junmin

  • Hello Karl,

    I tried today, but did get some issues.

    1. In order to add a ASL connection, it seems I can start from ble_core_init(ble_core_ready_t ready_callback) in ble_core.c or le_audio_enable(le_audio_rx_data_handler, audio_datapath_sdu_ref_update) defined in 4 different files with le_audio_cis_headset.c as default. However, I have no idea how to do further.

    2. I'd like add peripheral role in nRF5340 LE Audio DK to work with nRF Connect for Mobile or Nordic UART in nRF Toolbox for Bluetooth LE, but I can't scan nRF5340 Audio yet with the unchanged reference application in SDK 2.4.

    Regards

    Junmin

  • Hello Junmin,

    1. Did you also add the necessary changes to your prj.conf, to support the additional ACL link? I am not sure if I understand what you mean about it being defined in 4 different places, but please do not make any changes directly to the LE Audio architecture files like audio_datapath since this is not recommended as this might break something else unexpectedly.

    2. You can use this example as a reference for how to implement this - it is made for v2.3.0, but the steps are identical for v2.4.0.

    Best regards,
    Karl

  • Hello Karl,

    Per your suggestions, I created a new application with nRF5340 LE Audio reference application as template, and furthermore, I created a dedicated thread to run peripheral ISO, using the example you mentioned as reference. Also, prj.conf was modified according to the example. The console outputs are as following, could you give some clues to fix the err "Unable to register ISO server"?

    Thank you and Best Regards

    Junmin

    *** Booting Zephyr OS build v3.3.99-ncs1 ***
    HL [00:00:00.257,476] <inf> fw_info: fw_info_app_print:
    nRF5340 Audio nRF5340 Audio DK cpuapp
    NCS base version: 2.4.0
    Cmake run : Fri Aug 04 20:29:26 2023
    HL [00:00:00.257,507] <inf> fw_info: fw_info_app_print: ------- DEBUG BUILD -------
    HL [00:00:00.257,507] <inf> fw_info: fw_info_app_print: HEADSET left device
    HL [00:00:00.268,127] <inf> board_version: board_version_valid_check: Compatible board/HW version found: 1.0.0
    HL [00:00:00.302,490] <wrn> bt_hci_core: set_flow_control: Controller to host flow control not supported
    HL [00:00:00.307,556] <inf> bt_hci_core: bt_dev_show_info: Identity: C7:48:40:57:8F:D4 (random)
    HL [00:00:00.307,586] <inf> bt_hci_core: bt_dev_show_info: HCI: version 5.2 (0x0b) revision 0x0d15, manufacturer 0x07e8
    HL [00:00:00.307,617] <inf> bt_hci_core: bt_dev_show_info: LMP: version 5.2 (0x0b) subver 0x0d15
    HL [00:00:00.433,776] <inf> ble: mac_print: MAC: 44:43:CF:DA:0F:E1 (random)
    HL [00:00:00.433,990] <inf> ble: on_bt_ready: Controller version: 3349
    HL [00:00:00.527,862] <inf> ble_iso: uart_control_sub_thread: Bluetooth initialized
    HL [00:00:00.527,893] <inf> ble_iso: uart_control_sub_thread: Unable to register ISO server (err -112)
    HL [00:00:00.528,137] <inf> cis_headset: advertising_process: Advertising successfully started

  • Hello again, Junmin

    Junmin said:
    The console outputs are as following, could you give some clues to fix the err "Unable to register ISO server"?

    The -112 error code means 'address already in use', could it be that you are attempting to use the same instance as your CIS ACL for your NUS service?

    For future reference, please use the Insert->Code option when sharing code or logs here on DevZone.

    On a general note I would also recommend that you use the latest 3393 controller version.

    Best regards,
    Karl

  • Hello Karl,

    I checked my code and did some experiments, you are right, I'm attempting to use the same CIS ACL for NUS service. I though a lot and reviewed other people's related questions in DevZone, but still have no idea how to fix it, any suggestions?

    By the way, I have upgraded my code with the latest 3393 controller version.

    Best Regards

    Junmin

Reply Children
  • 	err = bt_enable(NULL);
    	if (err) {
    		LOG_INF("Bluetooth init failed (err %d)", err);
    		return;
    	}
    
    	if (IS_ENABLED(CONFIG_SETTINGS)) {
    		settings_load();
    	}
    
    	LOG_INF("Bluetooth initialized");
    
    	err = bt_iso_server_register(&iso_server);
    	if (err) {
    		LOG_INF("Unable to register ISO server (err %d)", err);
    		return;
    	}
    
    	err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
    	if (err) {
    		LOG_INF("Advertising failed to start (err %d)", err);
    		return;
    	}

    *** Booting Zephyr OS build v3.3.99-ncs1 ***
    HL [00:00:00.257,446] <inf> fw_info: fw_info_app_print: 
             nRF5340 Audio nRF5340 Audio DK cpuapp                      
             NCS base version: 2.4.0                            
             Cmake run : Wed Aug 09 23:30:14 2023
    HL [00:00:00.257,446] <inf> fw_info: fw_info_app_print: ------- DEBUG BUILD -------
    HL [00:00:00.257,446] <inf> fw_info: fw_info_app_print: HEADSET left device
    HL [00:00:00.268,066] <inf> board_version: board_version_valid_check: Compatible board/HW version found: 1.0.0
    HL [00:00:00.302,551] <wrn> bt_hci_core: set_flow_control: Controller to host flow control not supported
    HL [00:00:00.307,586] <inf> bt_hci_core: bt_dev_show_info: Identity: D4:A5:74:D6:1E:9F (random)
    HL [00:00:00.307,617] <inf> bt_hci_core: bt_dev_show_info: HCI: version 5.2 (0x0b) revision 0x0d41, manufacturer 0x07e8
    HL [00:00:00.307,617] <inf> bt_hci_core: bt_dev_show_info: LMP: version 5.2 (0x0b) subver 0x0d41
    HL [00:00:00.433,502] <inf> ble: mac_print: MAC: 79:DD:C1:19:AE:31 (random)
    HL [00:00:00.433,715] <inf> ble: on_bt_ready: Controller version: 3393
    HL [00:00:00.527,954] <inf> ble_iso: uart_control_sub_thread: Bluetooth init failed (err -120)
    HL [00:00:00.528,228] <inf> cis_headset: advertising_process: Advertising successfully started

  • Hello Karl,

    I'm still waiting for you suggestions. At the same time, I'm trying to take the following discussion as reference,

     nRF5340 Audio DK: LE Audio and UART2 Concurrently 

    Since it's based on NCS 2.20, I'll go down to this version first.

    Any comments?

    Best Regards

    Junmin

  • Hello Junmin,

    Thank you for your extreme patience with this - I was unfortunately out of office for the first few days of this week due to sickness, but now I am back.

    Junmin said:
    I checked my code and did some experiments, you are right, I'm attempting to use the same CIS ACL for NUS service. I though a lot and reviewed other people's related questions in DevZone, but still have no idea how to fix it, any suggestions?

    I see from your latest log that you receive the -120 error (operation already in progress) from your call to start, but it is hard for me to understand the context from which the bt_enable call was made from the code you have shared alone.
    Could you share your full main.c with me, so that I may take a look?

    Judging by this error message alone I wonder if you might be calling bt_enable elsewhere, such as in your uart_control_sub_thread? If so, please know that you only need to call bt_enable once in your main().

    Junmin said:

    At the same time, I'm trying to take the following discussion as reference,

     nRF5340 Audio DK: LE Audio and UART2 Concurrently 

    Since it's based on NCS 2.20, I'll go down to this version first.

    In this case I would recommend that you instead try the same approach with v2.4, instead of downgrading to v2.2, since there are so many important LE Audio related features and improvements that have been introduced since v2.2.

    Best regards,
    Karl

  • Hello Karl,

    Glad to know you are back from sickness!

    My main.c is as following, just adding several line on the reference application. I tried to comment out bt_enable in my thread, the error code became -112, address already in use.

    /*
     * Copyright (c) 2018 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/kernel.h>
    #include <zephyr/debug/stack.h>
    #include <zephyr/device.h>
    #include <string.h>
    
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/settings/settings.h>
    #include <zephyr/zbus/zbus.h>
    
    #include "macros_common.h"
    #include "fw_info_app.h"
    #include "led.h"
    #include "button_handler.h"
    #include "button_assignments.h"
    #include "nrfx_clock.h"
    #include "ble_core.h"
    #include "sd_card.h"
    #include "board_version.h"
    #include "audio_system.h"
    #include "channel_assignment.h"
    #include "streamctrl.h"
    //#include "ble_peripheral_uart.h"
    #include "ble_peripheral_iso.h"
    static K_SEM_DEFINE(le_audio_ok, 0, 1);
    
    #if defined(CONFIG_AUDIO_DFU_ENABLE)
    #include "dfu_entry.h"
    #endif
    
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(main, CONFIG_MAIN_LOG_LEVEL);
    
    #if defined(CONFIG_INIT_STACKS)
    /* Used for printing stack usage */
    extern struct k_thread z_main_thread;
    #endif /* defined(CONFIG_INIT_STACKS) */
    
    static atomic_t ble_core_is_ready = (atomic_t) false;
    static struct board_version board_rev;
    
    ZBUS_CHAN_DECLARE(button_chan);
    ZBUS_CHAN_DECLARE(le_audio_chan);
    
    ZBUS_OBS_DECLARE(button_sub);
    ZBUS_OBS_DECLARE(le_audio_evt_sub);
    
    static int hfclock_config_and_start(void)
    {
    	int ret;
    
    	/* Use this to turn on 128 MHz clock for cpu_app */
    	ret = nrfx_clock_divider_set(NRF_CLOCK_DOMAIN_HFCLK, NRF_CLOCK_HFCLK_DIV_1);
    
    	ret -= NRFX_ERROR_BASE_NUM;
    	if (ret) {
    		return ret;
    	}
    
    	nrfx_clock_hfclk_start();
    	while (!nrfx_clock_hfclk_is_running()) {
    	}
    
    	return 0;
    }
    
    static int leds_set(void)
    {
    	int ret;
    
    	/* Blink LED 3 to indicate that APP core is running */
    	ret = led_blink(LED_APP_3_GREEN);
    	if (ret) {
    		return ret;
    	}
    
    #if (CONFIG_AUDIO_DEV == HEADSET)
    	enum audio_channel channel;
    
    	channel_assignment_get(&channel);
    
    	if (channel == AUDIO_CH_L) {
    		ret = led_on(LED_APP_RGB, LED_COLOR_BLUE);
    	} else {
    		ret = led_on(LED_APP_RGB, LED_COLOR_MAGENTA);
    	}
    
    	if (ret) {
    		return ret;
    	}
    #elif (CONFIG_AUDIO_DEV == GATEWAY)
    	ret = led_on(LED_APP_RGB, LED_COLOR_GREEN);
    	if (ret) {
    		return ret;
    	}
    #endif /* (CONFIG_AUDIO_DEV == HEADSET) */
    
    	return 0;
    }
    
    static int bonding_clear_check(void)
    {
    	int ret;
    	bool pressed;
    
    	ret = button_pressed(BUTTON_5, &pressed);
    	if (ret) {
    		return ret;
    	}
    
    	if (pressed) {
    		if (IS_ENABLED(CONFIG_SETTINGS)) {
    			LOG_INF("Clearing all bonds");
    			bt_unpair(BT_ID_DEFAULT, NULL);
    		}
    	}
    	return 0;
    }
    
    static int channel_assign_check(void)
    {
    #if (CONFIG_AUDIO_DEV == HEADSET) && CONFIG_AUDIO_HEADSET_CHANNEL_RUNTIME
    	int ret;
    	bool pressed;
    
    	ret = button_pressed(BUTTON_VOLUME_DOWN, &pressed);
    	if (ret) {
    		return ret;
    	}
    
    	if (pressed) {
    		channel_assignment_set(AUDIO_CH_L);
    		return 0;
    	}
    
    	ret = button_pressed(BUTTON_VOLUME_UP, &pressed);
    	if (ret) {
    		return ret;
    	}
    
    	if (pressed) {
    		channel_assignment_set(AUDIO_CH_R);
    		return 0;
    	}
    #endif
    
    	return 0;
    }
    
    /* Callback from ble_core when the ble subsystem is ready */
    void on_ble_core_ready(void)
    {
    	int ret;
    
    	(void)atomic_set(&ble_core_is_ready, (atomic_t) true);
    
    	if (IS_ENABLED(CONFIG_SETTINGS)) {
    		settings_load();
    
    		ret = bonding_clear_check();
    		ERR_CHK(ret);
    	}
    
    	k_sem_give(&le_audio_ok); 
    }
    
    int main(void)
    {
    	int ret;
    
    	LOG_DBG("nRF5340 APP core started");
    
    	ret = hfclock_config_and_start();
    	ERR_CHK(ret);
    
    	ret = led_init();
    	ERR_CHK(ret);
    
    	if (IS_ENABLED(CONFIG_ZBUS) && (CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE > 0)) {
    		ret = zbus_chan_add_obs(&button_chan, &button_sub, K_MSEC(200));
    		ERR_CHK(ret);
    
    		ret = zbus_chan_add_obs(&le_audio_chan, &le_audio_evt_sub, K_MSEC(200));
    		ERR_CHK(ret);
    	}
    
    	ret = button_handler_init();
    	ERR_CHK(ret);
    
    	channel_assignment_init();
    
    	ret = channel_assign_check();
    	ERR_CHK(ret);
    
    	ret = fw_info_app_print();
    	ERR_CHK(ret);
    
    	ret = board_version_valid_check();
    	ERR_CHK(ret);
    
    	ret = board_version_get(&board_rev);
    	ERR_CHK(ret);
    
    	if (board_rev.mask & BOARD_VERSION_VALID_MSK_SD_CARD) {
    		ret = sd_card_init();
    		if (ret != -ENODEV) {
    			ERR_CHK(ret);
    		}
    	}
    
    #if defined(CONFIG_AUDIO_DFU_ENABLE)
    	/* Check DFU BTN before initialize BLE */
    	dfu_entry_check((void *)ble_core_init);
    #endif
    
    	/* Initialize BLE, with callback for when BLE is ready */
    	ret = ble_core_init(on_ble_core_ready);
    	ERR_CHK(ret);
    
    	/* Wait until ble_core/NET core is ready */
    	while (!(bool)atomic_get(&ble_core_is_ready)) {
    		(void)k_sleep(K_MSEC(100));
    	}
    
    	ret = leds_set();
    	ERR_CHK(ret);
    
    	ret = streamctrl_start();
    	ERR_CHK(ret);
    /**/
        /* Don't go any further until BLE is initialized */
        k_sem_take(&le_audio_ok, K_FOREVER);
    
    	ret = uart_start();
    	ERR_CHK(ret);
    
    }
    

    Another thing I always wonder is that why I can't find nRF5340 audio DK board with nRF Connect mobile, as you know, I want to do volume control with phone app, scanning devices is the first step.

    Thank you for your suggestion to stop trying on v2.2, or I would waste more time on it.

    Best Regards

    Junmin

  • Hello Junmin,

    Junmin said:
    Glad to know you are back from sickness!

    Thank you for saying so! :) 

    Junmin said:
    My main.c is as following, just adding several line on the reference application. I tried to comment out bt_enable in my thread, the error code became -112, address already in use.

    Oh, could you include the code where you have added the nus functionality? I incorrectly assumed that you had this added as a thread towards the end of main.c, but it seems you have that implemented in another file somewhere.

    Junmin said:
    Another thing I always wonder is that why I can't find nRF5340 audio DK board with nRF Connect mobile, as you know, I want to do volume control with phone app, scanning devices is the first step.

    The default nRF5340 LE Audio application will advertise using Direct Advertising in the case that it is already bonded with a peer - could this be the case here?
    Also, I think we will need to resolve the current BLE issues in order to ensure that the regular peripheral advertising actually starts in this case, before we look further into this.

    Junmin said:
    Thank you for your suggestion to stop trying on v2.2, or I would waste more time on it.

    No problem at all, I am happy to help! :) 
    It would be more productive to instead apply the same approach to your v2.4 based project, instead of downgrading to v2.2.

    Best regards,
    Karl

Related