Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 766498be5a | |||
| 9ea485abc0 | |||
| 1b12e5151d | |||
| 4d6e6b8962 | |||
| bcb2bf3694 | |||
| 2120f9b188 | |||
| a70bf09bfa | |||
| 9647a07598 |
@@ -1,3 +1,5 @@
|
|||||||
|
*.pyc
|
||||||
|
|
||||||
# editors
|
# editors
|
||||||
*.swp
|
*.swp
|
||||||
*~
|
*~
|
||||||
|
|||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"broadcast_source.h": "c",
|
||||||
|
"bit": "c"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,8 @@ zephyr_library_include_directories(app PRIVATE
|
|||||||
${ZEPHYR_NRF_MODULE_DIR}/applications/nrf5340_audio/src/modules
|
${ZEPHYR_NRF_MODULE_DIR}/applications/nrf5340_audio/src/modules
|
||||||
${ZEPHYR_NRF_MODULE_DIR}/applications/nrf5340_audio/src/utils/macros
|
${ZEPHYR_NRF_MODULE_DIR}/applications/nrf5340_audio/src/utils/macros
|
||||||
)
|
)
|
||||||
|
include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake)
|
||||||
|
|
||||||
|
|
||||||
add_subdirectory(${ZEPHYR_NRF_MODULE_DIR}/applications/nrf5340_audio/src/bluetooth bluetooth_build)
|
add_subdirectory(${ZEPHYR_NRF_MODULE_DIR}/applications/nrf5340_audio/src/bluetooth bluetooth_build)
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,81 @@ rsource "${ZEPHYR_NRF_MODULE_DIR}/applications/nrf5340_audio/src/utils/Kconfig"
|
|||||||
|
|
||||||
#----------------------------------------------------------------------------#
|
#----------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
# USB mass storage device
|
||||||
|
menu "MSC sample options"
|
||||||
|
|
||||||
|
config APP_WIPE_STORAGE
|
||||||
|
bool "Option to clear the flash area before mounting"
|
||||||
|
help
|
||||||
|
Use this to force an existing file system to be created.
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "Storage and file system type used by the application"
|
||||||
|
default APP_MSC_STORAGE_NONE
|
||||||
|
help
|
||||||
|
Specify the type of storage and file system.
|
||||||
|
|
||||||
|
config APP_MSC_STORAGE_NONE
|
||||||
|
bool "Use RAM disk as block device"
|
||||||
|
|
||||||
|
config APP_MSC_STORAGE_RAM
|
||||||
|
bool "Use RAM disk and FAT file system"
|
||||||
|
imply FILE_SYSTEM
|
||||||
|
imply FAT_FILESYSTEM_ELM
|
||||||
|
|
||||||
|
config APP_MSC_STORAGE_FLASH_FATFS
|
||||||
|
bool "Use FLASH disk and FAT file system"
|
||||||
|
imply DISK_DRIVER_FLASH
|
||||||
|
imply FILE_SYSTEM
|
||||||
|
imply FAT_FILESYSTEM_ELM
|
||||||
|
|
||||||
|
config APP_MSC_STORAGE_FLASH_LITTLEFS
|
||||||
|
bool "Use FLASH disk and LittleFS"
|
||||||
|
imply DISK_DRIVER_FLASH
|
||||||
|
imply FILE_SYSTEM
|
||||||
|
imply FILE_SYSTEM_LITTLEFS
|
||||||
|
|
||||||
|
config APP_MSC_STORAGE_SDCARD
|
||||||
|
bool "Use SDHC and FAT file system"
|
||||||
|
imply DISK_DRIVER_SDMMC
|
||||||
|
imply FILE_SYSTEM
|
||||||
|
imply FAT_FILESYSTEM_ELM
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config MASS_STORAGE_DISK_NAME
|
||||||
|
default "NAND" if DISK_DRIVER_FLASH
|
||||||
|
default "RAM" if DISK_DRIVER_RAM
|
||||||
|
default "SD" if DISK_DRIVER_SDMMC
|
||||||
|
|
||||||
|
if DISK_DRIVER_FLASH
|
||||||
|
|
||||||
|
config FLASH_MAP
|
||||||
|
default y
|
||||||
|
|
||||||
|
config FLASH_PAGE_LAYOUT
|
||||||
|
default y
|
||||||
|
|
||||||
|
config FLASH_LOG_LEVEL
|
||||||
|
default 3
|
||||||
|
|
||||||
|
if NORDIC_QSPI_NOR
|
||||||
|
|
||||||
|
config NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE
|
||||||
|
default 4096
|
||||||
|
|
||||||
|
endif # NORDIC_QSPI_NOR
|
||||||
|
|
||||||
|
endif # DISK_DRIVER_FLASH
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
# Source common USB sample options used to initialize new experimental USB
|
||||||
|
# device stack. The scope of these options is limited to USB samples in project
|
||||||
|
# tree, you cannot use them in your own application.
|
||||||
|
source "samples/subsys/usb/common/Kconfig.sample_usbd"
|
||||||
|
|
||||||
|
# Auraconfig
|
||||||
config TRANSPORT_BIS
|
config TRANSPORT_BIS
|
||||||
bool "Use BIS (Broadcast Isochronous Stream)"
|
bool "Use BIS (Broadcast Isochronous Stream)"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
nac preset 24_2_1 0
|
||||||
|
nac file select left-channel_24kHz_left_48kbps_10ms.lc3 0 0 0
|
||||||
|
nac file select left-channel_24kHz_left_48kbps_10ms.lc3 0 0 1
|
||||||
|
nac broadcast_name broadcast1 0
|
||||||
|
|
||||||
|
nac preset 24_2_1 1
|
||||||
|
nac file select right-channel_24kHz_left_48kbps_10ms.lc3 1 0 0
|
||||||
|
nac file select right-channel_24kHz_left_48kbps_10ms.lc3 1 0 1
|
||||||
|
nac broadcast_name broadcast2 1
|
||||||
|
|
||||||
|
nac start
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
from config_broadcaster import write_to_serial_read_respone
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
serial_port = "/dev/ttyACM0"
|
||||||
|
broadcast_config = {
|
||||||
|
"broadcast1": "left24kHz_48kbps.lc3",
|
||||||
|
"broadcast2": "right-channel_24kHz_left_48kbps_10ms.lc3"
|
||||||
|
}
|
||||||
|
broadcast_ch = 0
|
||||||
|
file = "announcement_de.lc3"
|
||||||
|
|
||||||
|
ret = write_to_serial_read_respone(serial_port, f"nac file stream_close {broadcast_ch} 0 0", timeout=0.1)
|
||||||
|
print("\n".join(ret))
|
||||||
|
|
||||||
|
ret = write_to_serial_read_respone(serial_port, f"nac file select_play_once {file} {broadcast_ch} 0 0", timeout=0.1)
|
||||||
|
print("\n".join(ret))
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
broadcast_ch = 1
|
||||||
|
file = "announcement_en.lc3"
|
||||||
|
|
||||||
|
ret = write_to_serial_read_respone(serial_port, f"nac stream_close {broadcast_ch} 0 0", timeout=0.1)
|
||||||
|
print("\n".join(ret))
|
||||||
|
|
||||||
|
ret = write_to_serial_read_respone(serial_port, f"nac file select_play_once {file} {broadcast_ch} 0 0", timeout=0.1)
|
||||||
|
print("\n".join(ret))
|
||||||
|
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
import serial
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
def write_to_serial_read_respone(port, cmd, timeout = 2):
|
||||||
|
# Initialize serial connection
|
||||||
|
ser = serial.Serial(timeout = timeout)
|
||||||
|
ser.port = port
|
||||||
|
ser.baudrate = 115200
|
||||||
|
ser.bytesize = serial.EIGHTBITS
|
||||||
|
ser.parity = serial.PARITY_NONE
|
||||||
|
ser.stopbits = serial.STOPBITS_ONE
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Try to open the serial connection
|
||||||
|
#if not ser.is_open:
|
||||||
|
ser.open()
|
||||||
|
|
||||||
|
# Send string to serial port and get response
|
||||||
|
command = f"{cmd.strip()}\r\n"
|
||||||
|
ser.write(command.encode())
|
||||||
|
time.sleep(1) # wait a bit for response
|
||||||
|
|
||||||
|
readlines = []
|
||||||
|
for _ in range(20):
|
||||||
|
line = ser.readline().decode('utf-8').strip()
|
||||||
|
if not line:
|
||||||
|
ser.close()
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
readlines.append(line)
|
||||||
|
|
||||||
|
except serial.SerialException as e:
|
||||||
|
print(f"Error communicating with serial port: {e}")
|
||||||
|
finally:
|
||||||
|
# Close serial connection before returning
|
||||||
|
if ser.is_open:
|
||||||
|
ser.close()
|
||||||
|
return readlines
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def gen_broadcast_config_cmd(preset, broadcast_config: dict):
|
||||||
|
"""
|
||||||
|
Writes broadcaster configuration to the given serial port.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
serial_port (str): Device path of the serial port (e.g., '/dev/ttyACM0')
|
||||||
|
preset (str): Preset string used in nac preset line
|
||||||
|
broadcast_names (list): List of names for each broadcast group
|
||||||
|
"""
|
||||||
|
cmds = []
|
||||||
|
for ch, file_name in broadcast_config.items():
|
||||||
|
|
||||||
|
cmds.append(f"nac preset {preset} {ch}")
|
||||||
|
cmds.append(f"nac broadcast_name broadcast{ch} {ch}")
|
||||||
|
cmds.append(f"nac file select {file_name} {ch} 0 0")
|
||||||
|
cmds.append(f"nac num_bises 1 {ch} 0")
|
||||||
|
|
||||||
|
return cmds
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
PORT = "/dev/ttyACM0"
|
||||||
|
|
||||||
|
SAMPLING_RATE_KHZ = 16
|
||||||
|
FRAME_DUR_MS = 10
|
||||||
|
PRESET = f'{SAMPLING_RATE_KHZ}_2_1'
|
||||||
|
|
||||||
|
if SAMPLING_RATE_KHZ == 8:
|
||||||
|
BITRATE_KBPS = 16
|
||||||
|
elif SAMPLING_RATE_KHZ == 16:
|
||||||
|
BITRATE_KBPS = 32
|
||||||
|
elif SAMPLING_RATE_KHZ == 24:
|
||||||
|
BITRATE_KBPS = 48
|
||||||
|
else:
|
||||||
|
raise NotImplemented()
|
||||||
|
|
||||||
|
# TODO: Advertising interval wird ungelmäßig bei mehr als 3 broadcasts 10ms -> 1s< bei 24kHz sampling rat. Wie ist die load ?
|
||||||
|
# TODO: stop the lc3 streamer, setup all files and then start the streamer, should work for up to 4 streams
|
||||||
|
broadcast_config = {
|
||||||
|
0: f"announcement_{SAMPLING_RATE_KHZ}_{FRAME_DUR_MS}_{BITRATE_KBPS}_de.lc3",
|
||||||
|
1: f"announcement_{SAMPLING_RATE_KHZ}_{FRAME_DUR_MS}_{BITRATE_KBPS}_en.lc3",
|
||||||
|
2: f"announcement_{SAMPLING_RATE_KHZ}_{FRAME_DUR_MS}_{BITRATE_KBPS}_fr.lc3",
|
||||||
|
3: f"announcement_{SAMPLING_RATE_KHZ}_{FRAME_DUR_MS}_{BITRATE_KBPS}_es.lc3",
|
||||||
|
#4: f"announcement_{SAMPLING_RATE_KHZ}_{FRAME_DUR_MS}_{BITRATE_KBPS}_it.lc3"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmds = gen_broadcast_config_cmd(PRESET, broadcast_config)
|
||||||
|
|
||||||
|
subprocess.run(["nrfjprog", "--reset", "-s", "1050109484"], check=True)
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
for cmd in cmds:
|
||||||
|
ret = write_to_serial_read_respone(PORT, cmd, timeout=0.1)
|
||||||
|
print("\n".join(ret))
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
for i in broadcast_config.keys():
|
||||||
|
ret = write_to_serial_read_respone(PORT, f"nac start_idx {i}", timeout=0.1)
|
||||||
|
print("\n".join(ret))
|
||||||
|
time.sleep(0.2)
|
||||||
@@ -3,7 +3,16 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||||
#
|
#
|
||||||
|
# USB mass storage
|
||||||
|
CONFIG_APP_MSC_STORAGE_SDCARD=y
|
||||||
|
CONFIG_USB_DEVICE_STACK=y
|
||||||
|
CONFIG_USB_DEVICE_PRODUCT="Zephyr MSC sample"
|
||||||
|
CONFIG_USB_DEVICE_PID=0x0008
|
||||||
|
CONFIG_LOG=y
|
||||||
|
CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
|
||||||
|
CONFIG_USB_MASS_STORAGE=y
|
||||||
|
CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
|
||||||
|
CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y
|
||||||
|
|
||||||
# General
|
# General
|
||||||
CONFIG_REBOOT=y
|
CONFIG_REBOOT=y
|
||||||
@@ -15,9 +24,9 @@ CONFIG_THREAD_RUNTIME_STATS=y
|
|||||||
CONFIG_MAIN_THREAD_PRIORITY=10
|
CONFIG_MAIN_THREAD_PRIORITY=10
|
||||||
CONFIG_STACK_SENTINEL=y
|
CONFIG_STACK_SENTINEL=y
|
||||||
CONFIG_INIT_STACKS=y
|
CONFIG_INIT_STACKS=y
|
||||||
CONFIG_MAIN_STACK_SIZE=12000
|
CONFIG_MAIN_STACK_SIZE=18000
|
||||||
CONFIG_THREAD_NAME=y
|
CONFIG_THREAD_NAME=y
|
||||||
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=1200
|
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2000
|
||||||
|
|
||||||
# Uart driver
|
# Uart driver
|
||||||
CONFIG_SERIAL=y
|
CONFIG_SERIAL=y
|
||||||
@@ -28,7 +37,7 @@ CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
|
|||||||
CONFIG_LOG_TAG_MAX_LEN=2
|
CONFIG_LOG_TAG_MAX_LEN=2
|
||||||
CONFIG_LOG_TAG_DEFAULT="--"
|
CONFIG_LOG_TAG_DEFAULT="--"
|
||||||
|
|
||||||
CONFIG_LOG_BUFFER_SIZE=4096
|
CONFIG_LOG_BUFFER_SIZE=16384
|
||||||
CONFIG_USE_SEGGER_RTT=n
|
CONFIG_USE_SEGGER_RTT=n
|
||||||
CONFIG_LOG_BACKEND_RTT=n
|
CONFIG_LOG_BACKEND_RTT=n
|
||||||
|
|
||||||
@@ -82,7 +91,6 @@ CONFIG_ADC=y
|
|||||||
CONFIG_WATCHDOG=y
|
CONFIG_WATCHDOG=y
|
||||||
CONFIG_TASK_WDT=y
|
CONFIG_TASK_WDT=y
|
||||||
|
|
||||||
|
|
||||||
# Use this for debugging thread usage
|
# Use this for debugging thread usage
|
||||||
#CONFIG_LOG_THREAD_ID_PREFIX=y
|
#CONFIG_LOG_THREAD_ID_PREFIX=y
|
||||||
|
|
||||||
@@ -96,8 +104,8 @@ CONFIG_KERNEL_SHELL=y
|
|||||||
CONFIG_SHELL_BACKEND_SERIAL=y
|
CONFIG_SHELL_BACKEND_SERIAL=y
|
||||||
CONFIG_SHELL_VT100_COMMANDS=y
|
CONFIG_SHELL_VT100_COMMANDS=y
|
||||||
CONFIG_SHELL_VT100_COLORS=y
|
CONFIG_SHELL_VT100_COLORS=y
|
||||||
CONFIG_SHELL_STACK_SIZE=8096
|
CONFIG_SHELL_STACK_SIZE=16384
|
||||||
CONFIG_SHELL_CMD_BUFF_SIZE=128
|
CONFIG_SHELL_CMD_BUFF_SIZE=512
|
||||||
## Reduce shell memory usage
|
## Reduce shell memory usage
|
||||||
CONFIG_SHELL_WILDCARD=n
|
CONFIG_SHELL_WILDCARD=n
|
||||||
CONFIG_SHELL_HELP_ON_WRONG_ARGUMENT_COUNT=n
|
CONFIG_SHELL_HELP_ON_WRONG_ARGUMENT_COUNT=n
|
||||||
@@ -125,16 +133,16 @@ CONFIG_BT_DEVICE_NAME_DYNAMIC=y
|
|||||||
CONFIG_BT_CAP_INITIATOR=y
|
CONFIG_BT_CAP_INITIATOR=y
|
||||||
|
|
||||||
CONFIG_BT_ISO_BROADCASTER=y
|
CONFIG_BT_ISO_BROADCASTER=y
|
||||||
CONFIG_BT_ISO_MAX_BIG=2
|
CONFIG_BT_ISO_MAX_BIG=5
|
||||||
CONFIG_BT_ISO_MAX_CHAN=8
|
CONFIG_BT_ISO_MAX_CHAN=8
|
||||||
# Should be twice that of BT_ISO_MAX_CHAN
|
# Should be twice that of BT_ISO_MAX_CHAN
|
||||||
CONFIG_BT_ISO_TX_BUF_COUNT=16
|
CONFIG_BT_ISO_TX_BUF_COUNT=16
|
||||||
|
|
||||||
CONFIG_BT_BAP_BROADCAST_SOURCE=y
|
CONFIG_BT_BAP_BROADCAST_SOURCE=y
|
||||||
CONFIG_BT_BAP_BROADCAST_SRC_COUNT=2
|
CONFIG_BT_BAP_BROADCAST_SRC_COUNT=5
|
||||||
CONFIG_BT_EXT_ADV_MAX_ADV_SET=2
|
CONFIG_BT_EXT_ADV_MAX_ADV_SET=5
|
||||||
CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT=4
|
CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT=1
|
||||||
CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT=8
|
CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT=1
|
||||||
|
|
||||||
# Broadcasting Device - 0x0885
|
# Broadcasting Device - 0x0885
|
||||||
CONFIG_BT_DEVICE_APPEARANCE=2181
|
CONFIG_BT_DEVICE_APPEARANCE=2181
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# TODO:
|
||||||
|
- stoppen von streams während advertising weiter läuft
|
||||||
|
- 16kHz mit 16kbps (nur 32 kbps möglich)
|
||||||
|
- cpu usage debuggen
|
||||||
|
- 5 streams oder mehr parallel
|
||||||
|
- mehr als 4 streams erzeugen file open error
|
||||||
+399
-36
@@ -22,10 +22,57 @@
|
|||||||
#include "sd_card.h"
|
#include "sd_card.h"
|
||||||
#include "lc3_streamer.h"
|
#include "lc3_streamer.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
|
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_REGISTER(main, CONFIG_MAIN_LOG_LEVEL);
|
LOG_MODULE_REGISTER(main, CONFIG_MAIN_LOG_LEVEL);
|
||||||
|
|
||||||
|
#include <sample_usbd.h>
|
||||||
|
#include <zephyr/usb/usb_device.h>
|
||||||
|
#include <zephyr/usb/usbd.h>
|
||||||
|
#include <zephyr/usb/class/usbd_msc.h>
|
||||||
|
#include <zephyr/fs/fs.h>
|
||||||
|
|
||||||
|
#if CONFIG_FAT_FILESYSTEM_ELM
|
||||||
|
#include <ff.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CONFIG_DISK_DRIVER_FLASH) && \
|
||||||
|
!defined(CONFIG_DISK_DRIVER_RAM) && \
|
||||||
|
!defined(CONFIG_DISK_DRIVER_SDMMC)
|
||||||
|
#error No supported disk driver enabled
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define STORAGE_PARTITION storage_partition
|
||||||
|
#define STORAGE_PARTITION_ID FIXED_PARTITION_ID(STORAGE_PARTITION)
|
||||||
|
|
||||||
|
static struct fs_mount_t fs_mnt;
|
||||||
|
|
||||||
|
static int mount_app_fs(struct fs_mount_t *mnt)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
#if CONFIG_FAT_FILESYSTEM_ELM
|
||||||
|
static FATFS fat_fs;
|
||||||
|
|
||||||
|
mnt->type = FS_FATFS;
|
||||||
|
mnt->fs_data = &fat_fs;
|
||||||
|
if (IS_ENABLED(CONFIG_DISK_DRIVER_RAM)) {
|
||||||
|
mnt->mnt_point = "/RAM:";
|
||||||
|
} else if (IS_ENABLED(CONFIG_DISK_DRIVER_SDMMC)) {
|
||||||
|
mnt->mnt_point = "/SD:";
|
||||||
|
} else {
|
||||||
|
mnt->mnt_point = "/NAND:";
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif CONFIG_FILE_SYSTEM_LITTLEFS
|
||||||
|
mnt->type = FS_LITTLEFS;
|
||||||
|
mnt->mnt_point = "/lfs";
|
||||||
|
mnt->fs_data = &storage;
|
||||||
|
#endif
|
||||||
|
rc = fs_mount(mnt);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
ZBUS_CHAN_DECLARE(bt_mgmt_chan);
|
ZBUS_CHAN_DECLARE(bt_mgmt_chan);
|
||||||
ZBUS_CHAN_DECLARE(sdu_ref_chan);
|
ZBUS_CHAN_DECLARE(sdu_ref_chan);
|
||||||
ZBUS_CHAN_DECLARE(le_audio_chan);
|
ZBUS_CHAN_DECLARE(le_audio_chan);
|
||||||
@@ -44,11 +91,17 @@ struct bt_le_ext_adv *ext_adv;
|
|||||||
#define EXT_ADV_UUID_BUF_SIZE (128)
|
#define EXT_ADV_UUID_BUF_SIZE (128)
|
||||||
NET_BUF_SIMPLE_DEFINE_STATIC(uuid_data0, EXT_ADV_UUID_BUF_SIZE);
|
NET_BUF_SIMPLE_DEFINE_STATIC(uuid_data0, EXT_ADV_UUID_BUF_SIZE);
|
||||||
NET_BUF_SIMPLE_DEFINE_STATIC(uuid_data1, EXT_ADV_UUID_BUF_SIZE);
|
NET_BUF_SIMPLE_DEFINE_STATIC(uuid_data1, EXT_ADV_UUID_BUF_SIZE);
|
||||||
|
NET_BUF_SIMPLE_DEFINE_STATIC(uuid_data2, EXT_ADV_UUID_BUF_SIZE);
|
||||||
|
NET_BUF_SIMPLE_DEFINE_STATIC(uuid_data3, EXT_ADV_UUID_BUF_SIZE);
|
||||||
|
NET_BUF_SIMPLE_DEFINE_STATIC(uuid_data4, EXT_ADV_UUID_BUF_SIZE);
|
||||||
|
|
||||||
/* Buffer for periodic advertising BASE data. */
|
/* Buffer for periodic advertising BASE data. */
|
||||||
#define BASE_DATA_BUF_SIZE (256)
|
#define BASE_DATA_BUF_SIZE (256)
|
||||||
NET_BUF_SIMPLE_DEFINE_STATIC(base_data0, BASE_DATA_BUF_SIZE);
|
NET_BUF_SIMPLE_DEFINE_STATIC(base_data0, BASE_DATA_BUF_SIZE);
|
||||||
NET_BUF_SIMPLE_DEFINE_STATIC(base_data1, BASE_DATA_BUF_SIZE);
|
NET_BUF_SIMPLE_DEFINE_STATIC(base_data1, BASE_DATA_BUF_SIZE);
|
||||||
|
NET_BUF_SIMPLE_DEFINE_STATIC(base_data2, BASE_DATA_BUF_SIZE);
|
||||||
|
NET_BUF_SIMPLE_DEFINE_STATIC(base_data3, BASE_DATA_BUF_SIZE);
|
||||||
|
NET_BUF_SIMPLE_DEFINE_STATIC(base_data4, BASE_DATA_BUF_SIZE);
|
||||||
|
|
||||||
/* Extended advertising buffer. */
|
/* Extended advertising buffer. */
|
||||||
static struct bt_data ext_adv_buf[CONFIG_BT_ISO_MAX_BIG][CONFIG_EXT_ADV_BUF_MAX];
|
static struct bt_data ext_adv_buf[CONFIG_BT_ISO_MAX_BIG][CONFIG_EXT_ADV_BUF_MAX];
|
||||||
@@ -80,13 +133,28 @@ static struct broadcast_source_ext_adv_data ext_adv_data[] = {
|
|||||||
.pba_buf = pba_data[0]},
|
.pba_buf = pba_data[0]},
|
||||||
{.uuid_buf = &uuid_data1,
|
{.uuid_buf = &uuid_data1,
|
||||||
.pba_metadata_vacant_cnt = BROADCAST_SOURCE_PBA_METADATA_VACANT,
|
.pba_metadata_vacant_cnt = BROADCAST_SOURCE_PBA_METADATA_VACANT,
|
||||||
.pba_buf = pba_data[1]}};
|
.pba_buf = pba_data[1]},
|
||||||
|
{.uuid_buf = &uuid_data2,
|
||||||
|
.pba_metadata_vacant_cnt = BROADCAST_SOURCE_PBA_METADATA_VACANT,
|
||||||
|
.pba_buf = pba_data[2]},
|
||||||
|
{.uuid_buf = &uuid_data3,
|
||||||
|
.pba_metadata_vacant_cnt = BROADCAST_SOURCE_PBA_METADATA_VACANT,
|
||||||
|
.pba_buf = pba_data[3]},
|
||||||
|
{.uuid_buf = &uuid_data1,
|
||||||
|
.pba_metadata_vacant_cnt = BROADCAST_SOURCE_PBA_METADATA_VACANT,
|
||||||
|
.pba_buf = pba_data[4]}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Broadcast source static periodic advertising data.
|
* @brief Broadcast source static periodic advertising data.
|
||||||
*/
|
*/
|
||||||
static struct broadcast_source_per_adv_data per_adv_data[] = {{.base_buf = &base_data0},
|
static struct broadcast_source_per_adv_data per_adv_data[] = {
|
||||||
{.base_buf = &base_data1}};
|
{.base_buf = &base_data0},
|
||||||
|
{.base_buf = &base_data1},
|
||||||
|
{.base_buf = &base_data2},
|
||||||
|
{.base_buf = &base_data3},
|
||||||
|
{.base_buf = &base_data4}
|
||||||
|
};
|
||||||
|
|
||||||
static struct broadcast_source_big broadcast_param[CONFIG_BT_ISO_MAX_BIG];
|
static struct broadcast_source_big broadcast_param[CONFIG_BT_ISO_MAX_BIG];
|
||||||
static struct subgroup_config subgroups[CONFIG_BT_ISO_MAX_BIG]
|
static struct subgroup_config subgroups[CONFIG_BT_ISO_MAX_BIG]
|
||||||
@@ -287,24 +355,33 @@ static void stream_frame_get_and_send(struct stream_index stream_idx)
|
|||||||
|
|
||||||
ret = lc3_streamer_next_frame_get(
|
ret = lc3_streamer_next_frame_get(
|
||||||
stream_file_idx, (const uint8_t **const)&(bis_info->frame_ptrs[stream_idx.lvl3]));
|
stream_file_idx, (const uint8_t **const)&(bis_info->frame_ptrs[stream_idx.lvl3]));
|
||||||
if (ret == -ENODATA) {
|
|
||||||
LOG_WRN("No more frames to read");
|
if (ret != 0){
|
||||||
ret = lc3_streamer_stream_close(stream_file_idx);
|
bis_info->frame_ptrs[stream_idx.lvl3] = NULL; // use zero packet
|
||||||
if (ret) {
|
//ret = lc3_streamer_stream_close(stream_file_idx);
|
||||||
LOG_ERR("Failed to close stream: %d", ret);
|
// if (ret) {
|
||||||
}
|
// LOG_ERR("Failed to close stream: %d", ret);
|
||||||
|
// }
|
||||||
bis_info->lc3_streamer_idx[stream_idx.lvl3] = LC3_STREAMER_INDEX_UNUSED;
|
|
||||||
|
|
||||||
return;
|
|
||||||
} else if (ret == -ENOMSG) {
|
|
||||||
LOG_DBG("Frame from SD card not ready for stream %d, using zero packet",
|
|
||||||
stream_idx.lvl3);
|
|
||||||
bis_info->frame_ptrs[stream_idx.lvl3] = NULL;
|
|
||||||
} else if (ret) {
|
|
||||||
LOG_ERR("Failed to get next frame: %d", ret);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (ret == -ENODATA) {
|
||||||
|
// LOG_WRN("No more frames to read");
|
||||||
|
// ret = lc3_streamer_stream_close(stream_file_idx);
|
||||||
|
// if (ret) {
|
||||||
|
// LOG_ERR("Failed to close stream: %d", ret);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bis_info->lc3_streamer_idx[stream_idx.lvl3] = LC3_STREAMER_INDEX_UNUSED;
|
||||||
|
|
||||||
|
// return;
|
||||||
|
// } else if (ret == -ENOMSG) {
|
||||||
|
// LOG_DBG("Frame from SD card not ready for stream %d, using zero packet",
|
||||||
|
// stream_idx.lvl3);
|
||||||
|
// bis_info->frame_ptrs[stream_idx.lvl3] = NULL;
|
||||||
|
// } else if (ret) {
|
||||||
|
// LOG_ERR("Failed to get next frame: %d", ret);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
bis_info->frame_loaded[stream_idx.lvl3] = true;
|
bis_info->frame_loaded[stream_idx.lvl3] = true;
|
||||||
|
|
||||||
@@ -490,13 +567,16 @@ static int ext_adv_populate(uint8_t big_index, struct broadcast_source_ext_adv_d
|
|||||||
ext_adv_buf[ext_adv_buf_cnt].data = ext_adv_data->uuid_buf->data;
|
ext_adv_buf[ext_adv_buf_cnt].data = ext_adv_data->uuid_buf->data;
|
||||||
ext_adv_buf_cnt++;
|
ext_adv_buf_cnt++;
|
||||||
|
|
||||||
ret = bt_mgmt_manufacturer_uuid_populate(ext_adv_data->uuid_buf,
|
//TODO: populating the manufacturer id fails with crash for more than 2 big
|
||||||
CONFIG_BT_DEVICE_MANUFACTURER_ID);
|
// LOG_INF("populating manufacurer id for %d", big_index);
|
||||||
if (ret) {
|
// ret = bt_mgmt_manufacturer_uuid_populate(ext_adv_data->uuid_buf,
|
||||||
LOG_ERR("Failed to add adv data with manufacturer ID: %d", ret);
|
// CONFIG_BT_DEVICE_MANUFACTURER_ID);
|
||||||
return ret;
|
// if (ret) {
|
||||||
}
|
// LOG_ERR("Failed to add adv data with manufacturer ID: %d", ret);
|
||||||
|
// return ret;
|
||||||
|
// }
|
||||||
|
|
||||||
|
LOG_INF("Populating ext adv broadcast source %d", big_index);
|
||||||
ret = broadcast_source_ext_adv_populate(big_index, broadcast_param[big_index].fixed_id,
|
ret = broadcast_source_ext_adv_populate(big_index, broadcast_param[big_index].fixed_id,
|
||||||
broadcast_param[big_index].broadcast_id,
|
broadcast_param[big_index].broadcast_id,
|
||||||
ext_adv_data, &ext_adv_buf[ext_adv_buf_cnt],
|
ext_adv_data, &ext_adv_buf[ext_adv_buf_cnt],
|
||||||
@@ -511,7 +591,7 @@ static int ext_adv_populate(uint8_t big_index, struct broadcast_source_ext_adv_d
|
|||||||
/* Add the number of UUIDs */
|
/* Add the number of UUIDs */
|
||||||
ext_adv_buf[0].data_len = ext_adv_data->uuid_buf->len;
|
ext_adv_buf[0].data_len = ext_adv_data->uuid_buf->len;
|
||||||
|
|
||||||
LOG_DBG("Size of adv data: %d, num_elements: %d", sizeof(struct bt_data) * ext_adv_buf_cnt,
|
LOG_INF("Size of adv data: %d, num_elements: %d", sizeof(struct bt_data) * ext_adv_buf_cnt,
|
||||||
ext_adv_buf_cnt);
|
ext_adv_buf_cnt);
|
||||||
|
|
||||||
*ext_adv_count = ext_adv_buf_cnt;
|
*ext_adv_count = ext_adv_buf_cnt;
|
||||||
@@ -560,7 +640,7 @@ static int per_adv_populate(uint8_t big_index, struct broadcast_source_per_adv_d
|
|||||||
static void broadcast_create(uint8_t big_index)
|
static void broadcast_create(uint8_t big_index)
|
||||||
{
|
{
|
||||||
if (big_index >= CONFIG_BT_ISO_MAX_BIG) {
|
if (big_index >= CONFIG_BT_ISO_MAX_BIG) {
|
||||||
LOG_ERR("BIG index out of range");
|
LOG_ERR("BIG index %d out of range", big_index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,7 +734,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
LOG_DBG("Main started");
|
LOG_INF("Main started");
|
||||||
|
|
||||||
ret = nrfx_clock_divider_set(NRF_CLOCK_DOMAIN_HFCLK, NRF_CLOCK_HFCLK_DIV_1);
|
ret = nrfx_clock_divider_set(NRF_CLOCK_DOMAIN_HFCLK, NRF_CLOCK_HFCLK_DIV_1);
|
||||||
ret -= NRFX_ERROR_BASE_NUM;
|
ret -= NRFX_ERROR_BASE_NUM;
|
||||||
@@ -689,14 +769,15 @@ int main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = zbus_subscribers_create();
|
|
||||||
ERR_CHK_MSG(ret, "Failed to create zbus subscriber threads");
|
|
||||||
|
|
||||||
if (sd_card_present) {
|
if (sd_card_present) {
|
||||||
ret = sd_card_toc_gen();
|
ret = sd_card_toc_gen();
|
||||||
ERR_CHK_MSG(ret, "Failed to generate SD card table");
|
ERR_CHK_MSG(ret, "Failed to generate SD card table");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = zbus_subscribers_create();
|
||||||
|
ERR_CHK_MSG(ret, "Failed to create zbus subscriber threads");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -874,6 +955,18 @@ static void nrf_auraconfig_print(const struct shell *shell, uint8_t group_index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cmd_usb_mass_enable(const struct shell *shell, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ret = usb_enable(NULL);
|
||||||
|
if (ret != 0) {
|
||||||
|
LOG_ERR("Failed to enable USB");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
LOG_INF("The device is put in USB mass storage mode.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int cmd_list(const struct shell *shell, size_t argc, char **argv)
|
static int cmd_list(const struct shell *shell, size_t argc, char **argv)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(argc);
|
ARG_UNUSED(argc);
|
||||||
@@ -892,12 +985,15 @@ static int adv_create_and_start(const struct shell *shell, uint8_t big_index)
|
|||||||
|
|
||||||
size_t ext_adv_buf_cnt = 0;
|
size_t ext_adv_buf_cnt = 0;
|
||||||
size_t per_adv_buf_cnt = 0;
|
size_t per_adv_buf_cnt = 0;
|
||||||
|
LOG_INF("Starting Ext Advertising for big %d", big_index);
|
||||||
|
|
||||||
if (big_index >= CONFIG_BT_ISO_MAX_BIG) {
|
if (big_index >= CONFIG_BT_ISO_MAX_BIG) {
|
||||||
shell_error(shell, "BIG index out of range");
|
shell_error(shell, "BIG index out of range");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_INF("Starting Ext Advertising for big %d", big_index);
|
||||||
|
|
||||||
if (broadcast_param[big_index].broadcast_name[0] == '\0') {
|
if (broadcast_param[big_index].broadcast_name[0] == '\0') {
|
||||||
/* Name not set, using default */
|
/* Name not set, using default */
|
||||||
size_t brdcst_name_size = sizeof(CONFIG_BT_AUDIO_BROADCAST_NAME) - 1;
|
size_t brdcst_name_size = sizeof(CONFIG_BT_AUDIO_BROADCAST_NAME) - 1;
|
||||||
@@ -931,6 +1027,7 @@ static int adv_create_and_start(const struct shell *shell, uint8_t big_index)
|
|||||||
|
|
||||||
bt_set_name(broadcast_param[big_index].adv_name);
|
bt_set_name(broadcast_param[big_index].adv_name);
|
||||||
|
|
||||||
|
LOG_INF("Populating Ext Advertising for big %d", big_index);
|
||||||
/* Get advertising set for BIG0 */
|
/* Get advertising set for BIG0 */
|
||||||
ret = ext_adv_populate(big_index, &ext_adv_data[big_index], ext_adv_buf[big_index],
|
ret = ext_adv_populate(big_index, &ext_adv_data[big_index], ext_adv_buf[big_index],
|
||||||
ARRAY_SIZE(ext_adv_buf[big_index]), &ext_adv_buf_cnt);
|
ARRAY_SIZE(ext_adv_buf[big_index]), &ext_adv_buf_cnt);
|
||||||
@@ -938,6 +1035,7 @@ static int adv_create_and_start(const struct shell *shell, uint8_t big_index)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_INF("Populating periodic Advertising for big %d", big_index);
|
||||||
ret = per_adv_populate(big_index, &per_adv_data[big_index], &per_adv_buf[big_index], 1,
|
ret = per_adv_populate(big_index, &per_adv_data[big_index], &per_adv_buf[big_index], 1,
|
||||||
&per_adv_buf_cnt);
|
&per_adv_buf_cnt);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -945,6 +1043,7 @@ static int adv_create_and_start(const struct shell *shell, uint8_t big_index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Start broadcaster */
|
/* Start broadcaster */
|
||||||
|
LOG_INF("Starting the Advertiser for big %d", big_index);
|
||||||
ret = bt_mgmt_adv_start(big_index, ext_adv_buf[big_index], ext_adv_buf_cnt,
|
ret = bt_mgmt_adv_start(big_index, ext_adv_buf[big_index], ext_adv_buf_cnt,
|
||||||
&per_adv_buf[big_index], per_adv_buf_cnt, false);
|
&per_adv_buf[big_index], per_adv_buf_cnt, false);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -1053,12 +1152,13 @@ static int big_enable(const struct shell *shell, uint8_t big_index)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_INF("starting advertising for BIG %d", big_index);
|
||||||
ret = adv_create_and_start(shell, big_index);
|
ret = adv_create_and_start(shell, big_index);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
shell_error(shell, "Failed to start advertising for BIG%d: %d", big_index, ret);
|
shell_error(shell, "Failed to start advertising for BIG%d: %d", big_index, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
LOG_INF("Advertising started for BIG %d", big_index);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1096,6 +1196,103 @@ static int cmd_start(const struct shell *shell, size_t argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cmd_start_idx(const struct shell *shell, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint8_t big_index;
|
||||||
|
|
||||||
|
big_index = (uint8_t)atoi(argv[1]);
|
||||||
|
LOG_INF("Enable big %d", big_index);
|
||||||
|
ret = big_enable(shell, big_index);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
led_blink(LED_APP_RGB, LED_COLOR_GREEN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int enable_broadcast_source_only(const struct shell *shell, uint8_t big_index)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (big_index >= CONFIG_BT_ISO_MAX_BIG) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((broadcast_param[big_index].subgroups == NULL) ||
|
||||||
|
(broadcast_param[big_index].num_subgroups == 0)) {
|
||||||
|
LOG_ERR("No subgroups defined for BIG%d", big_index);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (broadcast_source_is_streaming(big_index)) {
|
||||||
|
LOG_WRN("BIG %d is already streaming", big_index);
|
||||||
|
/* Do not return error code as this might be called from a for-loop */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = broadcast_source_enable(&broadcast_param[big_index], big_index);
|
||||||
|
if (ret) {
|
||||||
|
shell_error(shell, "Failed to enable broadcaster: %d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_broadcast_source_enable(const struct shell *shell, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (argc == 2) {
|
||||||
|
uint8_t big_index;
|
||||||
|
|
||||||
|
ret = argv_to_indexes(shell, argc, argv, &big_index, 1, NULL, 0);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = enable_broadcast_source_only(shell, big_index);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < CONFIG_BT_ISO_MAX_BIG; i++) {
|
||||||
|
if (broadcast_param[i].subgroups != NULL ||
|
||||||
|
broadcast_param[i].num_subgroups > 0) {
|
||||||
|
ret = enable_broadcast_source_only(shell, i);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
led_blink(LED_APP_RGB, LED_COLOR_GREEN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int broadcaster_source_disable(const struct shell *shell, uint8_t big_index)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!broadcast_source_is_streaming(big_index)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = broadcast_source_disable(big_index);
|
||||||
|
if (ret) {
|
||||||
|
shell_error(shell, "Failed to stop broadcaster(s) %d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int broadcaster_stop(const struct shell *shell, uint8_t big_index)
|
static int broadcaster_stop(const struct shell *shell, uint8_t big_index)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -1121,14 +1318,24 @@ static int broadcaster_stop(const struct shell *shell, uint8_t big_index)
|
|||||||
shell_error(shell, "Failed to stop extended advertiser");
|
shell_error(shell, "Failed to stop extended advertiser");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (big_index == 0) {
|
if (big_index == 0) {
|
||||||
net_buf_simple_reset(&base_data0);
|
net_buf_simple_reset(&base_data0);
|
||||||
net_buf_simple_reset(&uuid_data0);
|
net_buf_simple_reset(&uuid_data0);
|
||||||
} else if (big_index == 1) {
|
} else if (big_index == 1) {
|
||||||
net_buf_simple_reset(&base_data1);
|
net_buf_simple_reset(&base_data1);
|
||||||
net_buf_simple_reset(&uuid_data1);
|
net_buf_simple_reset(&uuid_data1);
|
||||||
} else {
|
} else if (big_index == 2) {
|
||||||
|
net_buf_simple_reset(&base_data2);
|
||||||
|
net_buf_simple_reset(&uuid_data2);
|
||||||
|
} else if (big_index == 3) {
|
||||||
|
net_buf_simple_reset(&base_data3);
|
||||||
|
net_buf_simple_reset(&uuid_data3);
|
||||||
|
} else if (big_index == 4) {
|
||||||
|
net_buf_simple_reset(&base_data4);
|
||||||
|
net_buf_simple_reset(&uuid_data4);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_ERR("Stopping the broadcast source failed, big index %d out of range", big_index);
|
||||||
shell_error(shell, "BIG index out of range");
|
shell_error(shell, "BIG index out of range");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -1146,6 +1353,38 @@ static int broadcaster_stop(const struct shell *shell, uint8_t big_index)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int cmd_broadcast_source_disable(const struct shell *shell, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (argc == 2) {
|
||||||
|
uint8_t big_index;
|
||||||
|
|
||||||
|
ret = argv_to_indexes(shell, argc, argv, &big_index, 1, NULL, 0);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = broadcaster_source_disable(shell, big_index);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < CONFIG_BT_ISO_MAX_BIG; i++) {
|
||||||
|
if (broadcast_param[i].subgroups != NULL) {
|
||||||
|
ret = broadcaster_source_disable(shell, i);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
led_on(LED_APP_RGB, LED_COLOR_GREEN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int cmd_stop(const struct shell *shell, size_t argc, char **argv)
|
static int cmd_stop(const struct shell *shell, size_t argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -1780,7 +2019,120 @@ static int cmd_file_select(const struct shell *shell, size_t argc, char **argv)
|
|||||||
|
|
||||||
ret = lc3_streamer_stream_register(
|
ret = lc3_streamer_stream_register(
|
||||||
file_name, &lc3_stream_infos[big_index][sub_index].lc3_streamer_idx[bis_index],
|
file_name, &lc3_stream_infos[big_index][sub_index].lc3_streamer_idx[bis_index],
|
||||||
true);
|
true); // TODO: set this to false and only loop once with a dedicated command
|
||||||
|
if (ret) {
|
||||||
|
shell_error(shell, "Failed to register stream: %d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
lc3_stream_infos[big_index][sub_index].frame_size =
|
||||||
|
broadcast_param[big_index].subgroups[sub_index].group_lc3_preset.qos.sdu;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int cmd_stream_close(const struct shell *shell, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint8_t big_index;
|
||||||
|
uint8_t sub_index;
|
||||||
|
uint8_t bis_index;
|
||||||
|
|
||||||
|
ret = argv_to_indexes(shell, argc, argv, &big_index, 1, &sub_index, 2);
|
||||||
|
if (ret) {
|
||||||
|
shell_error(shell, "Failed to get indexes: %d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bis_index = (uint8_t)atoi(argv[3]);
|
||||||
|
|
||||||
|
ret = lc3_streamer_stream_close(lc3_stream_infos[big_index][sub_index].lc3_streamer_idx[bis_index]);
|
||||||
|
|
||||||
|
}
|
||||||
|
static int cmd_file_select_play_once(const struct shell *shell, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint8_t big_index;
|
||||||
|
uint8_t sub_index;
|
||||||
|
uint8_t bis_index;
|
||||||
|
|
||||||
|
if (!sd_card_present) {
|
||||||
|
shell_error(shell, "No SD card present: files cannot be selected");
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc != 5) {
|
||||||
|
shell_error(shell,
|
||||||
|
"Usage: nac file select <file path> <BIG index> <subgroup index> "
|
||||||
|
"<BIS index>");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = argv_to_indexes(shell, argc, argv, &big_index, 2, &sub_index, 3);
|
||||||
|
if (ret) {
|
||||||
|
shell_error(shell, "Failed to get indexes: %d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bis_index = (uint8_t)atoi(argv[4]);
|
||||||
|
// ret = lc3_streamer_stream_close(lc3_stream_infos[big_index][sub_index].lc3_streamer_idx[bis_index]);
|
||||||
|
// if (ret) {
|
||||||
|
// shell_error(shell, "Failed to close stream: %d", ret);
|
||||||
|
// return ret;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (!is_number(argv[4])) {
|
||||||
|
shell_error(shell, "BIS index must be a digit");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bis_index = (uint8_t)atoi(argv[4]);
|
||||||
|
|
||||||
|
if ((bis_index >= CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT) ||
|
||||||
|
(bis_index >= broadcast_param[big_index].subgroups[sub_index].num_bises)) {
|
||||||
|
shell_error(shell, "BIS index %d is out of range (max %d)", bis_index,
|
||||||
|
broadcast_param[big_index].subgroups[sub_index].num_bises - 1);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *file_name = argv[1];
|
||||||
|
|
||||||
|
LOG_DBG("Selecting file %s for stream big: %d sub: %d bis: %d", file_name, big_index,
|
||||||
|
sub_index, bis_index);
|
||||||
|
|
||||||
|
struct bt_audio_codec_cfg *codec_cfg =
|
||||||
|
&broadcast_param[big_index].subgroups[sub_index].group_lc3_preset.codec_cfg;
|
||||||
|
|
||||||
|
struct lc3_stream_cfg cfg;
|
||||||
|
|
||||||
|
ret = le_audio_freq_hz_get(codec_cfg, &cfg.sample_rate_hz);
|
||||||
|
if (ret) {
|
||||||
|
shell_error(shell, "Failed to get frequency: %d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = le_audio_duration_us_get(codec_cfg, &cfg.frame_duration_us);
|
||||||
|
if (ret) {
|
||||||
|
shell_error(shell, "Failed to get frame duration: %d", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = le_audio_bitrate_get(codec_cfg, &cfg.bit_rate_bps);
|
||||||
|
if (ret) {
|
||||||
|
shell_error(shell, "Failed to get bit rate: %d", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify that the file header matches the stream configurationn */
|
||||||
|
/* NOTE: This will not abort the streamer if the file is not valid, only give a warning */
|
||||||
|
bool header_valid = lc3_streamer_file_compatible_check(file_name, &cfg);
|
||||||
|
|
||||||
|
if (!header_valid) {
|
||||||
|
shell_warn(shell, "File header verification failed. File may not be compatible "
|
||||||
|
"with stream config.");
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = lc3_streamer_stream_register(
|
||||||
|
file_name, &lc3_stream_infos[big_index][sub_index].lc3_streamer_idx[bis_index],
|
||||||
|
false); // TODO: set this to false and only loop once with a dedicated command
|
||||||
if (ret) {
|
if (ret) {
|
||||||
shell_error(shell, "Failed to register stream: %d", ret);
|
shell_error(shell, "Failed to register stream: %d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -2603,6 +2955,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_file_cmd,
|
|||||||
/* 5 required arguments */
|
/* 5 required arguments */
|
||||||
SHELL_CMD_ARG(select, &folder_names, "Select file on SD card",
|
SHELL_CMD_ARG(select, &folder_names, "Select file on SD card",
|
||||||
cmd_file_select, 5, 0),
|
cmd_file_select, 5, 0),
|
||||||
|
SHELL_CMD_ARG(select_play_once, &folder_names, "Select file on SD card",
|
||||||
|
cmd_file_select_play_once, 5, 0),
|
||||||
|
SHELL_CMD_ARG(stream_close, &folder_names, "Select file on SD card",
|
||||||
|
cmd_stream_close, 4, 0),
|
||||||
SHELL_SUBCMD_SET_END);
|
SHELL_SUBCMD_SET_END);
|
||||||
|
|
||||||
SHELL_STATIC_SUBCMD_SET_CREATE(
|
SHELL_STATIC_SUBCMD_SET_CREATE(
|
||||||
@@ -2617,6 +2973,13 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
|
|||||||
configuration_cmd, SHELL_COND_CMD(CONFIG_SHELL, list, NULL, "List presets", cmd_list),
|
configuration_cmd, SHELL_COND_CMD(CONFIG_SHELL, list, NULL, "List presets", cmd_list),
|
||||||
SHELL_COND_CMD(CONFIG_SHELL, start, NULL, "Start broadcaster", cmd_start),
|
SHELL_COND_CMD(CONFIG_SHELL, start, NULL, "Start broadcaster", cmd_start),
|
||||||
SHELL_COND_CMD(CONFIG_SHELL, stop, NULL, "Stop broadcaster", cmd_stop),
|
SHELL_COND_CMD(CONFIG_SHELL, stop, NULL, "Stop broadcaster", cmd_stop),
|
||||||
|
SHELL_COND_CMD(CONFIG_SHELL, start_idx, NULL, "Start broadcaster with index", cmd_start_idx),
|
||||||
|
SHELL_COND_CMD(CONFIG_SHELL, source_disable, NULL, "Disable broadcast source", cmd_broadcast_source_disable),
|
||||||
|
SHELL_COND_CMD(CONFIG_SHELL, source_enable, NULL, "Enable broadcast source", cmd_broadcast_source_enable),
|
||||||
|
SHELL_COND_CMD(CONFIG_SHELL, stream_close, NULL, "Close lc3 stream", cmd_stream_close),
|
||||||
|
SHELL_COND_CMD(CONFIG_SHELL, en_usb_mass, NULL, "Enable usb mass storage device", cmd_usb_mass_enable),
|
||||||
|
|
||||||
|
|
||||||
SHELL_COND_CMD(CONFIG_SHELL, show, NULL, "Show current configuration", cmd_show),
|
SHELL_COND_CMD(CONFIG_SHELL, show, NULL, "Show current configuration", cmd_show),
|
||||||
SHELL_COND_CMD(CONFIG_SHELL, packing, NULL, "Set type of packing", cmd_packing),
|
SHELL_COND_CMD(CONFIG_SHELL, packing, NULL, "Set type of packing", cmd_packing),
|
||||||
SHELL_COND_CMD(CONFIG_SHELL, preset, NULL, "Set preset", cmd_preset),
|
SHELL_COND_CMD(CONFIG_SHELL, preset, NULL, "Set preset", cmd_preset),
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ CONFIG_BT_ISO_BROADCASTER=y
|
|||||||
CONFIG_BT_ISO_SYNC_RECEIVER=n
|
CONFIG_BT_ISO_SYNC_RECEIVER=n
|
||||||
CONFIG_BT_EXT_ADV=y
|
CONFIG_BT_EXT_ADV=y
|
||||||
|
|
||||||
CONFIG_BT_CTLR_ADV_SET=2
|
CONFIG_BT_CTLR_ADV_SET=5
|
||||||
CONFIG_BT_EXT_ADV_MAX_ADV_SET=2
|
CONFIG_BT_EXT_ADV_MAX_ADV_SET=5
|
||||||
CONFIG_BT_CTLR_ADV_ISO_SET=2
|
CONFIG_BT_CTLR_ADV_ISO_SET=5
|
||||||
CONFIG_BT_CTLR_ADV_ISO_STREAM_COUNT=8
|
CONFIG_BT_CTLR_ADV_ISO_STREAM_COUNT=8
|
||||||
|
|
||||||
CONFIG_BT_MAX_CONN=1
|
CONFIG_BT_MAX_CONN=1
|
||||||
|
|||||||
Reference in New Issue
Block a user