aboutsummaryrefslogtreecommitdiffstats
path: root/mpm/python/usrp_mpm
diff options
context:
space:
mode:
authorBrent Stapleton <brent.stapleton@ettus.com>2017-12-14 14:39:49 -0800
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:05:58 -0800
commit02cbe06c307c35d38423bba29efbaac97ad22771 (patch)
tree1cb549eee9b1802796d2d17809a6a9d0c15e1550 /mpm/python/usrp_mpm
parentf7e88fbf03da8db2388aa3b16f9fa54c18bebfe8 (diff)
downloaduhd-02cbe06c307c35d38423bba29efbaac97ad22771.tar.gz
uhd-02cbe06c307c35d38423bba29efbaac97ad22771.tar.bz2
uhd-02cbe06c307c35d38423bba29efbaac97ad22771.zip
mpm: mg: Added magnesium_update_cpld.py
Reviewed-by: Martin Braun <martin.braun@ettus.com>
Diffstat (limited to 'mpm/python/usrp_mpm')
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/CMakeLists.txt3
-rwxr-xr-xmpm/python/usrp_mpm/dboard_manager/magnesium_update_cpld.py126
2 files changed, 128 insertions, 1 deletions
diff --git a/mpm/python/usrp_mpm/dboard_manager/CMakeLists.txt b/mpm/python/usrp_mpm/dboard_manager/CMakeLists.txt
index 4c5cbc761..99184fcd3 100644
--- a/mpm/python/usrp_mpm/dboard_manager/CMakeLists.txt
+++ b/mpm/python/usrp_mpm/dboard_manager/CMakeLists.txt
@@ -17,6 +17,7 @@ SET(USRP_MPM_DBMGR_FILES
${CMAKE_CURRENT_SOURCE_DIR}/lmk_eiscat.py
${CMAKE_CURRENT_SOURCE_DIR}/lmk_mg.py
${CMAKE_CURRENT_SOURCE_DIR}/unknown.py
- )
+ ${CMAKE_CURRENT_SOURCE_DIR}/magnesium_update_cpld.py
+)
LIST(APPEND USRP_MPM_FILES ${USRP_MPM_DBMGR_FILES})
SET(USRP_MPM_FILES ${USRP_MPM_FILES} PARENT_SCOPE)
diff --git a/mpm/python/usrp_mpm/dboard_manager/magnesium_update_cpld.py b/mpm/python/usrp_mpm/dboard_manager/magnesium_update_cpld.py
new file mode 100755
index 000000000..afb6fa635
--- /dev/null
+++ b/mpm/python/usrp_mpm/dboard_manager/magnesium_update_cpld.py
@@ -0,0 +1,126 @@
+#!/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 %d...", 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())