summaryrefslogtreecommitdiff
path: root/gr-uhd
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2014-07-07 18:06:20 +0200
committerMartin Braun <martin.braun@ettus.com>2014-07-08 12:10:22 +0200
commit12523cdb3218be85565c3c3bcb49d113e6bac518 (patch)
tree94960d3ed62cf265d6c1966a3a9a628f449af4f4 /gr-uhd
parentaf0a33196d7a39d27df7f1810f395e6f64cf43b6 (diff)
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.
Diffstat (limited to 'gr-uhd')
-rw-r--r--gr-uhd/lib/usrp_common.h50
-rw-r--r--gr-uhd/lib/usrp_sink_impl.cc42
-rw-r--r--gr-uhd/lib/usrp_sink_impl.h4
-rw-r--r--gr-uhd/lib/usrp_source_impl.cc41
-rw-r--r--gr-uhd/lib/usrp_source_impl.h3
5 files changed, 139 insertions, 1 deletions
diff --git a/gr-uhd/lib/usrp_common.h b/gr-uhd/lib/usrp_common.h
index 732bcef63c..29caa585cf 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 ad96bcb216..cdbe7b58f4 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 8848fe0712..21bb991b92 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 b85b45b16b..53038bf202 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 faceb5a177..6de4c9c6a3 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;