mirror of
https://github.com/saymrwulf/uhd.git
synced 2026-05-16 21:10:10 +00:00
126 lines
4.1 KiB
Python
Executable file
126 lines
4.1 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
#
|
|
# Copyright 2017 Ettus Research, a National Instruments Company
|
|
#
|
|
# SPDX-License-Identifier: GPL-3.0
|
|
#
|
|
"""
|
|
Update the CPLD image for the N310
|
|
"""
|
|
import os
|
|
import argparse
|
|
import subprocess
|
|
import pyudev
|
|
from usrp_mpm.mpmlog import get_logger
|
|
|
|
|
|
OPENOCD_DIR = "/usr/share/openocd/scripts"
|
|
REQUIRED_FILES = ["interface/sysfsgpio-ettus-magnesium-dba.cfg",
|
|
"interface/sysfsgpio-ettus-magnesium-dbb.cfg",
|
|
"cpld/altera-5m570z-cpld.cfg"]
|
|
OPENOCD_CMD = "init; svf -tap 5m570z.tap %s -progress -quiet;exit"
|
|
|
|
|
|
def check_openocd_files(logger=None):
|
|
"""
|
|
Check if all file required by OpenOCD exist
|
|
:param logger: logger object
|
|
"""
|
|
for ocd_file in REQUIRED_FILES:
|
|
if not os.path.exists(os.path.join(OPENOCD_DIR, ocd_file)):
|
|
if logger is not None:
|
|
logger.error("Missing file %s" % os.path.join(OPENOCD_DIR, ocd_file))
|
|
return False
|
|
return True
|
|
|
|
|
|
def check_fpga_state(which=0):
|
|
"""
|
|
Check if the FPGA is operational
|
|
:param which: the FPGA to check
|
|
"""
|
|
logger = get_logger('update_cpld')
|
|
try:
|
|
context = pyudev.Context()
|
|
fpga_mgrs = [dev for dev in context.list_devices(subsystem="fpga_manager")]
|
|
if fpga_mgrs:
|
|
state = fpga_mgrs[which].attributes.asstring('state')
|
|
logger.trace("FPGA State: {}".format(state))
|
|
return state == "operating"
|
|
except OSError as ex:
|
|
logger.error("Error while checking FPGA status: {}".format(ex))
|
|
return False
|
|
|
|
|
|
def do_update_cpld(filename, daughterboards, force=False):
|
|
"""
|
|
Carry out update process for the CPLD
|
|
:param filename: path (on device) to the new CPLD image
|
|
:param daughterboards: iterable containing dboard numbers to update
|
|
:param force: bool, ignore issues during update process
|
|
:return: True on success, False otherwise
|
|
"""
|
|
logger = get_logger('update_cpld')
|
|
logger.info("Programming CPLD of dboards {} with image {}".format(daughterboards, filename))
|
|
|
|
if not daughterboards:
|
|
logger.error("Invalid daughterboard selection.")
|
|
return False
|
|
|
|
if not os.path.exists(filename):
|
|
logger.error("CPLD image file {} not found".format(filename))
|
|
return False
|
|
|
|
# If we don't want to force this, check that the FPGA is operational
|
|
if not force and not check_fpga_state():
|
|
logger.error("CPLD lines are routed through fabric, FPGA is not programmed, giving up")
|
|
return False
|
|
|
|
if check_openocd_files(logger=logger):
|
|
logger.trace("Found required OpenOCD files.")
|
|
else:
|
|
# check_openocd_files logs errors
|
|
return False
|
|
|
|
for dboard in daughterboards:
|
|
logger.info("Updating daughterboard slot {}...".format(dboard))
|
|
cmd = ["openocd",
|
|
"-f", (REQUIRED_FILES[int(dboard, 10)]).strip(),
|
|
"-f", (REQUIRED_FILES[2]).strip(),
|
|
"-c", OPENOCD_CMD % filename]
|
|
logger.trace("Update CPLD CMD: {}".format(" ".join(cmd)))
|
|
subprocess.call(cmd)
|
|
|
|
logger.trace("Done programming CPLD...")
|
|
return True
|
|
|
|
|
|
def main():
|
|
"""
|
|
Go, go, go!
|
|
"""
|
|
# We need to make a logger if we're running stand-alone
|
|
from usrp_mpm.mpmlog import get_main_logger
|
|
log = get_main_logger()
|
|
|
|
# Do some setup
|
|
def parse_args():
|
|
"""Parse the command-line arguments"""
|
|
parser = argparse.ArgumentParser(description='Update the CPLD image on NI Magnesium')
|
|
parser.add_argument("--file", help="Filename of CPLD image",
|
|
default="/lib/firmware/ni/cpld-magnesium-revc.svf")
|
|
parser.add_argument("--dboards", help="Slot name to program", default="0,1")
|
|
parser.add_argument("--force", help="Ignore issues and move on",
|
|
default=False, action="store_true")
|
|
return parser.parse_args()
|
|
|
|
args = parse_args()
|
|
dboards = args.dboards.split(",")
|
|
if any([x not in ('0', '1') for x in dboards]):
|
|
log.error("Unsupported dboards requested: {}".format(dboards))
|
|
return False
|
|
else:
|
|
return do_update_cpld(args.file, dboards, args.force)
|
|
|
|
if __name__ == "__main__":
|
|
exit(not main())
|