Initial commit for nrf5340_audio

This commit is contained in:
2025-06-30 09:28:01 +02:00
commit 62dbb94724
174 changed files with 27001 additions and 0 deletions

View File

@@ -0,0 +1,418 @@
#
# Copyright (c) 2018 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
"""
Script to build and program the nRF5340 Audio project to multiple devices
"""
import argparse
import sys
import shutil
import os
import json
import subprocess
import re
import getpass
from pathlib import Path
from colorama import Fore, Style
from prettytable import PrettyTable
from nrf5340_audio_dk_devices import (
BuildType,
Channel,
DeviceConf,
BuildConf,
AudioDevice,
SelectFlags,
Core,
Transport,
)
from program import program_threads_run
BUILDPROG_FOLDER = Path(__file__).resolve().parent
NRF5340_AUDIO_FOLDER = (BUILDPROG_FOLDER / "../..").resolve()
NRF_FOLDER = (BUILDPROG_FOLDER / "../../../..").resolve()
if os.getenv("AUDIO_KIT_SERIAL_NUMBERS_JSON") is None:
AUDIO_KIT_SERIAL_NUMBERS_JSON = BUILDPROG_FOLDER / "nrf5340_audio_dk_devices.json"
else:
AUDIO_KIT_SERIAL_NUMBERS_JSON = Path(
os.getenv("AUDIO_KIT_SERIAL_NUMBERS_JSON"))
TARGET_BOARD_NRF5340_AUDIO_DK_APP_NAME = "nrf5340_audio_dk/nrf5340/cpuapp"
TARGET_AUDIO_FOLDER = NRF5340_AUDIO_FOLDER
TARGET_AUDIO_BUILD_FOLDER = TARGET_AUDIO_FOLDER / "tools/build"
UNICAST_SERVER_OVERLAY = NRF5340_AUDIO_FOLDER / "unicast_server/overlay-unicast_server.conf"
UNICAST_CLIENT_OVERLAY = NRF5340_AUDIO_FOLDER / "unicast_client/overlay-unicast_client.conf"
BROADCAST_SINK_OVERLAY = NRF5340_AUDIO_FOLDER / "broadcast_sink/overlay-broadcast_sink.conf"
BROADCAST_SOURCE_OVERLAY = NRF5340_AUDIO_FOLDER / "broadcast_source/overlay-broadcast_source.conf"
TARGET_RELEASE_FOLDER = "build_release"
TARGET_DEBUG_FOLDER = "build_debug"
MAX_USER_NAME_LEN = 248 - len('\0')
def __print_add_color(status):
if status == SelectFlags.FAIL:
return Fore.RED + status.value + Style.RESET_ALL
elif status == SelectFlags.DONE:
return Fore.GREEN + status.value + Style.RESET_ALL
return status.value
def __print_dev_conf(device_list):
"""Print settings in a formatted manner"""
table = PrettyTable()
table.field_names = [
"snr",
"snr conn",
"device",
"only reboot",
"core app programmed",
"core net programmed",
]
for device in device_list:
row = []
row.append(device.nrf5340_audio_dk_snr)
color = Fore.GREEN if device.snr_connected else Fore.YELLOW
row.append(color + str(device.snr_connected) + Style.RESET_ALL)
row.append(device.nrf5340_audio_dk_dev.value)
row.append(__print_add_color(device.only_reboot))
row.append(__print_add_color(device.core_app_programmed))
row.append(__print_add_color(device.core_net_programmed))
table.add_row(row)
print(table)
def __build_cmd_get(core: Core, device: AudioDevice, build: BuildType,
pristine, options):
build_cmd = (f"west build {TARGET_AUDIO_FOLDER} "
f"-b {TARGET_BOARD_NRF5340_AUDIO_DK_APP_NAME} "
f"--sysbuild")
if core == Core.app:
build_cmd += " --domain nrf5340_audio"
elif core == Core.net:
build_cmd += " --domain ipc_radio"
else:
raise Exception("Invalid core!")
if build == BuildType.debug:
release_flag = ""
elif build == BuildType.release:
release_flag = " -DFILE_SUFFIX=release"
else:
raise Exception("Invalid build type!")
device_flag = ""
if options.nrf21540:
device_flag += " -Dnrf5340_audio_SHIELD=nrf21540ek"
device_flag += " -Dipc_radio_SHIELD=nrf21540ek"
if options.custom_bt_name is not None and options.user_bt_name:
raise Exception(
"User BT name option is invalid when custom BT name is set")
if options.custom_bt_name is not None:
custom_bt_name = "_".join(options.custom_bt_name)[
:MAX_USER_NAME_LEN].upper()
device_flag += " -DCONFIG_BT_DEVICE_NAME=\\\"" + custom_bt_name + "\\\""
if options.user_bt_name:
user_specific_bt_name = (
"AUDIO_DEV_" + getpass.getuser())[:MAX_USER_NAME_LEN].upper()
device_flag += " -DCONFIG_BT_DEVICE_NAME=\\\"" + user_specific_bt_name + "\\\""
if options.transport == Transport.broadcast.name:
if device == AudioDevice.headset:
overlay_flag = f" -DEXTRA_CONF_FILE={BROADCAST_SINK_OVERLAY}"
else:
overlay_flag = f" -DEXTRA_CONF_FILE={BROADCAST_SOURCE_OVERLAY}"
else:
if device == AudioDevice.headset:
overlay_flag = f" -DEXTRA_CONF_FILE={UNICAST_SERVER_OVERLAY}"
else:
overlay_flag = f" -DEXTRA_CONF_FILE={UNICAST_CLIENT_OVERLAY}"
if os.name == 'nt':
release_flag = release_flag.replace('\\', '/')
if pristine:
build_cmd += " --pristine"
dest_folder = TARGET_AUDIO_BUILD_FOLDER / options.transport / device / core / build
return build_cmd, dest_folder, device_flag, release_flag, overlay_flag
def __build_module(build_config, options):
build_cmd, dest_folder, device_flag, release_flag, overlay_flag = __build_cmd_get(
build_config.core,
build_config.device,
build_config.build,
build_config.pristine,
options,
)
west_str = f"{build_cmd} -d {dest_folder} "
if build_config.pristine and dest_folder.exists():
shutil.rmtree(dest_folder)
# Only add compiler flags if folder doesn't exist already
if not dest_folder.exists():
west_str = west_str + device_flag + release_flag + overlay_flag
print("Run: " + west_str)
ret_val = os.system(west_str)
if ret_val:
raise Exception("cmake error: " + str(ret_val))
def __find_snr():
"""Rebooting or programming requires connected programmer/debugger"""
# Use nrfjprog executable for WSL compatibility
stdout = subprocess.check_output(
"nrfjprog --ids", shell=True).decode("utf-8")
snrs = re.findall(r"([\d]+)", stdout)
if not snrs:
print("No programmer/debugger connected to PC")
return list(map(int, snrs))
def __populate_hex_paths(dev, options):
"""Poplulate hex paths where relevant"""
_, temp_dest_folder, _, _, _ = __build_cmd_get(Core.app, dev.nrf5340_audio_dk_dev, options.build, options.pristine, options)
dev.hex_path_app = temp_dest_folder / "nrf5340_audio/zephyr/zephyr.hex"
_, temp_dest_folder, _, _, _ = __build_cmd_get(Core.net, dev.nrf5340_audio_dk_dev, options.build, options.pristine, options)
dev.hex_path_net = temp_dest_folder / "ipc_radio/zephyr/zephyr.hex"
def __finish(device_list):
"""Finish script. Print report"""
print("build_prog.py finished. Report:")
__print_dev_conf(device_list)
exit(0)
def __main():
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=(
"This script builds and programs the nRF5340 "
"Audio project on Windows and Linux"
),
epilog=("If there exists an environmental variable called \"AUDIO_KIT_SERIAL_NUMBERS_JSON\""
"which contains the location of a json file,"
"the program will use this file as a substitute for nrf5340_audio_dk_devices.json"),
allow_abbrev=False
)
parser.add_argument(
"-r",
"--only_reboot",
default=False,
action="store_true",
help="Only reboot, no building or programming",
)
parser.add_argument(
"-p",
"--program",
default=False,
action="store_true",
help="Will program and reboot nRF5340 Audio DK",
)
parser.add_argument(
"-c",
"--core",
type=str,
choices=[i.name for i in Core],
help="Select which cores to include in build",
)
parser.add_argument(
"--pristine",
default=False,
action="store_true",
help="Will build cleanly"
)
parser.add_argument(
"-b",
"--build",
required="-p" in sys.argv or "--program" in sys.argv,
choices=[i.name for i in BuildType],
help="Select the build type",
)
parser.add_argument(
"-d",
"--device",
required=("-r" in sys.argv or "--only_reboot" in sys.argv)
or (
("-b" in sys.argv or "--build" in sys.argv)
and ("both" in sys.argv or "app" in sys.argv)
),
choices=[i.name for i in AudioDevice],
help=(
"nRF5340 Audio on the application core can be "
"built for either ordinary headset "
"(earbuds/headphone..) use or gateway (USB dongle)"
),
)
parser.add_argument(
"-s",
"--sequential",
action="store_true",
dest="sequential_prog",
default=False,
help="Run nrfjprog sequentially instead of in parallel",
)
parser.add_argument(
"-f",
"--recover_on_fail",
action="store_true",
dest="recover_on_fail",
default=False,
help="Recover device if programming fails",
)
parser.add_argument(
"--nrf21540",
action="store_true",
dest="nrf21540",
default=False,
help="Set when using nRF21540 for extra TX power",
)
parser.add_argument(
"-cn",
"--custom_bt_name",
nargs='*',
dest="custom_bt_name",
default=None,
help="Use custom Bluetooth device name",
)
parser.add_argument(
"-u",
"--user_bt_name",
action="store_true",
dest="user_bt_name",
default=False,
help="Set to generate a user specific Bluetooth device name.\
Note that this will put the computer user name on air in clear text",
)
parser.add_argument(
"-t",
"--transport",
required=True,
choices=[i.name for i in Transport],
default=Transport.unicast.name,
help="Select the transport type",
)
options = parser.parse_args(args=sys.argv[1:])
# Post processing for Enums
if options.core is None:
cores = []
elif options.core == "both":
cores = [Core.app, Core.net]
else:
cores = [Core[options.core]]
if options.device is None:
devices = []
elif options.device == "both":
devices = [AudioDevice.gateway, AudioDevice.headset]
else:
devices = [AudioDevice[options.device]]
options.build = BuildType[options.build] if options.build else None
options.only_reboot = SelectFlags.TBD if options.only_reboot else SelectFlags.NOT
boards_snr_connected = __find_snr()
if not boards_snr_connected:
print("No snrs connected")
# Update device list
# This JSON file should be altered by the developer.
# Then run git update-index --skip-worktree FILENAME to avoid changes
# being pushed
with AUDIO_KIT_SERIAL_NUMBERS_JSON.open() as f:
dev_arr = json.load(f)
device_list = [
DeviceConf(
nrf5340_audio_dk_snr=dev["nrf5340_audio_dk_snr"],
channel=Channel[dev["channel"]],
snr_connected=(dev["nrf5340_audio_dk_snr"]
in boards_snr_connected),
recover_on_fail=options.recover_on_fail,
nrf5340_audio_dk_dev=AudioDevice[dev["nrf5340_audio_dk_dev"]],
cores=cores,
devices=devices,
_only_reboot=options.only_reboot,
)
for dev in dev_arr
]
__print_dev_conf(device_list)
# Initialization step finsihed
# Reboot step start
if options.only_reboot == SelectFlags.TBD:
program_threads_run(device_list, sequential=options.sequential_prog)
__finish(device_list)
# Reboot step finished
# Build step start
if options.build is not None:
print("Invoking build step")
build_configs = []
if AudioDevice.headset in devices:
for c in cores:
build_configs.append(
BuildConf(
core=c,
device=AudioDevice.headset,
pristine=options.pristine,
build=options.build,
)
)
if AudioDevice.gateway in devices:
for c in cores:
build_configs.append(
BuildConf(
core=c,
device=AudioDevice.gateway,
pristine=options.pristine,
build=options.build,
)
)
for build_cfg in build_configs:
__build_module(build_cfg, options)
# Build step finished
# Program step start
if options.program:
for dev in device_list:
if dev.snr_connected:
__populate_hex_paths(dev, options)
program_threads_run(device_list, sequential=options.sequential_prog)
# Program step finished
__finish(device_list)
if __name__ == "__main__":
__main()

View File

@@ -0,0 +1,96 @@
#
# Copyright (c) 2022 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
"""
Generate fw_info for B0N container from .config
"""
from intelhex import IntelHex
import argparse
import struct
def get_fw_info(input_hex, offset, magic_value, fw_version, fw_valid_val):
# 0x0c start of fw_info_total_size
# 0x10 start of flash_used
# 0x14 start of fw_version
# 0x18 the address of the start of the image
# 0x1c the address of the boot point (vector table) of the firmware
# 0x20 the address Value that can be modified to invalidate the firmware
fw_info_bytes = magic_value
for i in range(0xc, 0x14):
fw_info_bytes += input_hex[offset + i].to_bytes(1, byteorder='little')
fw_info_bytes += struct.pack('<I', fw_version)
for i in range(0x18, 0x20):
fw_info_bytes += input_hex[offset + i].to_bytes(1, byteorder='little')
fw_info_bytes += fw_valid_val
return fw_info_bytes
def inject_fw_info(input_file, offset, output_hex, magic_value, fw_version, fw_valid_val):
ih = IntelHex(input_file)
# OBJCOPY incorrectly inserts x86 specific records, remove the start_addr as it is wrong.
ih.start_addr = None
# Parse comma-separated string of uint32s into hex string. Each is encoded in little-endian byte order
parsed_magic_value = b''.join(
[struct.pack('<I', int(m, 0)) for m in magic_value.split(',')])
# Parse string of uint32s into hex string. Each is encoded in little-endian byte order
parsed_fw_valid_val = struct.pack('<I', fw_valid_val)
parsed_fw_version = '0x%08X' % fw_version
print(parsed_fw_version)
fw_info_data = get_fw_info(input_hex=ih,
offset=offset,
magic_value=parsed_magic_value,
fw_version=fw_version,
fw_valid_val=parsed_fw_valid_val)
fw_info_data_data_hex = IntelHex()
fw_info_data_data_hex.frombytes(fw_info_data, offset)
ih.merge(fw_info_data_data_hex, overlap='replace')
ih.write_hex_file(output_hex)
def parse_args():
parser = argparse.ArgumentParser(
description='Inject fw info metadata at specified offset. Generate HEX file',
formatter_class=argparse.RawDescriptionHelpFormatter,
allow_abbrev=False)
parser.add_argument('-i', '--input', required=True, type=argparse.FileType('r', encoding='UTF-8'),
help='Input hex file.')
parser.add_argument('--offset', required=True, type=lambda x: int(x, 0),
help='Offset to store validation metadata at.', default=0x01008A00)
parser.add_argument('-m', '--magic-value', required=True,
help='ASCII representation of magic value.')
parser.add_argument('-v', '--fw-version', required=True, type=int,
help='Fw version.')
parser.add_argument('-l', '--fw-valid-val', required=True, type=lambda x: int(x, 0),
help='ASCII representation of fw valid val.')
parser.add_argument('-o', '--output-hex', required=False, default=None, type=argparse.FileType('w'),
help='.hex output file name. Default is to overwrite --input.')
args = parser.parse_args()
if args.output_hex is None:
args.output_hex = args.input
return args
def main():
args = parse_args()
inject_fw_info(input_file=args.input,
offset=args.offset,
output_hex=args.output_hex,
magic_value=args.magic_value,
fw_version=args.fw_version,
fw_valid_val=args.fw_valid_val)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,17 @@
[
{
"nrf5340_audio_dk_snr": 1000,
"nrf5340_audio_dk_dev": "headset",
"channel": "left"
},
{
"nrf5340_audio_dk_snr": 1000,
"nrf5340_audio_dk_dev": "gateway",
"channel": "NA"
},
{
"nrf5340_audio_dk_snr": 1000,
"nrf5340_audio_dk_dev": "headset",
"channel": "right"
}
]

View File

@@ -0,0 +1,107 @@
#
# Copyright (c) 2018 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
"""
Settings for building and flashing nRF5340 Audio DK for different targets.
"""
from dataclasses import InitVar, dataclass, field
from enum import auto, Enum
from pathlib import Path
from typing import List
class SelectFlags(str, Enum):
"""Holds the available status flags"""
NOT = "Not selected"
TBD = "Selected"
DONE = "Done"
FAIL = "Failed"
class Core(str, Enum):
"""SoC core"""
app = "app"
net = "net"
both = "both"
class AudioDevice(str, Enum):
"""Audio device"""
headset = "headset"
gateway = "gateway"
both = "both"
class BuildType(str, Enum):
"""Release or debug build"""
release = "release"
debug = "debug"
class Channel(Enum):
"""Left or right Value represents UICR channel"""
left = 0
right = 1
NA = auto()
class Transport(str, Enum):
"""Transport type"""
broadcast = "broadcast"
unicast = "unicast"
@dataclass
class DeviceConf:
"""This config is populated according to connected SEGGER serial numbers
(snr) and command line arguments"""
# Constructor variables
nrf5340_audio_dk_snr: int
channel: Channel
snr_connected: bool
nrf5340_audio_dk_dev: AudioDevice
recover_on_fail: bool
cores: InitVar[List[Core]]
devices: InitVar[List[AudioDevice]]
_only_reboot: InitVar[SelectFlags]
# Post init variables
only_reboot: SelectFlags = field(init=False, default=SelectFlags.NOT)
hex_path_app: Path = field(init=False, default=None)
core_app_programmed: SelectFlags = field(
init=False, default=SelectFlags.NOT)
hex_path_net: Path = field(init=False, default=None)
core_net_programmed: SelectFlags = field(
init=False, default=SelectFlags.NOT)
def __post_init__(
self, cores: List[Core], devices: List[AudioDevice], _only_reboot: SelectFlags,
):
device_selected = self.nrf5340_audio_dk_dev in devices
self.only_reboot = _only_reboot if device_selected else SelectFlags.NOT
if self.only_reboot == SelectFlags.TBD:
return
if (Core.app in cores) and device_selected:
self.core_app_programmed = SelectFlags.TBD
if (Core.net in cores) and device_selected:
self.core_net_programmed = SelectFlags.TBD
def __str__(self):
result = f"{self.nrf5340_audio_dk_snr} {self.nrf5340_audio_dk_dev.name}"
if self.nrf5340_audio_dk_dev == AudioDevice.headset:
result += f" {self.channel.name}"
return result
@dataclass
class BuildConf:
"""Build config"""
core: Core
device: AudioDevice
build: BuildType
pristine: bool

135
tools/buildprog/program.py Normal file
View File

@@ -0,0 +1,135 @@
#
# Copyright (c) 2018 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
""" Tools to program multiple nRF5340 Audio DKs """
from threading import Thread
from os import system, path
from typing import List
from nrf5340_audio_dk_devices import DeviceConf, SelectFlags, AudioDevice
MEM_ADDR_UICR_SNR = 0x00FF80F0
MEM_ADDR_UICR_CH = 0x00FF80F4
def __populate_uicr(dev):
"""Program UICR in device with information from JSON file"""
if dev.nrf5340_audio_dk_dev == AudioDevice.headset:
cmd = (f"nrfjprog --memwr {MEM_ADDR_UICR_CH} --val {dev.channel.value} "
f"--snr {dev.nrf5340_audio_dk_snr}")
# Write channel information to UICR
print("Programming UICR")
ret_val = system(cmd)
if ret_val:
return False
cmd = (f"nrfjprog --memwr {MEM_ADDR_UICR_SNR} --val {dev.nrf5340_audio_dk_snr} "
f"--snr {dev.nrf5340_audio_dk_snr}")
# Write segger nr to UICR
ret_val = system(cmd)
if ret_val:
return False
else:
return True
def _program_cores(dev: DeviceConf) -> int:
if dev.core_net_programmed == SelectFlags.TBD:
if not path.isfile(dev.hex_path_net):
print(f"NET core hex not found. Built only for APP core. {dev.hex_path_net}")
else:
print(f"Programming net core on: {dev}")
cmd = (f"nrfjprog --program {dev.hex_path_net} -f NRF53 -q "
f"--snr {dev.nrf5340_audio_dk_snr} --sectorerase --coprocessor CP_NETWORK")
ret_val = system(cmd)
if ret_val != 0:
if not dev.recover_on_fail:
dev.core_net_programmed = SelectFlags.FAIL
return ret_val
else:
dev.core_net_programmed = SelectFlags.DONE
if dev.core_app_programmed == SelectFlags.TBD:
if not path.isfile(dev.hex_path_app):
print(f"APP core hex not found. Built only for NET core. {dev.hex_path_app}")
return 1
else:
print(f"Programming app core on: {dev}")
cmd = (f"nrfjprog --program {dev.hex_path_app} -f NRF53 -q "
f"--snr {dev.nrf5340_audio_dk_snr} --chiperase --coprocessor CP_APPLICATION")
ret_val = system(cmd)
if ret_val != 0:
if not dev.recover_on_fail:
dev.core_app_programmed = SelectFlags.FAIL
return ret_val
else:
dev.core_app_programmed = SelectFlags.DONE
# Populate UICR data matching the JSON file
if not __populate_uicr(dev):
dev.core_app_programmed = SelectFlags.FAIL
return 1
if dev.core_net_programmed != SelectFlags.NOT or dev.core_app_programmed != SelectFlags.NOT:
print(f"Resetting {dev}")
cmd = f"nrfjprog -r --snr {dev.nrf5340_audio_dk_snr}"
ret_val = system(cmd)
if ret_val != 0:
return ret_val
return 0
def _recover(dev: DeviceConf):
print(f"Recovering device: {dev}")
ret_val = system(
f"nrfjprog --recover --coprocessor CP_NETWORK --snr {dev.nrf5340_audio_dk_snr}"
)
if ret_val != 0:
dev.core_net_programmed = SelectFlags.FAIL
ret_val = system(
f"nrfjprog --recover --coprocessor CP_APPLICATION --snr {dev.nrf5340_audio_dk_snr}"
)
if ret_val != 0:
dev.core_app_programmed = SelectFlags.FAIL
def __program_thread(dev: DeviceConf):
if dev.only_reboot == SelectFlags.TBD:
print(f"Resetting {dev}")
cmd = f"nrfjprog -r --snr {dev.nrf5340_audio_dk_snr}"
ret_val = system(cmd)
dev.only_reboot = SelectFlags.FAIL if ret_val else SelectFlags.DONE
return
return_code = _program_cores(dev)
if return_code != 0 and dev.recover_on_fail:
_recover(dev)
_program_cores(dev)
def program_threads_run(devices_list: List[DeviceConf], sequential: bool = False):
"""Program devices in parallel"""
threads = []
# First program net cores if applicable
for dev in devices_list:
if not dev.snr_connected:
dev.only_reboot = SelectFlags.NOT
dev.core_app_programmed = SelectFlags.NOT
dev.core_net_programmed = SelectFlags.NOT
continue
thread = Thread(target=__program_thread, args=(dev,))
threads.append(thread)
thread.start()
if sequential:
thread.join()
for thread in threads:
thread.join()
threads.clear()

View File

@@ -0,0 +1,28 @@
#
# Copyright (c) 2022 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
import sys
import subprocess
def get_serial_ports():
nrfjprog_com = subprocess.Popen(["nrfjprog", "--com"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
nrfjprog_com.wait()
if nrfjprog_com.returncode != 0:
sys.exit("'nrfjprog --com' failed")
output = nrfjprog_com.communicate()
output_decoded = output[0].decode()
output_decoded_lines = output_decoded.splitlines()
ports = list()
for line in output_decoded_lines:
if "VCOM0" in line:
info = line.split(" ")
ports.append(info[1])
return ports

View File

@@ -0,0 +1,62 @@
[global_config]
suppress_multiple_term_dialog = True
[keybindings]
[profiles]
[[default]]
cursor_color = "#aaaaaa"
scrollback_infinite = True
[layouts]
[[default]]
[[[child0]]]
type = Window
parent = ""
order = 0
position = 72:35
maximised = False
fullscreen = False
size = 2000, 1000
title = nRF5340 Audio DK
last_active_window = True
[[[child1]]]
type = VPaned
parent = child0
order = 0
position = 540
ratio = 0.5
[[[child2]]]
type = HPaned
parent = child1
order = 0
position = 600
ratio = 0.5
[[[terminal3]]]
type = Terminal
parent = child2
order = 0
profile = default
command = python3 scripts/open_terminator.py 0; sh
[[[terminal4]]]
type = Terminal
parent = child2
order = 1
profile = default
command = python3 scripts/open_terminator.py 1; sh
[[[child5]]]
type = HPaned
parent = child1
order = 1
position = 600
ratio = 0.5
[[[terminal6]]]
type = Terminal
parent = child5
order = 0
profile = default
command = python3 scripts/open_terminator.py 2; sh
[[[terminal7]]]
type = Terminal
parent = child5
order = 1
profile = default
command = echo Available ttyACM devices: && cd /dev/ && ls -l | grep "ttyACM"; bash
[plugins]

View File

@@ -0,0 +1,15 @@
#
# Copyright (c) 2022 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
import subprocess
from get_serial_ports import get_serial_ports
def open_putty():
ports = get_serial_ports()
for port in ports:
subprocess.Popen("putty -serial " + port + " -sercfg 115200,8,n,1,N")

View File

@@ -0,0 +1,16 @@
#
# Copyright (c) 2022 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
import sys
import subprocess
from get_serial_ports import get_serial_ports
ports = get_serial_ports()
if int(sys.argv[1]) < len(ports):
subprocess.Popen(["minicom", "--color=on", "-b 115200", "-8", "-D " + ports[int(sys.argv[1])]])
else:
print("Not enough boards connected")

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2022 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
import sys
import subprocess
sys.path.append("./scripts")
from open_putty import open_putty
if sys.platform == "linux":
terminator = subprocess.Popen(["terminator", "--config=scripts/linux_terminator_config"], stderr=subprocess.PIPE)
elif sys.platform == "win32":
open_putty()
else:
print("OS not supported")