Files
nrf5340_audio/tools/buildprog/program.py

136 lines
4.4 KiB
Python

#
# 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()