build/generic_programmer: add call method that raises OSError when failing and use it on specific programmers.

This will avoid programming errors to be silently ignored and will raise the following error:

OSError: Error occured during OpenOCD's call, please check:
- OpenOCD installation.
- access permissions.
- hardware and cable.
This commit is contained in:
Florent Kermarrec 2020-11-10 10:22:40 +01:00
parent a5bdfe3f4c
commit 2741fc2ba5
6 changed files with 34 additions and 34 deletions

View file

@ -4,8 +4,6 @@
# Copyright (c) 2015-2018 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
import subprocess
from litex.build.generic_programmer import GenericProgrammer
# USBBlaster ---------------------------------------------------------------------------------------
@ -18,8 +16,8 @@ class USBBlaster(GenericProgrammer):
self.device_id = device_id
def load_bitstream(self, bitstream_file, cable_suffix=""):
subprocess.call(["quartus_pgm",
"-m", "jtag",
"-c", "{}{}".format(self.cable_name, cable_suffix),
"-o", "p;{}@{}".format(bitstream_file, self.device_id)
self.call(["quartus_pgm",
"-m", "jtag",
"-c", "{}{}".format(self.cable_name, cable_suffix),
"-o", "p;{}@{}".format(bitstream_file, self.device_id)
])

View file

@ -8,6 +8,7 @@
import os
import sys
import subprocess
from litex.build import tools
@ -90,4 +91,10 @@ class GenericProgrammer:
def flash(self, address, data_file):
raise NotImplementedError
def call(self, command):
if subprocess.call(command) != 0:
msg = f"Error occured during {self.__class__.__name__}'s call, please check:\n"
msg += f"- {self.__class__.__name__} installation.\n"
msg += f"- access permissions.\n"
msg += f"- hardware and cable."
raise OSError(msg)

View file

@ -6,7 +6,6 @@
# SPDX-License-Identifier: BSD-2-Clause
import os
import subprocess
from litex.build.generic_programmer import GenericProgrammer
from litex.build import tools
@ -23,7 +22,7 @@ class LatticeProgrammer(GenericProgrammer):
xcf_file = bitstream_file.replace(".bit", ".xcf")
xcf_content = self.xcf_template.format(bitstream_file=bitstream_file)
tools.write_to_file(xcf_file, xcf_content)
subprocess.call(["pgrcmd", "-infile", xcf_file])
self.call(["pgrcmd", "-infile", xcf_file])
# OpenOCDJTAGProgrammer --------------------------------------------------------------------------------
@ -35,7 +34,7 @@ class OpenOCDJTAGProgrammer(GenericProgrammer):
def load_bitstream(self, bitstream_file):
config = self.find_config()
svf_file = bitstream_file.replace(".bit", ".svf")
subprocess.call(["openocd", "-f", config, "-c", "transport select jtag; init; svf quiet progress \"{}\"; exit".format(svf_file)])
self.call(["openocd", "-f", config, "-c", "transport select jtag; init; svf quiet progress \"{}\"; exit".format(svf_file)])
def flash(self, address, data, verify=True):
config = self.find_config()
@ -52,7 +51,7 @@ class OpenOCDJTAGProgrammer(GenericProgrammer):
"flash verify_bank spi0 \"{0}\" 0x{1:x}" if verify else "".format(data, address),
"exit"
])
subprocess.call(["openocd", "-f", config, "-c", script])
self.call(["openocd", "-f", config, "-c", script])
# IceStormProgrammer -------------------------------------------------------------------------------
@ -60,10 +59,10 @@ class IceStormProgrammer(GenericProgrammer):
needs_bitreverse = False
def flash(self, address, bitstream_file):
subprocess.call(["iceprog", "-o", str(address), bitstream_file])
self.call(["iceprog", "-o", str(address), bitstream_file])
def load_bitstream(self, bitstream_file):
subprocess.call(["iceprog", "-S", bitstream_file])
self.call(["iceprog", "-S", bitstream_file])
# IceBurnProgrammer --------------------------------------------------------------------------------
@ -75,7 +74,7 @@ class IceBurnProgrammer(GenericProgrammer):
needs_bitreverse = False
def load_bitstream(self, bitstream_file):
subprocess.call([self.iceburn, "-evw", bitstream_file])
self.call([self.iceburn, "-evw", bitstream_file])
# TinyFpgaBProgrammer ------------------------------------------------------------------------------
@ -85,13 +84,13 @@ class TinyFpgaBProgrammer(GenericProgrammer):
# The default flash address you probably want is 0x30000; the image at
# address 0 is for the bootloader.
def flash(self, address, bitstream_file):
subprocess.call(["tinyfpgab", "-a", str(address), "-p",
self.call(["tinyfpgab", "-a", str(address), "-p",
bitstream_file])
# Force user image to boot if a user reset tinyfpga, the bootloader
# is active, and the user image need not be reprogrammed.
def boot(self):
subprocess.call(["tinyfpgab", "-b"])
self.call(["tinyfpgab", "-b"])
# TinyProgProgrammer -------------------------------------------------------------------------------
@ -108,19 +107,19 @@ class TinyProgProgrammer(GenericProgrammer):
if not user_data:
# tinyprog looks at spi flash metadata to figure out where to
# program your bitstream.
subprocess.call(["tinyprog", "-p", bitstream_file])
self.call(["tinyprog", "-p", bitstream_file])
else:
# Ditto with user data.
subprocess.call(["tinyprog", "-u", bitstream_file])
self.call(["tinyprog", "-u", bitstream_file])
else:
# Provide override so user can program wherever they wish.
subprocess.call(["tinyprog", "-a", str(address), "-p",
self.call(["tinyprog", "-a", str(address), "-p",
bitstream_file])
# Force user image to boot if a user reset tinyfpga, the bootloader
# is active, and the user image need not be reprogrammed.
def boot(self):
subprocess.call(["tinyprog", "-b"])
self.call(["tinyprog", "-b"])
# MyStormProgrammer --------------------------------------------------------------------------------
@ -140,4 +139,4 @@ class UJProg(GenericProgrammer):
needs_bitreverse = False
def load_bitstream(self, bitstream_file):
subprocess.call(["ujprog", bitstream_file])
self.call(["ujprog", bitstream_file])

View file

@ -4,8 +4,6 @@
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
import subprocess
from litex.build.tools import write_to_file
from litex.build.generic_programmer import GenericProgrammer
@ -21,4 +19,4 @@ class OpenFPGALoader(GenericProgrammer):
cmd = ["openFPGALoader", "--board", self.board, "--bitstream", bitstream_file]
if flash:
cmd.append("--write-flash")
subprocess.call(cmd)
self.call(cmd)

View file

@ -6,8 +6,6 @@
# Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
import subprocess
from litex.build.tools import write_to_file
from litex.build.generic_programmer import GenericProgrammer
@ -26,7 +24,7 @@ class OpenOCD(GenericProgrammer):
"pld load 0 {{{}}}".format(bitstream),
"exit",
])
subprocess.call(["openocd", "-f", config, "-c", script])
self.call(["openocd", "-f", config, "-c", script])
def flash(self, address, data, set_qe=False):
config = self.find_config()
@ -39,7 +37,7 @@ class OpenOCD(GenericProgrammer):
"fpga_program",
"exit"
])
subprocess.call(["openocd", "-f", config, "-c", script])
self.call(["openocd", "-f", config, "-c", script])
def stream(self, port=20000):
@ -144,4 +142,4 @@ proc jtagstream_serve {tap port} {
"exit",
])
config = self.find_config()
subprocess.call(["openocd", "-f", config, "-f", "stream.cfg", "-c", script])
self.call(["openocd", "-f", config, "-f", "stream.cfg", "-c", script])

View file

@ -61,11 +61,11 @@ class XC3SProg(GenericProgrammer):
self.position = position
def load_bitstream(self, bitstream_file):
subprocess.call(["xc3sprog", "-v", "-c", self.cable, "-p", str(self.position), bitstream_file])
self.call(["xc3sprog", "-v", "-c", self.cable, "-p", str(self.position), bitstream_file])
def flash(self, address, data_file):
flash_proxy = self.find_flash_proxy()
subprocess.call(["xc3sprog", "-v", "-c", self.cable, "-p", str(self.position),
self.call(["xc3sprog", "-v", "-c", self.cable, "-p", str(self.position),
"-I"+flash_proxy, "{}:w:0x{:x}:BIN".format(data_file, address)])
# FpgaProg -----------------------------------------------------------------------------------------
@ -77,13 +77,13 @@ class FpgaProg(GenericProgrammer):
GenericProgrammer.__init__(self, flash_proxy_basename)
def load_bitstream(self, bitstream_file):
subprocess.call(["fpgaprog", "-v", "-f", bitstream_file])
self.call(["fpgaprog", "-v", "-f", bitstream_file])
def flash(self, address, data_file):
if address != 0:
raise ValueError("fpga prog needs a main bitstream at address 0")
flash_proxy = self.find_flash_proxy()
subprocess.call(["fpgaprog", "-v", "-sa", "-r", "-b", flash_proxy,
self.call(["fpgaprog", "-v", "-sa", "-r", "-b", flash_proxy,
"-f", data_file])
# iMPACT -------------------------------------------------------------------------------------------
@ -200,7 +200,7 @@ class Adept(GenericProgrammer):
self.index = index
def load_bitstream(self, bitstream_file):
subprocess.call([
self.call([
"djtgcfg",
"--verbose",
"prog", "-d", self.board,