aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2017-06-06 00:53:01 -0700
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:03:59 -0800
commiteb4a0cb6ebcff0bf3844df690a2d7653700211f2 (patch)
tree8eefda94a40ab2d96449e4b8d34760829c3c5852
parent14f0e113d967c9a9098be8cfea7f333c4bf5373f (diff)
downloaduhd-eb4a0cb6ebcff0bf3844df690a2d7653700211f2.tar.gz
uhd-eb4a0cb6ebcff0bf3844df690a2d7653700211f2.tar.bz2
uhd-eb4a0cb6ebcff0bf3844df690a2d7653700211f2.zip
mpmd/mpm/n310: Added clock and time source APIs
-rw-r--r--host/lib/usrp/mpmd/mpmd_impl.cpp61
-rw-r--r--host/lib/usrp/mpmd/mpmd_mboard_impl.cpp4
-rw-r--r--mpm/python/usrp_mpm/periph_manager/base.py6
-rw-r--r--mpm/python/usrp_mpm/periph_manager/n310.py77
4 files changed, 120 insertions, 28 deletions
diff --git a/host/lib/usrp/mpmd/mpmd_impl.cpp b/host/lib/usrp/mpmd/mpmd_impl.cpp
index 04d66a5c4..533b5dabf 100644
--- a/host/lib/usrp/mpmd/mpmd_impl.cpp
+++ b/host/lib/usrp/mpmd/mpmd_impl.cpp
@@ -37,7 +37,63 @@
using namespace uhd;
namespace {
+ /*************************************************************************
+ * Local constants
+ ************************************************************************/
const size_t MPMD_CROSSBAR_MAX_LADDR = 255;
+
+ /*************************************************************************
+ * Helper functions
+ ************************************************************************/
+ void init_property_tree(
+ uhd::property_tree::sptr tree,
+ fs_path mb_path,
+ mpmd_mboard_impl *mb
+ ) {
+ if (not tree->exists(fs_path("/name"))) {
+ tree->create<std::string>("/name")
+ .set(mb->device_info.get("name", "Unknown MPM device"))
+ ;
+ }
+
+ /*** Clocking *******************************************************/
+ tree->create<std::string>(mb_path / "clock_source/value")
+ .add_coerced_subscriber([mb](const std::string &clock_source){
+ mb->rpc->notify_with_token("set_clock_source", clock_source);
+ })
+ .set_publisher([mb](){
+ return mb->rpc->request_with_token<std::string>(
+ "get_clock_source"
+ );
+ })
+ ;
+ tree->create<std::vector<std::string>>(
+ mb_path / "clock_source/options")
+ .set_publisher([mb](){
+ return mb->rpc->request_with_token<std::vector<std::string>>(
+ "get_clock_sources"
+ );
+ })
+ ;
+ tree->create<std::string>(mb_path / "time_source/value")
+ .add_coerced_subscriber([mb](const std::string &time_source){
+ mb->rpc->notify_with_token("set_time_source", time_source);
+ })
+ .set_publisher([mb](){
+ return mb->rpc->request_with_token<std::string>(
+ "get_time_source"
+ );
+ })
+ ;
+ tree->create<std::vector<std::string>>(
+ mb_path / "time_source/options")
+ .set_publisher([mb](){
+ return mb->rpc->request_with_token<std::vector<std::string>>(
+ "get_time_sources"
+ );
+ })
+ ;
+ }
}
/*****************************************************************************
@@ -76,8 +132,9 @@ mpmd_impl::mpmd_impl(const device_addr_t& device_args)
setup_rfnoc_blocks(mb_i, mb_args[mb_i]);
}
- // TODO read this from the device info
- _tree->create<std::string>("/name").set("MPMD - Series device");
+ for (size_t mb_i = 0; mb_i < mb_args.size(); ++mb_i) {
+ init_property_tree(_tree, fs_path("/mboard") / mb_i, _mb[mb_i].get());
+ }
auto filtered_block_args = device_args; // TODO actually filter
setup_rpc_blocks(filtered_block_args);
diff --git a/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp b/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp
index 135d2973e..0584813df 100644
--- a/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp
+++ b/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp
@@ -22,6 +22,9 @@
#include <thread>
namespace {
+ /*************************************************************************
+ * Local constants
+ ************************************************************************/
//! Time between reclaims (ms)
const size_t MPMD_RECLAIM_INTERVAL_MS = 1000;
//! Default timeout value for the init() RPC call (ms)
@@ -30,6 +33,7 @@ namespace {
const size_t MPMD_DEFAULT_RPC_TIMEOUT = 2000;
const std::string MPMD_DEFAULT_SESSION_ID = "UHD";
+
}
using namespace uhd;
diff --git a/mpm/python/usrp_mpm/periph_manager/base.py b/mpm/python/usrp_mpm/periph_manager/base.py
index c0e64ade3..76fd610f1 100644
--- a/mpm/python/usrp_mpm/periph_manager/base.py
+++ b/mpm/python/usrp_mpm/periph_manager/base.py
@@ -124,6 +124,7 @@ class PeriphManagerBase(object):
# the network. Example: ['eth1', 'eth2']
chdr_interfaces = []
@staticmethod
+ # Yes, this is overridable too: List the required device tree overlays
def list_required_dt_overlays(eeprom_md, device_args):
"""
Lists device tree overlays that need to be applied before this class can
@@ -134,7 +135,7 @@ class PeriphManagerBase(object):
device_args -- Arbitrary dictionary of info, typically user-defined
"""
return []
-
+ ### End of overridables ###################################################
def __init__(self, args):
# First, make some checks to see if the child class is correctly set up:
@@ -332,7 +333,8 @@ class PeriphManagerBase(object):
self.log.trace("Resetting SID pool...")
self._available_endpoints = list(range(256))
- def safe_list_updateable_components(self):
+ @no_claim
+ def list_updateable_components(self):
"""
return list of updateable components
This method does not require a claim_token in the RPC
diff --git a/mpm/python/usrp_mpm/periph_manager/n310.py b/mpm/python/usrp_mpm/periph_manager/n310.py
index 537f43ee8..9531672ab 100644
--- a/mpm/python/usrp_mpm/periph_manager/n310.py
+++ b/mpm/python/usrp_mpm/periph_manager/n310.py
@@ -19,7 +19,7 @@ N310 implementation module
"""
from __future__ import print_function
-import time
+import os
from six import iteritems
from builtins import object
from .base import PeriphManagerBase
@@ -35,6 +35,7 @@ from .. import libpyusrp_periphs as lib
N3XX_DEFAULT_EXT_CLOCK_FREQ = 10e6
N3XX_DEFAULT_CLOCK_SOURCE = 'external'
+N3XX_DEFAULT_TIME_SOURCE = 'internal'
class TCA6424(object):
"""
@@ -130,8 +131,13 @@ class n310(PeriphManagerBase):
self.set_clock_source(
args.default_args.get('clock_source', N3XX_DEFAULT_CLOCK_SOURCE)
)
-
- # if header.get("dataversion", 0) == 1:
+ self._time_source = None # Gets set in set_time_source()
+ self.set_time_source(
+ args.default_args.get(
+ 'time_source',
+ N3XX_DEFAULT_TIME_SOURCE
+ )
+ )
self.log.info("mboard info: {}".format(self.mboard_info))
# Define some attributes so PyLint stays quiet
self._eth_dispatchers = None
@@ -183,31 +189,15 @@ class n310(PeriphManagerBase):
" Returns the currently selected clock source "
return self._clock_source
- def set_ext_clock_freq(self, freq):
- """
- Tell our USRP what the frequency of the external reference clock is.
-
- Will throw if it's not a valid value.
- """
- assert freq in (10e6, 20e6, 25e6)
- self._ext_clock_freq = freq
-
- def get_clock_freq(self):
- " Returns the currently active reference clock frequency"
- return {
- 'internal': 25e6,
- 'external': self._ext_clock_freq,
- 'gpsdo': 20e6,
- }[self._clock_source]
-
- def set_clock_source(self, clock_source):
+ def set_clock_source(self, *args):
"""
Enable given external reference clock.
Throws if clock_source is not a valid value.
"""
+ clock_source = args[0]
assert clock_source in self.get_clock_sources()
- self.log.trace("Setting clock sel to `{}'".format(clock_source))
+ self.log.trace("Setting clock source to `{}'".format(clock_source))
if clock_source == 'internal':
self._gpios.set("CLK-MAINREF-SEL0")
self._gpios.set("CLK-MAINREF-SEL1")
@@ -218,11 +208,50 @@ class n310(PeriphManagerBase):
self._gpios.reset("CLK-MAINREF-SEL0")
self._gpios.reset("CLK-MAINREF-SEL1")
self._clock_source = clock_source
- ref_clk_freq = self.get_clock_freq()
+ ref_clk_freq = self.get_ref_clock_freq()
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)
+ "Updating reference clock on dboard `{}' to {} MHz...".format(
+ slot, ref_clk_freq/1e6
+ )
)
dboard.update_ref_clock_freq(ref_clk_freq)
+ def set_ref_clock_freq(self, freq):
+ """
+ Tell our USRP what the frequency of the external reference clock is.
+
+ Will throw if it's not a valid value.
+ """
+ assert freq in (10e6, 20e6, 25e6)
+ self._ext_clock_freq = freq
+
+ def get_ref_clock_freq(self):
+ " Returns the currently active reference clock frequency"
+ return {
+ 'internal': 25e6,
+ 'external': self._ext_clock_freq,
+ 'gpsdo': 20e6,
+ }[self._clock_source]
+
+ def get_time_sources(self):
+ " Returns list of valid time sources "
+ return ['internal', 'external']
+
+ def get_time_source(self):
+ " Return the currently selected time source "
+ return self._time_source
+
+ def set_time_source(self, time_source):
+ " Set a time source "
+ assert time_source in self.get_time_sources()
+ self.log.trace("Setting time source to `{}'".format(time_source))
+ # FIXME use uio
+ if time_source == 'internal':
+ os.system('devmem2 0x4001000C w 0x1')
+ elif time_source == 'external':
+ os.system('devmem2 0x4001000C w 0x0')
+ else:
+ assert False
+