diff options
| author | Martin Braun <martin.braun@ettus.com> | 2017-06-06 00:53:01 -0700 | 
|---|---|---|
| committer | Martin Braun <martin.braun@ettus.com> | 2017-12-22 15:03:59 -0800 | 
| commit | eb4a0cb6ebcff0bf3844df690a2d7653700211f2 (patch) | |
| tree | 8eefda94a40ab2d96449e4b8d34760829c3c5852 | |
| parent | 14f0e113d967c9a9098be8cfea7f333c4bf5373f (diff) | |
| download | uhd-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.cpp | 61 | ||||
| -rw-r--r-- | host/lib/usrp/mpmd/mpmd_mboard_impl.cpp | 4 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/periph_manager/base.py | 6 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/periph_manager/n310.py | 77 | 
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 + | 
