aboutsummaryrefslogtreecommitdiffstats
path: root/mpm/python/usrp_mpm
diff options
context:
space:
mode:
Diffstat (limited to 'mpm/python/usrp_mpm')
-rw-r--r--mpm/python/usrp_mpm/CMakeLists.txt2
-rw-r--r--mpm/python/usrp_mpm/__init__.py2
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/__init__.py28
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/base.py37
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/eiscat.py31
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/magnesium.py50
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/unknown.py32
-rw-r--r--mpm/python/usrp_mpm/helper.py3
-rw-r--r--mpm/python/usrp_mpm/periph_manager/__init__.py29
-rw-r--r--mpm/python/usrp_mpm/periph_manager/base.py75
-rw-r--r--mpm/python/usrp_mpm/periph_manager/n310.py46
-rw-r--r--mpm/python/usrp_mpm/periphs.py47
-rw-r--r--mpm/python/usrp_mpm/rpc_server.py5
-rw-r--r--mpm/python/usrp_mpm/types.py31
14 files changed, 376 insertions, 42 deletions
diff --git a/mpm/python/usrp_mpm/CMakeLists.txt b/mpm/python/usrp_mpm/CMakeLists.txt
index ad3ce41fd..f8f94bb5d 100644
--- a/mpm/python/usrp_mpm/CMakeLists.txt
+++ b/mpm/python/usrp_mpm/CMakeLists.txt
@@ -26,5 +26,7 @@ SET(USRP_MPM_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rpc_process.py
${CMAKE_CURRENT_SOURCE_DIR}/rpc_server.py
${CMAKE_CURRENT_SOURCE_DIR}/periphs.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/periph_manager
+ ${CMAKE_CURRENT_SOURCE_DIR}/dboard_manager
PARENT_SCOPE
)
diff --git a/mpm/python/usrp_mpm/__init__.py b/mpm/python/usrp_mpm/__init__.py
index dafb6940c..c349d3d77 100644
--- a/mpm/python/usrp_mpm/__init__.py
+++ b/mpm/python/usrp_mpm/__init__.py
@@ -21,3 +21,5 @@ MPM Module
from discovery import spawn_discovery_process
from rpc_process import spawn_rpc_process
import types
+import periph_manager
+import dboard_manager
diff --git a/mpm/python/usrp_mpm/dboard_manager/__init__.py b/mpm/python/usrp_mpm/dboard_manager/__init__.py
new file mode 100644
index 000000000..774f348d4
--- /dev/null
+++ b/mpm/python/usrp_mpm/dboard_manager/__init__.py
@@ -0,0 +1,28 @@
+#
+# Copyright 2017 Ettus Research (National Instruments)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+"""
+dboards module __init__.py
+"""
+from .. import libpyusrp_periphs as lib
+from magnesium import magnesium
+from eiscat import eiscat
+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
new file mode 100644
index 000000000..bf0a115cc
--- /dev/null
+++ b/mpm/python/usrp_mpm/dboard_manager/base.py
@@ -0,0 +1,37 @@
+#
+# Copyright 2017 Ettus Research (National Instruments)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+"""
+dboard base implementation module
+"""
+from . import lib
+import logging
+import struct
+
+log = logging.Logger("usrp_mpm.dboards")
+
+
+class dboard_manager(object):
+ """
+ Holds shared pointer to wrapped C++ implementation.
+ Sanitizes arguments before calling C++ functions.
+ Ties various constants to specific daughterboard class
+ """
+ def __init__(self, eeprom={}):
+ self._eeprom = eeprom
+
+ 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
new file mode 100644
index 000000000..f536d307b
--- /dev/null
+++ b/mpm/python/usrp_mpm/dboard_manager/eiscat.py
@@ -0,0 +1,31 @@
+#
+# Copyright 2017 Ettus Research (National Instruments)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+"""
+EISCAT rx board implementation module
+"""
+from base import dboard_manager
+from base import lib
+from base import log
+
+
+class eiscat(dboard_manager):
+ hw_pid = 3
+ special_eeprom_addrs = {"special0": "something"}
+
+ def __init__(self, spidevs=[], *args, **kwargs):
+ # Do own init
+ super(eiscat, self).__init__(*args, **kwargs)
diff --git a/mpm/python/usrp_mpm/dboard_manager/magnesium.py b/mpm/python/usrp_mpm/dboard_manager/magnesium.py
new file mode 100644
index 000000000..2201064ad
--- /dev/null
+++ b/mpm/python/usrp_mpm/dboard_manager/magnesium.py
@@ -0,0 +1,50 @@
+#
+# Copyright 2017 Ettus Research (National Instruments)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+"""
+magnesium dboard implementation module
+"""
+from base import dboard_manager
+from base import lib
+from base import log
+
+class magnesium(dboard_manager):
+ hw_pid = 2
+ special_eeprom_addrs = {"special0": "something"}
+ spi_chipselect = {"0": "lmk", "1": "mykonos", "2": "random"}
+ spidevs = {}
+
+ def __init__(self, spi_devices, eeprom_data, *args, **kwargs):
+ # eeprom_data is a tuple (head_dict, raw_data)
+ if len(spi_devices) != len(self.spi_chipselect):
+ log.error("Expected {0} spi devices, found {1} spi devices".format(len(spi_devices), len(self.spi_chipselect)))
+ exit(1)
+ for spi in spi_devices:
+ device = self.spi_chipselect.get(spi[-1], None)
+ if self.chipselect is None:
+ log.error("Unexpected chipselect {0}".format(spi[-1]))
+ exit(1)
+ setattr(self, device, spi)
+ super(magnesium, self).__init__(*args, **kwargs)
+
+ def init_device(self):
+ self._device = lib.db.magnesium(self.lmk, self.mykonos, self.random)
+
+ def read_eeprom_v1(self, data):
+ # magnesium eeprom contains
+ # nothing
+ return struct.unpack_from("x", data)
+
diff --git a/mpm/python/usrp_mpm/dboard_manager/unknown.py b/mpm/python/usrp_mpm/dboard_manager/unknown.py
new file mode 100644
index 000000000..f33bacc46
--- /dev/null
+++ b/mpm/python/usrp_mpm/dboard_manager/unknown.py
@@ -0,0 +1,32 @@
+#
+# Copyright 2017 Ettus Research (National Instruments)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+"""
+EISCAT rx board implementation module
+"""
+from base import dboard_manager
+from base import lib
+from base import log
+
+
+class unknown(dboard_manager):
+ hw_pid = 0
+ special_eeprom_addrs = {}
+
+ def __init__(self, spi_devices, eeprom_data):
+ self._eeprom = eeprom_data[0] # save eeprom header
+ # Do own init
+ super(unknown, self).__init__()
diff --git a/mpm/python/usrp_mpm/helper.py b/mpm/python/usrp_mpm/helper.py
new file mode 100644
index 000000000..29864124a
--- /dev/null
+++ b/mpm/python/usrp_mpm/helper.py
@@ -0,0 +1,3 @@
+
+
+class eeprom_helper:
diff --git a/mpm/python/usrp_mpm/periph_manager/__init__.py b/mpm/python/usrp_mpm/periph_manager/__init__.py
new file mode 100644
index 000000000..96eecf62e
--- /dev/null
+++ b/mpm/python/usrp_mpm/periph_manager/__init__.py
@@ -0,0 +1,29 @@
+#
+# Copyright 2017 Ettus Research (National Instruments)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+"""
+periph_manager __init__.py
+"""
+
+# This is where the import magic happens
+from .. import libpyusrp_periphs as lib
+from .. import dboard_manager
+from .. import types
+
+try:
+ from n310 import n310 as periph_manager
+except ImportError:
+ raise("Could not import n310")
diff --git a/mpm/python/usrp_mpm/periph_manager/base.py b/mpm/python/usrp_mpm/periph_manager/base.py
new file mode 100644
index 000000000..f19265a05
--- /dev/null
+++ b/mpm/python/usrp_mpm/periph_manager/base.py
@@ -0,0 +1,75 @@
+#
+# Copyright 2017 Ettus Research (National Instruments)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+"""
+Mboard implementation base class
+"""
+
+import re
+import os
+from . import lib
+from . import types
+from . import dboard_manager
+
+
+class periph_manager(object):
+ # stores discovered device information in dicts
+ dboards = {}
+ 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 = {}
+
+ def __init__(self):
+ # I know my EEPROM address, lets use it
+ helper = lib.udev_helper.udev_helper()
+ (self._eeprom_head, self._eeprom_rawdata) = types.eeprom().read_eeprom(helper.get_eeprom(self.mboard_eeprom_addr))
+ self._dboard_eeproms = {}
+ for dboard_slot, eeprom_addr in self.dboard_eeprom_addrs.iteritems():
+ spi_devices = []
+ # I know EEPROM adresses for my dboard slots
+ eeprom_data = types.eeprom().read(helper.get_eeprom(eeprom_addr))
+ # I know spidev masters on the dboard slots
+ hw_pid = eeprom_data.get("hw_pid", 0)
+ if hw_pid in dboards.hw_pids:
+ spi_devices = helper.get_spidev_nodes(self.dboard_spimaster_addrs.get(dboard_slot))
+ dboard = dboards.hw_pids.get(hw_pid, dboards.unknown)
+ self.dboards.update({dboard_slot: dboard(spi_devices, eeprom_data)})
+
+ def get_overlays(self):
+ self.mboard_overlays = []
+ for f in os.listdir("/lib/firmware/"):
+ if f.endswith(".dtbo"):
+ self.mboard_overlays.append(f.strip(".dtbo"))
+
+ def check_overlay(self):
+ for f in os.listdir("/sys/kernel/device-tree/overlays/"):
+ pass #do stuff
+
+ def get_serial(self):
+ return self._serial
+
+ def load_fpga_image(self, target=None):
+ pass
+
+ def init_device(self, *args, **kwargs):
+ # Load FPGA
+ # Init dboards
+ pass
+
diff --git a/mpm/python/usrp_mpm/periph_manager/n310.py b/mpm/python/usrp_mpm/periph_manager/n310.py
new file mode 100644
index 000000000..e270387f6
--- /dev/null
+++ b/mpm/python/usrp_mpm/periph_manager/n310.py
@@ -0,0 +1,46 @@
+#
+# Copyright 2017 Ettus Research (National Instruments)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+"""
+N310 implementation module
+"""
+from base import periph_manager
+import struct
+
+
+class n310(periph_manager):
+ hw_pids = "1"
+ mboard_eeprom_addr = "e0007000.spi:ec@0:i2c-tunnel"
+ dboard_eeprom_addrs = {"A": "something", "B": "else"}
+ dboard_spimaster_addrs = {"A": "something", "B": "else"}
+
+ def __init__(self, eeprom_device, *args, **kwargs):
+ # First initialize parent class - will populate self._eeprom_head and self._eeprom_rawdata
+ super(n310, self).__init__(*args, **kwargs)
+ data = self.read_eeprom_v1(self._eeprom_rawdata)
+ print(data)
+ # if header.get("dataversion", 0) == 1:
+
+ def read_eeprom_v1(self, data):
+ # data_version contains
+ # 6 bytes mac_addr0
+ # 2 bytes pad
+ # 6 bytes mac_addr1
+ # 2 bytes pad
+ # 6 bytes mac_addr2
+ # 2 bytes pad
+ # 8 bytes serial
+ return struct.unpack_from("6s 2x 6s 2x 6s 2x 8s", data)
diff --git a/mpm/python/usrp_mpm/periphs.py b/mpm/python/usrp_mpm/periphs.py
index 3a78f224b..8c00d8f50 100644
--- a/mpm/python/usrp_mpm/periphs.py
+++ b/mpm/python/usrp_mpm/periphs.py
@@ -19,52 +19,19 @@
"""
import libpyusrp_periphs as lib
-import re
import logging
-log = logging.Logger("usrp_mpm.periphs")
+import periph_manager
+import dboard_manager
+
+log = logging.Logger("usrp_mpm.periphs")
def init_periph_manager(mb_type=None, db_types={}, fpga=None):
- # Detect motherboard type if not already specified
- if mb_type is None:
- mb_files = lib.helper.find_mb_file()
- with open(mb_files, "r") as f:
- info = "".join(f.readlines())
- device_type = re.match("^.*USRP;([-\w])+;.*", info)
- if device_type is None:
- log.fatal("Could not determine device type from {}".format(info))
- exit(1)
- mb_type = device_type.group(1)
- # Check if we have an implementation for this motherboard type
- try:
- device_class = getattr(lib, mb_type)
- except AttributeError:
- log.fatal("Motherboard class implementation for {} device not found!".format(mb_type))
- exit(1)
+ pass
+ # Moved to periph_manager/base.py __init__
- # Detect daughterboard type if not already specified
- if not db_types:
- db_files = lib.helper.find_db_files()
- db_types = {}
- for db in db_files:
- with open(db, "r") as f:
- info = "".join(f.readlines())
- device_type = re.match("^.*SLOT;([\w]);DB;([-\w])+;.*", info)
- if device_type is None:
- log.fatal("Could not determine device type from: {}".format(info))
- exit(2)
- slot = device_type.group(1)
- db_type = device_type.group(2)
- db_types.update({slot: db_type})
- # Check if we have an implementation for the daughterboard types
- for db in db_types.values():
- try:
- getattr(lib.db, db)
- except AttributeError:
- log.fatal("Daughterboard class implementation for {} device not found!".format(db))
- exit(1)
- # Next steps
+ # Next steps implemented in periph_manager/derived class
#
# 1. Load FPGA image
# 2. Use motherboard and daughterboard types to load the FPGA image
diff --git a/mpm/python/usrp_mpm/rpc_server.py b/mpm/python/usrp_mpm/rpc_server.py
index b092abdf7..a5dda0826 100644
--- a/mpm/python/usrp_mpm/rpc_server.py
+++ b/mpm/python/usrp_mpm/rpc_server.py
@@ -61,7 +61,10 @@ class ClaimServer(RPCServer):
class MPMServer(RPCServer):
def __init__(self, state):
# Instead do self.mboard = periphs.init_periph_manager(args...)
- self.mboard = periphs.lib.n3xx.periph_manager("/dev/spidev1.0", "")
+ self.periph_manager = periphs.init_periph_manager()
+ # When we do init we can just add dboard/periph_manager methods with setattr(self, method)
+ # Maybe using partial
+ # To remove methods again we also have to remove them from self._methods dict (they're cached)
def get_clock_id(self, dboard):
dboard = getattr(self.mboard, "get_dboard_"+dboard)
diff --git a/mpm/python/usrp_mpm/types.py b/mpm/python/usrp_mpm/types.py
index bd7a874a8..31252e0b8 100644
--- a/mpm/python/usrp_mpm/types.py
+++ b/mpm/python/usrp_mpm/types.py
@@ -17,16 +17,18 @@
"""
MPM types
"""
+import ctypes
from multiprocessing import Value
from multiprocessing import Array
from multiprocessing import Lock
-import ctypes
+import struct
MPM_RPC_PORT = 49601
MPM_DISCOVERY_PORT = 49600
MPM_DISCOVERY_MESSAGE = "MPM-DISC"
+
class graceful_exit(Exception):
pass
@@ -36,3 +38,30 @@ class shared_state:
self.lock = Lock()
self.claim_status = Value(ctypes.c_bool, False, lock=self.lock) # lock
self.claim_token = Array(ctypes.c_char, 32, lock=self.lock) # String with max length of 32
+
+
+class eeprom(object):
+ # eeprom_header contains:
+ # 4 bytes magic
+ # 4 bytes CRC
+ # 2 bytes data_version
+ # 2 bytes hw_pid
+ # 2 bytes hw_rev
+ # 2 bytes pad
+ #
+ # 16 bytes in total
+ eeprom_header = struct.Struct("I I H H H 2x")
+
+ def read_eeprom(self, nvmem_path):
+ with open(nvmem_path, "rb") as f:
+ header = f.read(16)
+ data = f.read(240)
+ header = self.eeprom_header.unpack(header)
+ header = {
+ "magic": header[0],
+ "crc": header[1],
+ "data_version": header[2],
+ "hw_pid": header[3],
+ "hw_rev": header[4],
+ }
+ return (header, data)