2e0820f08c
- Runs Silabs Commanders which is useful for SiLabs boards that can not use J-Link for various reasons. - Flash support only, no debug. Signed-off-by: Roman Dobrodii <rdobrodii@antmicro.com>
128 lines
4.3 KiB
Python
128 lines
4.3 KiB
Python
# Copyright (c) 2023, Antmicro <www.antmicro.com>
|
|
#
|
|
# Based on J-Link runner
|
|
# Copyright (c) 2017 Linaro Limited.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
"""
|
|
Runner that implements flashing with SiLabs Simplicity Commander binary tool.
|
|
See SiLabs UG162: "Simplicity Commander Reference Guide" for more info.
|
|
"""
|
|
|
|
import os
|
|
import shlex
|
|
from runners.core import ZephyrBinaryRunner, RunnerCaps, FileType
|
|
|
|
|
|
DEFAULT_APP = 'commander'
|
|
|
|
|
|
class SiLabsCommanderBinaryRunner(ZephyrBinaryRunner):
|
|
def __init__(self, cfg, device, dev_id, commander, dt_flash, erase, speed, tool_opt):
|
|
super().__init__(cfg)
|
|
self.file = cfg.file
|
|
self.file_type = cfg.file_type
|
|
self.hex_name = cfg.hex_file
|
|
self.bin_name = cfg.bin_file
|
|
self.elf_name = cfg.elf_file
|
|
self.device = device
|
|
self.dev_id = dev_id
|
|
self.commander = commander
|
|
self.dt_flash = dt_flash
|
|
self.erase = erase
|
|
self.speed = speed
|
|
|
|
self.tool_opt = []
|
|
for opts in [shlex.split(opt) for opt in tool_opt]:
|
|
self.tool_opt += opts
|
|
|
|
@classmethod
|
|
def name(cls):
|
|
return 'silabs_commander'
|
|
|
|
@classmethod
|
|
def capabilities(cls):
|
|
return RunnerCaps(commands={'flash'},
|
|
dev_id=True, flash_addr=True, erase=True,
|
|
tool_opt=True, file=True)
|
|
|
|
@classmethod
|
|
def dev_id_help(cls) -> str:
|
|
return '''Device identifier. Use it to select the J-Link Serial Number
|
|
of the device connected over USB.'''
|
|
|
|
@classmethod
|
|
def tool_opt_help(cls) -> str:
|
|
return "Additional options for Simplicity Commander, e.g. '--noreset'"
|
|
|
|
@classmethod
|
|
def do_add_parser(cls, parser):
|
|
# Required:
|
|
parser.add_argument('--device', required=True,
|
|
help='device part number')
|
|
|
|
# Optional:
|
|
parser.add_argument('--commander', default=DEFAULT_APP,
|
|
help='path to Simplicity Commander executable')
|
|
parser.add_argument('--speed', default=None,
|
|
help='JTAG/SWD speed to use')
|
|
|
|
@classmethod
|
|
def do_create(cls, cfg, args):
|
|
return SiLabsCommanderBinaryRunner(
|
|
cfg, args.device,
|
|
dev_id=args.dev_id,
|
|
commander=args.commander,
|
|
dt_flash=args.dt_flash,
|
|
erase=args.erase,
|
|
speed=args.speed,
|
|
tool_opt=args.tool_opt)
|
|
|
|
def do_run(self, command, **kwargs):
|
|
self.require(self.commander)
|
|
|
|
opts = ['--device', self.device]
|
|
if self.erase:
|
|
opts.append('--masserase')
|
|
if self.dev_id:
|
|
opts.extend(['--serialno', self.dev_id])
|
|
if self.speed is not None:
|
|
opts.extend(['--speed', self.speed])
|
|
|
|
# Get the build artifact to flash
|
|
|
|
if self.dt_flash:
|
|
flash_addr = self.flash_address_from_build_conf(self.build_conf)
|
|
else:
|
|
flash_addr = 0
|
|
|
|
if self.file is not None:
|
|
# use file provided by the user
|
|
if not os.path.isfile(self.file):
|
|
raise ValueError(f'Cannot flash; file ({self.file}) not found')
|
|
|
|
flash_file = self.file
|
|
|
|
if self.file_type == FileType.HEX:
|
|
flash_args = [flash_file]
|
|
elif self.file_type == FileType.BIN:
|
|
flash_args = ['--binary', '--address', f'0x{flash_addr:x}', flash_file]
|
|
else:
|
|
raise ValueError('Cannot flash; this runner only supports hex and bin files')
|
|
|
|
else:
|
|
# use hex or bin file provided by the buildsystem, preferring .hex over .bin
|
|
if self.hex_name is not None and os.path.isfile(self.hex_name):
|
|
flash_file = self.hex_name
|
|
flash_args = [flash_file]
|
|
elif self.bin_name is not None and os.path.isfile(self.bin_name):
|
|
flash_file = self.bin_name
|
|
flash_args = ['--binary', '--address', f'0x{flash_addr:x}', flash_file]
|
|
else:
|
|
raise ValueError(f'Cannot flash; no hex ({self.hex_name}) or bin ({self.bin_name}) files found.')
|
|
|
|
args = [self.commander, 'flash'] + opts + self.tool_opt + flash_args
|
|
|
|
self.logger.info('Flashing file: {}'.format(flash_file))
|
|
self.check_call(args)
|