aboutsummaryrefslogtreecommitdiffstats
path: root/mpm
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2017-05-10 12:07:14 -0700
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:03:53 -0800
commit4efea95324b66477f877d65c2d9c6ce188850174 (patch)
tree5bd27de40dab19895445e8be0ed52cc601b237c4 /mpm
parent2270a6b1a670bfa8387004bafdfcf2e74fc90477 (diff)
downloaduhd-4efea95324b66477f877d65c2d9c6ce188850174.tar.gz
uhd-4efea95324b66477f877d65c2d9c6ce188850174.tar.bz2
uhd-4efea95324b66477f877d65c2d9c6ce188850174.zip
mpm: Enabled mboard EEPROM readout
Diffstat (limited to 'mpm')
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/__init__.py5
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/base.py17
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/eiscat.py15
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/magnesium.py12
-rw-r--r--mpm/python/usrp_mpm/mpmtypes.py32
-rw-r--r--mpm/python/usrp_mpm/periph_manager/base.py348
-rw-r--r--mpm/python/usrp_mpm/periph_manager/n310.py23
-rw-r--r--mpm/python/usrp_mpm/periph_manager/udev.py9
-rw-r--r--mpm/python/usrp_mpm/rpc_server.py3
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)