diff options
author | Martin Braun <martin.braun@ettus.com> | 2017-05-10 12:07:14 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2017-12-22 15:03:53 -0800 |
commit | 4efea95324b66477f877d65c2d9c6ce188850174 (patch) | |
tree | 5bd27de40dab19895445e8be0ed52cc601b237c4 /mpm/python/usrp_mpm | |
parent | 2270a6b1a670bfa8387004bafdfcf2e74fc90477 (diff) | |
download | uhd-4efea95324b66477f877d65c2d9c6ce188850174.tar.gz uhd-4efea95324b66477f877d65c2d9c6ce188850174.tar.bz2 uhd-4efea95324b66477f877d65c2d9c6ce188850174.zip |
mpm: Enabled mboard EEPROM readout
Diffstat (limited to 'mpm/python/usrp_mpm')
-rw-r--r-- | mpm/python/usrp_mpm/dboard_manager/__init__.py | 5 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/dboard_manager/base.py | 17 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/dboard_manager/eiscat.py | 15 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/dboard_manager/magnesium.py | 12 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/mpmtypes.py | 32 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/periph_manager/base.py | 348 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/periph_manager/n310.py | 23 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/periph_manager/udev.py | 9 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/rpc_server.py | 3 |
9 files changed, 360 insertions, 104 deletions
diff --git a/mpm/python/usrp_mpm/dboard_manager/__init__.py b/mpm/python/usrp_mpm/dboard_manager/__init__.py index 93de24695..a06591c81 100644 --- a/mpm/python/usrp_mpm/dboard_manager/__init__.py +++ b/mpm/python/usrp_mpm/dboard_manager/__init__.py @@ -18,12 +18,9 @@ dboards module __init__.py """ from .. import libpyusrp_periphs as lib +from .base import DboardManagerBase from .magnesium import Magnesium from .eiscat import EISCAT from .test import test from .unknown import unknown -HW_PIDS = { - EISCAT.hw_pid: EISCAT, - Magnesium.hw_pid: Magnesium, -} diff --git a/mpm/python/usrp_mpm/dboard_manager/base.py b/mpm/python/usrp_mpm/dboard_manager/base.py index 13284f6d3..985c20484 100644 --- a/mpm/python/usrp_mpm/dboard_manager/base.py +++ b/mpm/python/usrp_mpm/dboard_manager/base.py @@ -22,15 +22,20 @@ from ..mpmlog import get_logger class DboardManagerBase(object): """ - Holds shared pointer to wrapped C++ implementation. - Sanitizes arguments before calling C++ functions. - Ties various constants to specific daughterboard class + Base class for daughterboard controls """ - _eeprom = {} + ######################################################################### + # Overridables + # + # These values are meant to be overridden by the according subclasses + ######################################################################### + # Very important: A list of PIDs that apply to the current device. Must be + # list, even if there's only one entry. + pids = [] - def __init__(self, eeprom=None): - self._eeprom = eeprom or {} + def __init__(self, slot_idx, **kwargs): self.log = get_logger('dboardManager') + self.slot_idx = slot_idx def get_serial(self): return self._eeprom.get("serial", "") diff --git a/mpm/python/usrp_mpm/dboard_manager/eiscat.py b/mpm/python/usrp_mpm/dboard_manager/eiscat.py index d293bb706..330e6a605 100644 --- a/mpm/python/usrp_mpm/dboard_manager/eiscat.py +++ b/mpm/python/usrp_mpm/dboard_manager/eiscat.py @@ -338,21 +338,26 @@ class EISCAT(DboardManagerBase): """ EISCAT Daughterboard """ - hw_pid = 3 - special_eeprom_addrs = {"special0": "something"} + ######################################################################### + # Overridables + # + # See DboardManagerBase for documentation on these fields + ######################################################################### + pids = [0x180] + spi_chipselect = { "lmk": 0, "adc0": 1, "adc1": 2 } - def __init__(self, slot_idx, spi_devices, *args, **kwargs): - super(EISCAT, self).__init__(*args, **kwargs) + def __init__(self, slot_idx, **kwargs): + super(EISCAT, self).__init__(slot_idx, **kwargs) self.log = get_logger("EISCAT") - self.slot_idx = slot_idx self.log.trace("Initializing EISCAT daughterboard, slot index {}".format(self.slot_idx)) self.initialized = False self.ref_clock_freq = 10e6 + spi_devices = kwargs['spi_nodes'] if len(spi_devices) < len(self.spi_chipselect): self.log.error("Expected {0} spi devices, found {1} spi devices".format( len(self.spi_chipselect), len(spi_devices), diff --git a/mpm/python/usrp_mpm/dboard_manager/magnesium.py b/mpm/python/usrp_mpm/dboard_manager/magnesium.py index de871abf8..612705ce4 100644 --- a/mpm/python/usrp_mpm/dboard_manager/magnesium.py +++ b/mpm/python/usrp_mpm/dboard_manager/magnesium.py @@ -50,14 +50,20 @@ class Magnesium(DboardManagerBase): """ Holds all dboard specific information and methods of the magnesium dboard """ - hw_pid = 2 - special_eeprom_addrs = {"special0": "something"} + ######################################################################### + # Overridables + # + # See DboardManagerBase for documentation on these fields + ######################################################################### + pids = [0x150] + # Maps the chipselects to the corresponding devices: spi_chipselect = {"lmk": 0, "mykonos": 1} - def __init__(self, slot_idx, spi_devices, eeprom_data, *args, **kwargs): + def __init__(self, slot_idx, **kwargs): super(Magnesium, self).__init__(*args, **kwargs) self.log = get_logger("Magnesium") + spi_devices = kwargs['spi_nodes'] # eeprom_data is a tuple (head_dict, raw_data) if len(spi_devices) != len(self.spi_chipselect): self.log.error("Expected {0} spi devices, found {1} spi devices".format( diff --git a/mpm/python/usrp_mpm/mpmtypes.py b/mpm/python/usrp_mpm/mpmtypes.py index 1fbddb934..b1db3efb9 100644 --- a/mpm/python/usrp_mpm/mpmtypes.py +++ b/mpm/python/usrp_mpm/mpmtypes.py @@ -68,35 +68,3 @@ class SID(object): return (self.src_addr << 24) | (self.src_ep << 16) | (self.dst_addr << 8) | self.dst_ep -class EEPROM(object): - """ - Reads out common properties and rawdata out of a nvmem path - """ - # eeprom_header contains: - # 4 bytes magic - # 4 bytes version - # 4x4 bytes mcu_flags -> throw them away - # 2 bytes hw_pid - # 2 bytes hw_rev - # - # 28 bytes in total - eeprom_header = struct.Struct("!I I 16x H H") - - def read_eeprom(self, nvmem_path): - """ - Read the EEPROM located at nvmem_path and return a tuple (header, data) - Header is already parsed in the common header fields - Data contains the full eeprom data structure - """ - with open(nvmem_path, "rb") as nvmem_file: - data = nvmem_file.read(256) - _header = self.eeprom_header.unpack_from(data) - print hex(_header[0]), hex(_header[1]), hex(_header[2]), hex(_header[3]) - header = { - "magic": _header[0], - "version": _header[1], - "hw_pid": _header[2], - "hw_rev": _header[3], - } - print header - return (header, data) diff --git a/mpm/python/usrp_mpm/periph_manager/base.py b/mpm/python/usrp_mpm/periph_manager/base.py index 8d2d5773a..e46df44c2 100644 --- a/mpm/python/usrp_mpm/periph_manager/base.py +++ b/mpm/python/usrp_mpm/periph_manager/base.py @@ -19,13 +19,148 @@ Mboard implementation base class """ import os -from six import iteritems +import struct +from six import iteritems, itervalues from ..mpmlog import get_logger -from ..mpmtypes import EEPROM -from .. import dboard_manager -from .udev import get_eeprom_path +from .udev import get_eeprom_paths from .udev import get_spidev_nodes +EEPROM_DEFAULT_HEADER = struct.Struct("!I I") + +class MboardEEPROM(object): + """ + Given a nvmem path, read out EEPROM values from the motherboard's EEPROM. + The format of data in the EEPROM must follow the following standard: + + - 4 bytes magic. This will always be the same value; checking this value is + a sanity check for if the read was successful. + - 4 bytes version. This is the version of the EEPROM format. + + The following bytes are version-dependent: + + Version 1: + + - 4x4 bytes mcu_flags -> throw them away + - 2 bytes hw_pid + - 2 bytes hw_rev (starting at 0) + - 8 bytes serial number (zero-terminated string of 7 characters) + - 6 bytes MAC address for eth0 + - 2 bytes padding + - 6 bytes MAC address for eth1 + - 2 bytes padding + - 6 bytes MAC address for eth2 + - 2 bytes padding + - 4 bytes CRC + + MAC addresses are ignored here; they are read elsewhere. If we really need + to know the MAC address of an interface, we can fish it out the raw data, + or ask the system. + """ + # Create one of these for every version of the EEPROM format: + eeprom_header_format = ( + None, # For laziness, we start at version 1 and thus index 0 stays empty + "!I I 16x H H 7s 25x I", # Version 1 + ) + eeprom_header_keys = ( + None, # For laziness, we start at version 1 and thus index 0 stays empty + ('magic', 'eeprom_version', 'pid', 'rev', 'serial', 'CRC'), # Version 1 + ) + +class DboardEEPROM(object): + """ + Given a nvmem path, read out EEPROM values from the daughterboard's EEPROM. + The format of data in the EEPROM must follow the following standard: + + - 4 bytes magic. This will always be the same value; checking this value is + a sanity check for if the read was successful. + - 4 bytes version. This is the version of the EEPROM format. + + The following bytes are version-dependent: + + Version 1: + + - 2 bytes hw_pid + - 2 bytes hw_rev (starting at 0) + - 8 bytes serial number (zero-terminated string of 7 characters) + - 4 bytes CRC + + MAC addresses are ignored here; they are read elsewhere. If we really need + to know the MAC address of an interface, we can fish it out the raw data, + or ask the system. + """ + # Create one of these for every version of the EEPROM format: + eeprom_header_format = ( + None, # For laziness, we start at version 1 and thus index 0 stays empty + "!I I H H 7s 1x I", # Version 1 + ) + eeprom_header_keys = ( + None, # For laziness, we start at version 1 and thus index 0 stays empty + ('magic', 'eeprom_version', 'pid', 'rev', 'serial', 'CRC'), # Version 1 + ) + + +def read_eeprom( + nvmem_path, + eeprom_header_format, + eeprom_header_keys, + expected_magic, + max_size=None +): + """ + Read the EEPROM located at nvmem_path and return a tuple (header, data) + Header is already parsed in the common header fields + Data contains the full eeprom data structure + + nvmem_path -- Path to readable file (typically something in sysfs) + eeprom_header_format -- List of header formats, by version + eeprom_header_keys -- List of keys for the entries in the EEPROM + expected_magic -- The magic value that is expected + max_size -- Max number of bytes to be read. If omitted, will read the full file. + """ + assert len(eeprom_header_format) == len(eeprom_header_keys) + def _parse_eeprom_data( + data, + version, + ): + """ + Parses the raw 'data' according to the version. + Returns a dictionary. + """ + eeprom_parser = struct.Struct(eeprom_header_format[version]) + eeprom_keys = eeprom_header_keys[version] + parsed_data = eeprom_parser.unpack_from(data) + return dict(zip(eeprom_keys, parsed_data)) + # Dawaj, dawaj + max_size = max_size or -1 + with open(nvmem_path, "rb") as nvmem_file: + data = nvmem_file.read(max_size) + eeprom_magic, eeprom_version = EEPROM_DEFAULT_HEADER.unpack_from(data) + if eeprom_magic != expected_magic: + raise RuntimeError("Received incorrect EEPROM magic. " \ + "Read: {:08X} Expected: {:08X}".format( + eeprom_magic, expected_magic + )) + if eeprom_version >= len(eeprom_header_format): + raise RuntimeError("Unexpected EEPROM version: `{}'".format(eeprom_version)) + return (_parse_eeprom_data(data, eeprom_version), data) + + +def get_dboard_class_from_pid(pid): + """ + Given a PID, return a dboard class initializer callable. + """ + from .. import dboard_manager + for member in itervalues(dboard_manager.__dict__): + try: + if issubclass(member, dboard_manager.DboardManagerBase) and \ + hasattr(member, 'pids') and \ + pid in member.pids: + return member + except (TypeError, AttributeError): + continue + return None + + class PeriphManagerBase(object): """" Base class for all motherboards. Common function and API calls should @@ -34,52 +169,187 @@ class PeriphManagerBase(object): """ # stores discovered device information in dicts claimed = False - dboards = {} - mboard_info = {"type": "unknown"} mboard_if_addrs = {} mboard_overlays = {} # this information has to be provided by # the specific periph_manager implementation - mboard_eeprom_addr = "" - dboard_eeprom_addrs = {} dboard_spimaster_addrs = {} updateable_components = [] sid_endpoints = {} available_endpoints = range(256) + ######################################################################### + # Overridables + # + # These values are meant to be overridden by the according subclasses + ######################################################################### + # Very important: A list of PIDs that apply to the current device. Must be + # list, even if there's only one entry. + pids = [] + # Address of the motherboard EEPROM. This could be something like + # "e0005000.i2c". This value will be passed to get_eeprom_paths() tos + # determine a full path to an EEPROM device. + # If empty, this will be ignored and no EEPROM info for the device is read + # out. + mboard_eeprom_addr = "" + # The EEPROM code checks for this word to see if the readout was valid. + # Typically, devices should not override this unless their EEPROM follows a + # different standard. + mboard_eeprom_magic = 0xF008AD10 + # If this value is not set, the code will try and read out the entire EEPROM + # content as a binary blob. Use this to limit the number of bytes actually + # read. It's usually safe to not override this, as EEPROMs typically aren't + # that big. + mboard_eeprom_max_len = None + # This is the *default* mboard info. The keys from this dict will be copied + # into the current device info before it actually gets initialized. This + # means that keys from this dict could be overwritten during the + # initialization process. + mboard_info = {"type": "unknown"} + # This is a sanity check value to see if the correct number of + # daughterboards are detected. If somewhere along the line more than + # max_num_dboards dboards are found, an error or warning is raised, + # depending on the severity of the issue. If fewer dboards are found, + # that's generally considered OK. + max_num_dboards = 2 + # Address of the daughterboard EEPROMs. This could be something like + # "e0004000.i2c". This value will be passed to get_eeprom_paths() to + # determine a full path to an EEPROM device. + # If empty, this will be ignored and no EEPROM info for the device is read + # out. + # If this is a list of EEPROMs, paths will be concatenated. + dboard_eeprom_addr = None + # The EEPROM code checks for this word to see if the readout was valid. + # Typically, devices should not override this unless their EEPROM follows a + # different standard. + dboard_eeprom_magic = 0xF008AD11 + # If this value is not set, the code will try and read out the entire EEPROM + # content as a binary blob. Use this to limit the number of bytes actually + # read. It's usually safe to not override this, as EEPROMs typically aren't + # that big. + dboard_eeprom_max_len = None + # If the dboard requires spidev access, the following attribute is a list + # of SPI master addrs (typically something like 'e0006000.spi'). You + # usually want the length of this list to be as long as the number of + # dboards, but if it's shorter, it simply won't instantiate list SPI nodes + # for those dboards. + dboard_spimaster_addrs = [] + + def __init__(self): + # First, make some checks to see if the child class is correctly set up: + assert len(self.pids) > 0 + assert self.mboard_eeprom_magic is not None + # Set up logging self.log = get_logger('PeriphManager') - # I know my EEPROM address, lets use it - self.overlays = "" - # (self._eeprom_head, self._eeprom_rawdata) = EEPROM().read_eeprom( - # get_eeprom_path(self.mboard_eeprom_addr)) - # print self._eeprom_head - self._dboard_eeproms = {} - self.log.debug("Initializing dboards") - # for dboard_slot, eeprom_addr in self.dboard_eeprom_addrs.iteritems(): - # self.log.debug("Adding dboard for slot {0}".format(dboard_slot)) - # spi_devices = [] - # # I know EEPROM adresses for my dboard slots - # eeprom_data = EEPROM().read_eeprom(get_eeprom_path(eeprom_addr)) - # # I know spidev masters on the dboard slots - # hw_pid = eeprom_data[0].get("hw_pid", 0) - # if hw_pid in dboard_manager.HW_PIDS: - # spi_devices = get_spidev_nodes(self.dboard_spimaster_addrs.get(dboard_slot)) - # dboard = dboard_manager.HW_PIDS.get(hw_pid, dboard_manager.unknown) - # self.dboards.update({dboard_slot: dboard(spi_devices, eeprom_data)}) - dboard_slot = 0 - self.log.debug("Adding dboard for slot {0}".format(dboard_slot)) - spi_devices = [] - # I know EEPROM adresses for my dboard slots - # eeprom_data = EEPROM().read_eeprom(get_eeprom_path(eeprom_addr)) - eeprom_data = None - # I know spidev masters on the dboard slots - hw_pid = 3 - if hw_pid in dboard_manager.HW_PIDS: - spi_devices = sorted(get_spidev_nodes("e0006000.spi")) - self.log.debug("Found spidev nodes: {0}".format(spi_devices)) - dboard = dboard_manager.HW_PIDS.get(hw_pid, dboard_manager.unknown) - self.dboards.update({dboard_slot: dboard(0, spi_devices, eeprom_data)}) + self._init_mboard_with_eeprom() + self._init_dboards() + + + def _init_mboard_with_eeprom(self): + """ + Starts the device initialization. Typically requires reading from an + EEPROM. + """ + if len(self.mboard_eeprom_addr): + self.log.trace("Reading EEPROM from address `{}'...".format(self.mboard_eeprom_addr)) + (self._eeprom_head, self._eeprom_rawdata) = read_eeprom( + get_eeprom_paths(self.mboard_eeprom_addr)[0], + MboardEEPROM.eeprom_header_format, + MboardEEPROM.eeprom_header_keys, + self.mboard_eeprom_magic, + self.mboard_eeprom_max_len, + ) + self.log.trace("Found EEPROM metadata: `{}'".format(str(self._eeprom_head))) + self.log.trace("Read {} bytes of EEPROM data.".format(len(self._eeprom_rawdata))) + for key in ('pid', 'serial', 'rev'): + self.mboard_info[key] = self._eeprom_head.get(key, '') + if self._eeprom_head.has_key('pid') and not self._eeprom_head['pid'] in self.pids: + self.log.error("Found invalid PID in EEPROM: 0x{:04X}. Valid PIDs are: {}".format( + self._eeprom_head['pid'], + ", ".join(["0x{:04X}".format(x) for x in self.pids]), + )) + raise RuntimeError("Invalid PID found in EEPROM.") + else: + self.log.trace("No EEPROM address to read from.") + self._eeprom_head = {} + self._eeprom_rawdata = '' + self.log.info("Device serial number: {}".format(self.mboard_info.get('serial', 'n/a'))) + + + def _init_dboards(self, override_dboard_pids=None): + """ + Initialize all the daughterboards + """ + override_dboard_pids = override_dboard_pids or [] + dboard_eeprom_addrs = self.dboard_eeprom_addr \ + if isinstance(self.dboard_eeprom_addr, list) \ + else [self.dboard_eeprom_addr] + dboard_eeprom_paths = [] + self.log.trace("Identifying dboard EEPROM paths from addrs `{}'...".format(",".join(dboard_eeprom_addrs))) + for dboard_eeprom_addr in dboard_eeprom_addrs: + self.log.trace("Resolving {}...".format(dboard_eeprom_addr)) + dboard_eeprom_paths += get_eeprom_paths(dboard_eeprom_addr) + self.log.trace("Found dboard EEPROM paths: {}".format(",".join(dboard_eeprom_paths))) + if len(dboard_eeprom_paths) > self.max_num_dboards: + self.log.warning("Found more EEPROM paths than daughterboards. Ignoring some of them.") + dboard_eeprom_paths = dboard_eeprom_paths[:self.max_num_dboards] + num_dboards = len(dboard_eeprom_paths) + self.dboards = [] + for dboard_idx, dboard_eeprom_path in enumerate(dboard_eeprom_paths): + self.log.debug("Initializing dboard {}...".format(dboard_idx)) + dboard_eeprom_md, dboard_eeprom_rawdata = read_eeprom( + dboard_eeprom_path, + DboardEEPROM.eeprom_header_format, + DboardEEPROM.eeprom_header_keys, + self.dboard_eeprom_magic, + self.dboard_eeprom_max_len, + ) + self.log.trace("Found dboard EEPROM metadata: `{}'".format(str(dboard_eeprom_md))) + self.log.trace("Read {} bytes of dboard EEPROM data.".format(len(dboard_eeprom_rawdata))) + if len(override_dboard_pids) > dboard_idx: + db_pid = override_dboard_pids[dboard_idx] + self.log.warning("Overriding dboard PID for dboard {} with 0x{:04X}.".format(dboard_idx, db_pid)) + else: + db_pid = dboard_eeprom_md.get('pid') + if db_pid is None: + self.log.warning("No dboard PID found!") + else: + self.log.debug("Found dboard PID in EEPROM: 0x{:04X}".format(db_pid)) + if len(self.dboard_spimaster_addrs) > dboard_idx: + spi_nodes = sorted(get_spidev_nodes(self.dboard_spimaster_addrs[dboard_idx])) + self.log.debug("Found spidev nodes: {0}".format(spi_nodes)) + else: + spi_nodes = [] + self.log.warning("No SPI nodes for dboard {}.".format(dboard_idx)) + dboard_info = { + 'eeprom_md': dboard_eeprom_md, + 'eeprom_rawdata': dboard_eeprom_rawdata, + 'pid': db_pid, + 'spi_nodes': spi_nodes, + } + # This will actually instantiate the dboard class: + db_class = get_dboard_class_from_pid(db_pid) + if db_class is None: + self.log.warning("Could not identify daughterboard class for PID {:04X}!".format(pid)) + continue + self.dboards.append(db_class(dboard_idx, **dboard_info)) + self.log.info("Found {} daughterboard(s).".format(len(self.dboards))) + + # self.overlays = "" + # self._dboard_eeproms = {} + # self.log.debug("Initializing dboards") + # # for dboard_slot, eeprom_addr in self.dboard_eeprom_addrs.iteritems(): + # # self.log.debug("Adding dboard for slot {0}".format(dboard_slot)) + # # spi_devices = [] + # # # I know EEPROM adresses for my dboard slots + # # eeprom_data = EEPROM().read_eeprom(get_eeprom_paths(eeprom_addr)) + # # # I know spidev masters on the dboard slots + # # hw_pid = eeprom_data[0].get("hw_pid", 0) + # # if hw_pid in dboard_manager.HW_PIDS: + # # spi_devices = get_spidev_nodes(self.dboard_spimaster_addrs.get(dboard_slot)) + # # dboard = dboard_manager.HW_PIDS.get(hw_pid, dboard_manager.unknown) + # # self.dboards.update({dboard_slot: dboard(spi_devices, eeprom_data)}) def safe_list_updateable_components(self): """ diff --git a/mpm/python/usrp_mpm/periph_manager/n310.py b/mpm/python/usrp_mpm/periph_manager/n310.py index 97157ad1b..4d36700a3 100644 --- a/mpm/python/usrp_mpm/periph_manager/n310.py +++ b/mpm/python/usrp_mpm/periph_manager/n310.py @@ -94,15 +94,24 @@ class n310(PeriphManagerBase): """ Holds N310 specific attributes and methods """ - hw_pids = "1" - mboard_type = "n310" - mboard_eeprom_addr = "e0005000.i2c" - # dboard_eeprom_addrs = {"A": "something", "B": "else"} - # dboard_eeprom_addrs = {"A": "e0004000.i2c",} # dboard_spimaster_addrs = {"A": "something", "B": "else"} dboard_spimaster_addrs = {"A": "e0006000.spi",} interfaces = {} + ######################################################################### + # Overridables + # + # See PeriphManagerBase for documentation on these fields + ######################################################################### + pids = [0x4242,] + mboard_eeprom_addr = "e0005000.i2c" + mboard_eeprom_max_len = 256 + mboard_info = {"type": "n3xx"} + dboard_eeprom_addr = "e0004000.i2c" + dboard_eeprom_max_len = 64 + dboard_spimaster_addrs = ["e0006000.spi",] + + def __init__(self, *args, **kwargs): # First initialize parent class - will populate self._eeprom_head and self._eeprom_rawdata super(n310, self).__init__(*args, **kwargs) @@ -139,7 +148,7 @@ class n310(PeriphManagerBase): # Initialize our daughterboards: self.log.debug("Initializing dboards...") - for k, dboard in iteritems(self.dboards): + for dboard in self.dboards: dboard.init_device() def _read_eeprom_v1(self, data): @@ -251,7 +260,7 @@ class n310(PeriphManagerBase): self._gpios.reset("CLK-MAINREF-SEL1") self._clock_source = clock_source ref_clk_freq = self.get_clock_freq() - for slot, dboard in iteritems(self.dboards): + for slot, dboard in enumerate(self.dboards): if hasattr(dboard, 'update_ref_clock_freq'): self.log.trace( "Updating reference clock on dboard `{}' to {} MHz...".format(slot, ref_clk_freq/1e6) diff --git a/mpm/python/usrp_mpm/periph_manager/udev.py b/mpm/python/usrp_mpm/periph_manager/udev.py index 9d64b1b64..c0b85b032 100644 --- a/mpm/python/usrp_mpm/periph_manager/udev.py +++ b/mpm/python/usrp_mpm/periph_manager/udev.py @@ -19,18 +19,15 @@ import pyudev import os from ..mpmlog import get_logger -def get_eeprom_path(address): +def get_eeprom_paths(address): """ - Return EEPROM device path for a given I2C address + Return EEPROM device paths for a given I2C address """ context = pyudev.Context() parent = pyudev.Device.from_name(context, "platform", address) paths = [device.device_node if device.device_node is not None else device.sys_path for device in context.list_devices(parent=parent, subsystem="nvmem")] - if len(paths) != 1: - raise Exception("{0} paths to EEPROM found!".format(len(paths))) - return paths[0] + "/nvmem" - + return [os.path.join(x.encode('ascii'), 'nvmem') for x in paths] def get_spidev_nodes(spi_master): """ diff --git a/mpm/python/usrp_mpm/rpc_server.py b/mpm/python/usrp_mpm/rpc_server.py index ab9d017e7..6607aa082 100644 --- a/mpm/python/usrp_mpm/rpc_server.py +++ b/mpm/python/usrp_mpm/rpc_server.py @@ -27,7 +27,6 @@ from gevent import monkey monkey.patch_all() from mprpc import RPCServer from random import choice -from six import iteritems from string import ascii_letters, digits from multiprocessing import Process from .mpmlog import get_main_logger @@ -51,7 +50,7 @@ class MPMServer(RPCServer): # add public mboard methods without namespace self._update_component_commands(mgr, '', '_mb_methods') # add public dboard methods in `db_<slot>_` namespace - for db_slot, dboard in iteritems(mgr.dboards): + for db_slot, dboard in enumerate(mgr.dboards): self._update_component_commands(dboard, 'db_' + str(db_slot) + '_', '_db_methods') super(MPMServer, self).__init__(*args, **kwargs) |