| # Copyright (c) 2017 Linaro Limited. | 
 | # Copyright (c) 2019 Intel Corporation | 
 | # | 
 | # SPDX-License-Identifier: Apache-2.0 | 
 |  | 
 | '''Dediprog (dpcmd) flash only runner for SPI chips.''' | 
 |  | 
 | import platform | 
 | import subprocess | 
 |  | 
 | from runners.core import RunnerCaps, ZephyrBinaryRunner | 
 |  | 
 | DPCMD_EXE = 'dpcmd.exe' if platform.system() == 'Windows' else 'dpcmd' | 
 | DEFAULT_MAX_RETRIES = 3 | 
 |  | 
 | class DediProgBinaryRunner(ZephyrBinaryRunner): | 
 |     '''Runner front-end for DediProg (dpcmd).''' | 
 |  | 
 |     def __init__(self, cfg, spi_image, vcc, retries): | 
 |         super().__init__(cfg) | 
 |         self.spi_image = spi_image | 
 |         self.vcc = vcc | 
 |         self.dpcmd_retries = retries | 
 |  | 
 |     @classmethod | 
 |     def name(cls): | 
 |         return 'dediprog' | 
 |  | 
 |     @classmethod | 
 |     def capabilities(cls): | 
 |         return RunnerCaps(commands={'flash'}) | 
 |  | 
 |     @classmethod | 
 |     def do_add_parser(cls, parser): | 
 |         parser.add_argument('--spi-image', required=True, | 
 |                             help='path to SPI image') | 
 |         parser.add_argument('--vcc', | 
 |                             help='VCC (0=3.5V, 1=2.5V, 2=1.8V)') | 
 |         parser.add_argument('--retries', default=5, | 
 |                             help='Number of retries (default 5)') | 
 |  | 
 |     @classmethod | 
 |     def do_create(cls, cfg, args): | 
 |         return DediProgBinaryRunner(cfg, | 
 |                                     spi_image=args.spi_image, | 
 |                                     vcc=args.vcc, | 
 |                                     retries=args.retries) | 
 |  | 
 |     def do_run(self, command, **kwargs): | 
 |         self.require(DPCMD_EXE) | 
 |         cmd_flash = [DPCMD_EXE, '--auto', self.spi_image] | 
 |  | 
 |         if self.vcc: | 
 |             cmd_flash.append('--vcc') | 
 |             cmd_flash.append(self.vcc) | 
 |  | 
 |         # Allow to flash images smaller than flash device capacity | 
 |         cmd_flash.append('-x') | 
 |         cmd_flash.append('ff') | 
 |  | 
 |         cmd_flash.append('--silent') | 
 |         cmd_flash.append('--verify') | 
 |  | 
 |         try: | 
 |             max_retries = int(self.dpcmd_retries) | 
 |         except ValueError: | 
 |             max_retries = DEFAULT_MAX_RETRIES | 
 |  | 
 |         retries = 0 | 
 |         while retries <= max_retries: | 
 |             try: | 
 |                 self.check_call(cmd_flash) | 
 |             except subprocess.CalledProcessError as cpe: | 
 |                 retries += 1 | 
 |                 if retries > max_retries: | 
 |                     raise cpe | 
 |                 else: | 
 |                     continue | 
 |  | 
 |             break |