# Copyright (c) 2021, Telink Semiconductor # # SPDX-License-Identifier: Apache-2.0 import os import time import subprocess from runners.core import ZephyrBinaryRunner, RunnerCaps class SpiBurnBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for SPI_burn.''' def __init__(self, cfg, addr, spiburn, iceman, erase=False): super().__init__(cfg) self.bin = cfg.bin_file self.spiburn = spiburn self.iceman = iceman self.addr = addr self.erase = bool(erase) @classmethod def name(cls): return 'spi_burn' @classmethod def capabilities(cls): return RunnerCaps(commands={'flash'}, erase=True) @classmethod def do_add_parser(cls, parser): parser.add_argument('--addr', default='0x0', help='start flash address to write') parser.add_argument('--telink-tools-path', help='path to Telink flash tools') @classmethod def do_create(cls, cfg, args): if args.telink_tools_path: spiburn = f'{args.telink_tools_path}/flash/bin/SPI_burn' iceman = f'{args.telink_tools_path}/ice/ICEman' else: # If telink_tools_path arg is not specified then pass to tools shall be specified in PATH spiburn = 'SPI_burn' iceman = 'ICEman' return SpiBurnBinaryRunner(cfg, args.addr, spiburn, iceman, args.erase) def do_run(self, command, **kwargs): self.require(self.spiburn) # Find path to ICEman with require call self.iceman_path = self.require(self.iceman) if command == "flash": self._flash() else: self.logger.error(f'{command} not supported!') def _flash(self): origin_dir = os.getcwd() iceman_dir = os.path.dirname(self.iceman_path) try: # ICEman tool from Andestech is required to be run from its root dir, # due to the tool looking for its config files in currently active dir. # In attempt to run it from other dirs it returns with an error that # required config file is missing # Go into ICEman dir os.chdir(iceman_dir) # RUN ice in a background cmd_ice_run = ["./ICEman", '-Z', 'v5', '-l', 'aice_sdp.cfg'] ice_process = subprocess.Popen(cmd_ice_run) # Wait for initialization time.sleep(1) # Compose flash command cmd_flash = [self.spiburn, '--addr', str(self.addr), '--image', self.bin] if self.erase: cmd_flash += ["--erase-all"] # Run SPI burn flash tool self.check_call(cmd_flash) finally: # Kill ICEman ice_process.terminate() # Restore origin dir os.chdir(origin_dir)