1# Copyright (c) 2017 Linaro Limited. 2# Copyright (c) 2019 Intel Corporation 3# 4# SPDX-License-Identifier: Apache-2.0 5 6'''Dediprog (dpcmd) flash only runner for SPI chips.''' 7 8import platform 9import subprocess 10 11from runners.core import ZephyrBinaryRunner, RunnerCaps 12 13DPCMD_EXE = 'dpcmd.exe' if platform.system() == 'Windows' else 'dpcmd' 14DEFAULT_MAX_RETRIES = 3 15 16class DediProgBinaryRunner(ZephyrBinaryRunner): 17 '''Runner front-end for DediProg (dpcmd).''' 18 19 def __init__(self, cfg, spi_image, vcc, retries): 20 super().__init__(cfg) 21 self.spi_image = spi_image 22 self.vcc = vcc 23 self.dpcmd_retries = retries 24 25 @classmethod 26 def name(cls): 27 return 'dediprog' 28 29 @classmethod 30 def capabilities(cls): 31 return RunnerCaps(commands={'flash'}) 32 33 @classmethod 34 def do_add_parser(cls, parser): 35 parser.add_argument('--spi-image', required=True, 36 help='path to SPI image') 37 parser.add_argument('--vcc', 38 help='VCC (0=3.5V, 1=2.5V, 2=1.8V)') 39 parser.add_argument('--retries', default=5, 40 help='Number of retries (default 5)') 41 42 @classmethod 43 def do_create(cls, cfg, args): 44 return DediProgBinaryRunner(cfg, 45 spi_image=args.spi_image, 46 vcc=args.vcc, 47 retries=args.retries) 48 49 def do_run(self, command, **kwargs): 50 self.require(DPCMD_EXE) 51 cmd_flash = [DPCMD_EXE, '--auto', self.spi_image] 52 53 if self.vcc: 54 cmd_flash.append('--vcc') 55 cmd_flash.append(self.vcc) 56 57 # Allow to flash images smaller than flash device capacity 58 cmd_flash.append('-x') 59 cmd_flash.append('ff') 60 61 cmd_flash.append('--silent') 62 cmd_flash.append('--verify') 63 64 try: 65 max_retries = int(self.dpcmd_retries) 66 except ValueError: 67 max_retries = DEFAULT_MAX_RETRIES 68 69 retries = 0 70 while retries <= max_retries: 71 try: 72 self.check_call(cmd_flash) 73 except subprocess.CalledProcessError as cpe: 74 retries += 1 75 if retries > max_retries: 76 raise cpe 77 else: 78 continue 79 80 break 81