commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 10/37: uhd: Added checks for lock sensors.


From: git
Subject: [Commit-gnuradio] [gnuradio] 10/37: uhd: Added checks for lock sensors.
Date: Thu, 17 Jul 2014 20:23:40 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

trondeau pushed a commit to branch master
in repository gnuradio.

commit 12523cdb3218be85565c3c3bcb49d113e6bac518
Author: Martin Braun <address@hidden>
Date:   Mon Jul 7 18:06:20 2014 +0200

    uhd: Added checks for lock sensors.
    
    When operating with an external ref, in MIMO mode or with a GPSDO,
    the constructor now waits until the lock sensors report succesful
    locking.
    If this fails, a warning is displayed using the logger interface,
    to keep backward compatibility.
---
 gr-uhd/lib/usrp_common.h       | 50 +++++++++++++++++++++++++++++++++++++++++-
 gr-uhd/lib/usrp_sink_impl.cc   | 42 +++++++++++++++++++++++++++++++++++
 gr-uhd/lib/usrp_sink_impl.h    |  4 ++++
 gr-uhd/lib/usrp_source_impl.cc | 41 ++++++++++++++++++++++++++++++++++
 gr-uhd/lib/usrp_source_impl.h  |  3 +++
 5 files changed, 139 insertions(+), 1 deletion(-)

diff --git a/gr-uhd/lib/usrp_common.h b/gr-uhd/lib/usrp_common.h
index 732bcef..29caa58 100644
--- a/gr-uhd/lib/usrp_common.h
+++ b/gr-uhd/lib/usrp_common.h
@@ -26,12 +26,17 @@
 #include <pmt/pmt.h>
 #include <boost/dynamic_bitset.hpp>
 #include <boost/make_shared.hpp>
+#include <boost/bind.hpp>
+#include <boost/thread.hpp>
 #include <uhd/usrp/multi_usrp.hpp>
 #include <uhd/convert.hpp>
 #include <iostream>
 
 namespace gr {
   namespace uhd {
+    typedef boost::function< ::uhd::sensor_value_t (const std::string&)> 
get_sensor_fn_t;
+
+    static const double LOCK_TIMEOUT = 1.5; // s
 
     //! Helper function for msg_handler_command:
     // - Extracts command and the command value from the command PMT
@@ -105,8 +110,12 @@ namespace gr {
       return vals_updated;
     }
 
+
     /*! \brief Components common to USRP sink and source.
      *
+     * \param device_addr Device address + options
+     * \param stream_args Stream args (cpu format, otw format...)
+     * \param ts_tag_name If this block produces or consumes stream tags, 
enter the corresponding tag name here
      */
     class usrp_common_impl
     {
@@ -130,8 +139,47 @@ namespace gr {
 
       ~usrp_common_impl() {};
 
-
     protected:
+      /*! \brief Wait until a timeout or a sensor returns 'locked'.
+       *
+       * If a given sensor is not found, this still returns 'true', so we 
don't throw
+       * errors or warnings if a sensor wasn't implemented.
+       */
+      bool _wait_for_locked_sensor(
+          std::vector<std::string> sensor_names,
+          const std::string &sensor_name,
+          get_sensor_fn_t get_sensor_fn
+      ){
+        if (std::find(sensor_names.begin(), sensor_names.end(), sensor_name) 
== sensor_names.end())
+          return true;
+
+        boost::system_time start = boost::get_system_time();
+        boost::system_time first_lock_time;
+
+        while (true) {
+          if ((not first_lock_time.is_not_a_date_time()) and
+              (boost::get_system_time() > (first_lock_time + 
boost::posix_time::seconds(LOCK_TIMEOUT)))) {
+            break;
+          }
+
+          if (get_sensor_fn(sensor_name).to_bool()) {
+            if (first_lock_time.is_not_a_date_time())
+              first_lock_time = boost::get_system_time();
+          }
+          else {
+            first_lock_time = boost::system_time(); //reset to 'not a date 
time'
+
+            if (boost::get_system_time() > (start + 
boost::posix_time::seconds(LOCK_TIMEOUT))){
+              return false;
+            }
+          }
+
+          boost::this_thread::sleep(boost::posix_time::milliseconds(100));
+        }
+
+        return true;
+      }
+
       //! Shared pointer to the underlying multi_usrp object
       ::uhd::usrp::multi_usrp::sptr _dev;
       const ::uhd::stream_args_t _stream_args;
diff --git a/gr-uhd/lib/usrp_sink_impl.cc b/gr-uhd/lib/usrp_sink_impl.cc
index ad96bcb..cdbe7b5 100644
--- a/gr-uhd/lib/usrp_sink_impl.cc
+++ b/gr-uhd/lib/usrp_sink_impl.cc
@@ -80,8 +80,50 @@ namespace gr {
           pmt::mp("command"),
           boost::bind(&usrp_sink_impl::msg_handler_command, this, _1)
       );
+
+      _check_sensors_locked();
+    }
+
+    bool usrp_sink_impl::_check_sensors_locked()
+    {
+      bool clocks_locked = true;
+
+      // 1) Check ref lock for all mboards
+      for (size_t mboard_index = 0; mboard_index < _dev->get_num_mboards(); 
mboard_index++) {
+        std::string sensor_name = "ref_locked";
+        if (_dev->get_clock_source(mboard_index) == "internal") {
+          continue;
+        }
+        else if (_dev->get_clock_source(mboard_index) == "mimo") {
+          sensor_name = "mimo_locked";
+        }
+        if (not _wait_for_locked_sensor(
+                get_mboard_sensor_names(mboard_index),
+                sensor_name,
+                boost::bind(&usrp_sink_impl::get_mboard_sensor, this, _1, 
mboard_index)
+            )) {
+          GR_LOG_WARN(d_logger, boost::format("Sensor '%s' failed to lock 
within timeout on motherboard %d.") % sensor_name % mboard_index);
+          clocks_locked = false;
+        }
+      }
+
+      // 2) Check LO for all channels
+      for (size_t i = 0; i < _nchan; i++) {
+        size_t chan_index = _stream_args.channels[i];
+        if (not _wait_for_locked_sensor(
+                get_sensor_names(chan_index),
+                "lo_locked",
+                boost::bind(&usrp_sink_impl::get_sensor, this, _1, chan_index)
+            )) {
+          GR_LOG_WARN(d_logger, boost::format("Sensor 'lo_locked' failed to 
lock within timeout on channel %d.") % chan_index);
+          clocks_locked = false;
+        }
+      }
+
+      return clocks_locked;
     }
 
+
     usrp_sink_impl::~usrp_sink_impl()
     {
     }
diff --git a/gr-uhd/lib/usrp_sink_impl.h b/gr-uhd/lib/usrp_sink_impl.h
index 8848fe0..21bb991 100644
--- a/gr-uhd/lib/usrp_sink_impl.h
+++ b/gr-uhd/lib/usrp_sink_impl.h
@@ -123,6 +123,10 @@ namespace gr {
       inline void tag_work(int &ninput_items);
 
     private:
+      /*! \brief Run through all 'lock' sensors and make sure they are 
actually locked.
+       */
+      bool _check_sensors_locked();
+
       //! Like set_center_freq(), but uses _curr_freq and _curr_lo_offset
       ::uhd::tune_result_t _set_center_freq_from_internals(size_t chan);
       //! Calls _set_center_freq_from_internals() on all channels
diff --git a/gr-uhd/lib/usrp_source_impl.cc b/gr-uhd/lib/usrp_source_impl.cc
index b85b45b..53038bf 100644
--- a/gr-uhd/lib/usrp_source_impl.cc
+++ b/gr-uhd/lib/usrp_source_impl.cc
@@ -79,6 +79,47 @@ namespace gr {
           pmt::mp("command"),
           boost::bind(&usrp_source_impl::msg_handler_command, this, _1)
       );
+
+      _check_sensors_locked();
+    }
+
+    bool usrp_source_impl::_check_sensors_locked()
+    {
+      bool clocks_locked = true;
+
+      // 1) Check ref lock for all mboards
+      for (size_t mboard_index = 0; mboard_index < _dev->get_num_mboards(); 
mboard_index++) {
+        std::string sensor_name = "ref_locked";
+        if (_dev->get_clock_source(mboard_index) == "internal") {
+          continue;
+        }
+        else if (_dev->get_clock_source(mboard_index) == "mimo") {
+          sensor_name = "mimo_locked";
+        }
+        if (not _wait_for_locked_sensor(
+                get_mboard_sensor_names(mboard_index),
+                sensor_name,
+                boost::bind(&usrp_source_impl::get_mboard_sensor, this, _1, 
mboard_index)
+            )) {
+          GR_LOG_WARN(d_logger, boost::format("Sensor '%s' failed to lock 
within timeout on motherboard %d.") % sensor_name % mboard_index);
+          clocks_locked = false;
+        }
+      }
+
+      // 2) Check LO for all channels
+      for (size_t i = 0; i < _nchan; i++) {
+        size_t chan_index = _stream_args.channels[i];
+        if (not _wait_for_locked_sensor(
+                get_sensor_names(chan_index),
+                "lo_locked",
+                boost::bind(&usrp_source_impl::get_sensor, this, _1, 
chan_index)
+            )) {
+          GR_LOG_WARN(d_logger, boost::format("Sensor 'lo_locked' failed to 
lock within timeout on channel %d.") % chan_index);
+          clocks_locked = false;
+        }
+      }
+
+      return clocks_locked;
     }
 
     usrp_source_impl::~usrp_source_impl()
diff --git a/gr-uhd/lib/usrp_source_impl.h b/gr-uhd/lib/usrp_source_impl.h
index faceb5a..6de4c9c 100644
--- a/gr-uhd/lib/usrp_source_impl.h
+++ b/gr-uhd/lib/usrp_source_impl.h
@@ -125,6 +125,9 @@ namespace gr {
                gr_vector_void_star &output_items);
 
     private:
+      /*! \brief Run through all 'lock' sensors and make sure they are 
actually locked.
+       */
+      bool _check_sensors_locked();
 #ifdef GR_UHD_USE_STREAM_API
       ::uhd::rx_streamer::sptr _rx_stream;
       size_t _samps_per_packet;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]