summaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/CMakeLists.txt2
-rw-r--r--host/lib/simple_device.cpp303
-rw-r--r--host/lib/time_spec.cpp40
-rw-r--r--host/lib/usrp/usrp2/dboard_impl.cpp9
-rw-r--r--host/lib/usrp/usrp2/dsp_impl.cpp21
-rw-r--r--host/lib/usrp/usrp2/fw_common.h8
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp35
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp1
8 files changed, 400 insertions, 19 deletions
diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt
index b1daf22d1..b141d67bb 100644
--- a/host/lib/CMakeLists.txt
+++ b/host/lib/CMakeLists.txt
@@ -23,6 +23,8 @@ SET(libuhd_sources
device_addr.cpp
gain_handler.cpp
metadata.cpp
+ simple_device.cpp
+ time_spec.cpp
wax.cpp
transport/udp_simple.cpp
transport/vrt.cpp
diff --git a/host/lib/simple_device.cpp b/host/lib/simple_device.cpp
new file mode 100644
index 000000000..63a17c52d
--- /dev/null
+++ b/host/lib/simple_device.cpp
@@ -0,0 +1,303 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// 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/>.
+//
+
+#include <uhd/simple_device.hpp>
+#include <uhd/device.hpp>
+#include <uhd/utils.hpp>
+#include <uhd/props.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/trim.hpp>
+#include <boost/foreach.hpp>
+#include <boost/format.hpp>
+#include <stdexcept>
+
+using namespace uhd;
+
+tune_result_t::tune_result_t(void){
+ /* NOP */
+}
+
+/***********************************************************************
+ * Tune Helper Function
+ **********************************************************************/
+static tune_result_t tune(
+ double target_freq,
+ double lo_offset,
+ wax::obj subdev,
+ wax::obj dxc,
+ bool is_tx
+){
+ wax::obj subdev_freq_proxy = subdev[SUBDEV_PROP_FREQ];
+ bool subdev_quadrature = wax::cast<bool>(subdev[SUBDEV_PROP_QUADRATURE]);
+ bool subdev_spectrum_inverted = wax::cast<bool>(subdev[SUBDEV_PROP_SPECTRUM_INVERTED]);
+ wax::obj dxc_freq_proxy = dxc[std::string("freq")];
+ double dxc_sample_rate = wax::cast<double>(dxc[std::string("rate")]);
+
+ // Ask the d'board to tune as closely as it can to target_freq+lo_offset
+ double target_inter_freq = target_freq + lo_offset;
+ subdev_freq_proxy = target_inter_freq;
+ double actual_inter_freq = wax::cast<double>(subdev_freq_proxy);
+
+ // Calculate the DDC setting that will downconvert the baseband from the
+ // daughterboard to our target frequency.
+ double delta_freq = target_freq - actual_inter_freq;
+ double delta_sign = std::signum(delta_freq);
+ delta_freq *= delta_sign;
+ delta_freq = fmod(delta_freq, dxc_sample_rate);
+ bool inverted = delta_freq > dxc_sample_rate/2.0;
+ double target_dxc_freq = inverted? (delta_freq - dxc_sample_rate) : (-delta_freq);
+ target_dxc_freq *= delta_sign;
+
+ // If the spectrum is inverted, and the daughterboard doesn't do
+ // quadrature downconversion, we can fix the inversion by flipping the
+ // sign of the dxc_freq... (This only happens using the basic_rx board)
+ if (subdev_spectrum_inverted){
+ inverted = not inverted;
+ }
+ if (inverted and not subdev_quadrature){
+ target_dxc_freq *= -1.0;
+ inverted = not inverted;
+ }
+ // down conversion versus up conversion, fight!
+ // your mother is ugly and your going down...
+ target_dxc_freq *= (is_tx)? -1.0 : +1.0;
+
+ dxc_freq_proxy = target_dxc_freq;
+ double actual_dxc_freq = wax::cast<double>(dxc_freq_proxy);
+
+ //return some kind of tune result tuple/struct
+ tune_result_t tune_result;
+ tune_result.target_inter_freq = target_inter_freq;
+ tune_result.actual_inter_freq = actual_inter_freq;
+ tune_result.target_dxc_freq = target_dxc_freq;
+ tune_result.actual_dxc_freq = actual_dxc_freq;
+ tune_result.spectrum_inverted = inverted;
+ return tune_result;
+}
+
+/***********************************************************************
+ * Helper Functions
+ **********************************************************************/
+static std::string trim(const std::string &in){
+ return boost::algorithm::trim_copy(in);
+}
+
+device_addr_t args_to_device_addr(const std::string &args){
+ device_addr_t addr;
+
+ //split the args at the semi-colons
+ std::vector<std::string> pairs;
+ boost::split(pairs, args, boost::is_any_of(";"));
+ BOOST_FOREACH(std::string pair, pairs){
+ if (trim(pair) == "") continue;
+
+ //split the key value pairs at the equals
+ std::vector<std::string> key_val;
+ boost::split(key_val, pair, boost::is_any_of("="));
+ if (key_val.size() != 2) throw std::runtime_error("invalid args string: "+args);
+ addr[trim(key_val[0])] = trim(key_val[1]);
+ }
+
+ return addr;
+}
+
+static std::vector<double> get_xx_rates(wax::obj decerps, wax::obj rate){
+ std::vector<double> rates;
+ BOOST_FOREACH(size_t decerp, wax::cast<std::vector<size_t> >(decerps)){
+ rates.push_back(wax::cast<double>(rate)/decerp);
+ }
+ return rates;
+}
+
+/***********************************************************************
+ * Simple Device Implementation
+ **********************************************************************/
+class simple_device_impl : public simple_device{
+public:
+ simple_device_impl(const device_addr_t &addr){
+ _dev = device::make(addr);
+ _mboard = (*_dev)[DEVICE_PROP_MBOARD];
+ _rx_ddc = _mboard[named_prop_t(MBOARD_PROP_RX_DSP, "ddc0")];
+ _tx_duc = _mboard[named_prop_t(MBOARD_PROP_TX_DSP, "duc0")];
+ _rx_subdev = _mboard[MBOARD_PROP_RX_DBOARD][DBOARD_PROP_SUBDEV];
+ _tx_subdev = _mboard[MBOARD_PROP_TX_DBOARD][DBOARD_PROP_SUBDEV];
+ }
+
+ ~simple_device_impl(void){
+ /* NOP */
+ }
+
+ device::sptr get_device(void){
+ return _dev;
+ }
+
+ std::string get_name(void){
+ return wax::cast<std::string>(_mboard[MBOARD_PROP_NAME]);
+ }
+
+ /*******************************************************************
+ * Streaming
+ ******************************************************************/
+ void set_streaming(bool enb){
+ _rx_ddc[std::string("enabled")] = enb;
+ }
+
+ bool get_streaming(void){
+ return wax::cast<bool>(_rx_ddc[std::string("enabled")]);
+ }
+
+ /*******************************************************************
+ * RX methods
+ ******************************************************************/
+ void set_rx_rate(double rate){
+ double samp_rate = wax::cast<double>(_rx_ddc[std::string("rate")]);
+ assert_has(get_rx_rates(), rate, "simple device rx rate");
+ _rx_ddc[std::string("decim")] = size_t(samp_rate/rate);
+ }
+
+ double get_rx_rate(void){
+ double samp_rate = wax::cast<double>(_rx_ddc[std::string("rate")]);
+ size_t decim = wax::cast<size_t>(_rx_ddc[std::string("decim")]);
+ return samp_rate/decim;
+ }
+
+ std::vector<double> get_rx_rates(void){
+ return get_xx_rates(_rx_ddc[std::string("decims")], _rx_ddc[std::string("rate")]);
+ }
+
+ tune_result_t set_rx_freq(double target_freq, double lo_offset){
+ return tune(target_freq, lo_offset, _rx_subdev, _rx_ddc, false/* not tx */);
+ }
+
+ double get_rx_freq_min(void){
+ return wax::cast<double>(_rx_subdev[SUBDEV_PROP_FREQ_MIN]);
+ }
+
+ double get_rx_freq_max(void){
+ return wax::cast<double>(_rx_subdev[SUBDEV_PROP_FREQ_MAX]);
+ }
+
+ void set_rx_gain(float gain){
+ _rx_subdev[SUBDEV_PROP_GAIN] = gain;
+ }
+
+ float get_rx_gain(void){
+ return wax::cast<float>(_rx_subdev[SUBDEV_PROP_GAIN]);
+ }
+
+ float get_rx_gain_min(void){
+ return wax::cast<float>(_rx_subdev[SUBDEV_PROP_GAIN_MIN]);
+ }
+
+ float get_rx_gain_max(void){
+ return wax::cast<float>(_rx_subdev[SUBDEV_PROP_GAIN_MAX]);
+ }
+
+ float get_rx_gain_step(void){
+ return wax::cast<float>(_rx_subdev[SUBDEV_PROP_GAIN_STEP]);
+ }
+
+ void set_rx_antenna(const std::string &ant){
+ _rx_subdev[SUBDEV_PROP_ANTENNA] = ant;
+ }
+
+ std::string get_rx_antenna(void){
+ return wax::cast<std::string>(_rx_subdev[SUBDEV_PROP_ANTENNA]);
+ }
+
+ std::vector<std::string> get_rx_antennas(void){
+ return wax::cast<std::vector<std::string> >(_rx_subdev[SUBDEV_PROP_ANTENNA_NAMES]);
+ }
+
+ /*******************************************************************
+ * TX methods
+ ******************************************************************/
+ void set_tx_rate(double rate){
+ double samp_rate = wax::cast<double>(_tx_duc[std::string("rate")]);
+ assert_has(get_tx_rates(), rate, "simple device tx rate");
+ _tx_duc[std::string("interp")] = size_t(samp_rate/rate);
+ }
+
+ double get_tx_rate(void){
+ double samp_rate = wax::cast<double>(_tx_duc[std::string("rate")]);
+ size_t interp = wax::cast<size_t>(_tx_duc[std::string("interp")]);
+ return samp_rate/interp;
+ }
+
+ std::vector<double> get_tx_rates(void){
+ return get_xx_rates(_tx_duc[std::string("interps")], _tx_duc[std::string("rate")]);
+ }
+
+ tune_result_t set_tx_freq(double target_freq, double lo_offset){
+ return tune(target_freq, lo_offset, _tx_subdev, _tx_duc, true/* is tx */);
+ }
+
+ double get_tx_freq_min(void){
+ return wax::cast<double>(_tx_subdev[SUBDEV_PROP_FREQ_MIN]);
+ }
+
+ double get_tx_freq_max(void){
+ return wax::cast<double>(_tx_subdev[SUBDEV_PROP_FREQ_MAX]);
+ }
+
+ void set_tx_gain(float gain){
+ _tx_subdev[SUBDEV_PROP_GAIN] = gain;
+ }
+
+ float get_tx_gain(void){
+ return wax::cast<float>(_tx_subdev[SUBDEV_PROP_GAIN]);
+ }
+
+ float get_tx_gain_min(void){
+ return wax::cast<float>(_tx_subdev[SUBDEV_PROP_GAIN_MIN]);
+ }
+
+ float get_tx_gain_max(void){
+ return wax::cast<float>(_tx_subdev[SUBDEV_PROP_GAIN_MAX]);
+ }
+
+ float get_tx_gain_step(void){
+ return wax::cast<float>(_tx_subdev[SUBDEV_PROP_GAIN_STEP]);
+ }
+
+ void set_tx_antenna(const std::string &ant){
+ _tx_subdev[SUBDEV_PROP_ANTENNA] = ant;
+ }
+
+ std::string get_tx_antenna(void){
+ return wax::cast<std::string>(_tx_subdev[SUBDEV_PROP_ANTENNA]);
+ }
+
+ std::vector<std::string> get_tx_antennas(void){
+ return wax::cast<std::vector<std::string> >(_tx_subdev[SUBDEV_PROP_ANTENNA_NAMES]);
+ }
+
+private:
+ device::sptr _dev;
+ wax::obj _mboard;
+ wax::obj _rx_ddc;
+ wax::obj _tx_duc;
+ wax::obj _rx_subdev;
+ wax::obj _tx_subdev;
+};
+
+/***********************************************************************
+ * The Make Function
+ **********************************************************************/
+simple_device::sptr simple_device::make(const std::string &args){
+ return sptr(new simple_device_impl(args_to_device_addr(args)));
+}
diff --git a/host/lib/time_spec.cpp b/host/lib/time_spec.cpp
new file mode 100644
index 000000000..193441342
--- /dev/null
+++ b/host/lib/time_spec.cpp
@@ -0,0 +1,40 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// 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/>.
+//
+
+#include <uhd/time_spec.hpp>
+
+using namespace uhd;
+
+time_spec_t::time_spec_t(void){
+ secs = ~0;
+ ticks = ~0;
+}
+
+time_spec_t::time_spec_t(uint32_t new_secs, uint32_t new_ticks){
+ secs = new_secs;
+ ticks = new_ticks;
+}
+
+static const boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
+static double time_tick_rate(boost::posix_time::time_duration::ticks_per_second());
+
+time_spec_t::time_spec_t(boost::posix_time::ptime time, double tick_rate){
+ boost::posix_time::time_duration td = time - epoch;
+ secs = td.total_seconds();
+ double time_ticks_per_device_ticks = time_tick_rate/tick_rate;
+ ticks = td.fractional_seconds()/time_ticks_per_device_ticks;
+}
diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp
index 32c64f541..da05c3241 100644
--- a/host/lib/usrp/usrp2/dboard_impl.cpp
+++ b/host/lib/usrp/usrp2/dboard_impl.cpp
@@ -16,6 +16,7 @@
//
#include <uhd/utils.hpp>
+#include <boost/format.hpp>
#include "usrp2_impl.hpp"
#include "dboard_interface.hpp"
@@ -83,8 +84,8 @@ void usrp2_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){
val = _dboard_manager->get_rx_subdev_names();
return;
- case DBOARD_PROP_CODEC:
- throw std::runtime_error("unhandled prop in usrp2 dboard");
+ //case DBOARD_PROP_CODEC:
+ // throw std::runtime_error("unhandled prop in usrp2 dboard");
}
}
@@ -113,8 +114,8 @@ void usrp2_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){
val = _dboard_manager->get_tx_subdev_names();
return;
- case DBOARD_PROP_CODEC:
- throw std::runtime_error("unhandled prop in usrp2 dboard");
+ //case DBOARD_PROP_CODEC:
+ // throw std::runtime_error("unhandled prop in usrp2 dboard");
}
}
diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp
index 7831b7667..cb7f58ec8 100644
--- a/host/lib/usrp/usrp2/dsp_impl.cpp
+++ b/host/lib/usrp/usrp2/dsp_impl.cpp
@@ -16,6 +16,7 @@
//
#include <uhd/utils.hpp>
+#include <boost/format.hpp>
#include <boost/assign/list_of.hpp>
#include "usrp2_impl.hpp"
@@ -110,7 +111,7 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){
prop_names_t others = boost::assign::list_of
("rate")
("decim")
- ("decim_rates")
+ ("decims")
("freq")
("enabled")
("stream_at")
@@ -131,7 +132,7 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){
val = _ddc_decim;
return;
}
- else if (key_name == "decim_rates"){
+ else if (key_name == "decims"){
val = _allowed_decim_and_interp_rates;
return;
}
@@ -154,10 +155,10 @@ void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val){
std::string key_name = wax::cast<std::string>(key);
if (key_name == "decim"){
size_t new_decim = wax::cast<size_t>(val);
- ASSERT_THROW(std::has(
+ assert_has(
_allowed_decim_and_interp_rates,
- new_decim
- ));
+ new_decim, "usrp2 decimation"
+ );
_ddc_decim = new_decim; //shadow
update_ddc_config();
return;
@@ -244,7 +245,7 @@ void usrp2_impl::duc_get(const wax::obj &key, wax::obj &val){
prop_names_t others = boost::assign::list_of
("rate")
("interp")
- ("interp_rates")
+ ("interps")
("freq")
;
val = others;
@@ -263,7 +264,7 @@ void usrp2_impl::duc_get(const wax::obj &key, wax::obj &val){
val = _duc_interp;
return;
}
- else if (key_name == "interp_rates"){
+ else if (key_name == "interps"){
val = _allowed_decim_and_interp_rates;
return;
}
@@ -282,10 +283,10 @@ void usrp2_impl::duc_set(const wax::obj &key, const wax::obj &val){
std::string key_name = wax::cast<std::string>(key);
if (key_name == "interp"){
size_t new_interp = wax::cast<size_t>(val);
- ASSERT_THROW(std::has(
+ assert_has(
_allowed_decim_and_interp_rates,
- new_interp
- ));
+ new_interp, "usrp2 interpolation"
+ );
_duc_interp = new_interp; //shadow
update_duc_config();
return;
diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h
index 8e4b2ba35..10c1ef8cf 100644
--- a/host/lib/usrp/usrp2/fw_common.h
+++ b/host/lib/usrp/usrp2/fw_common.h
@@ -91,6 +91,9 @@ typedef enum{
USRP2_CTRL_ID_SETUP_THIS_DUC_FOR_ME_BRO,
USRP2_CTRL_ID_TOTALLY_SETUP_THE_DUC_DUDE,
+ USRP2_CTRL_ID_GOT_A_NEW_TIME_FOR_YOU_BRO,
+ USRP2_CTRL_ID_SWEET_I_GOT_THAT_TIME_DUDE,
+
USRP2_CTRL_ID_PEACE_OUT
} usrp2_ctrl_id_t;
@@ -186,6 +189,11 @@ typedef struct{
uint32_t interp;
uint32_t scale_iq;
} duc_args;
+ struct {
+ uint32_t secs;
+ uint32_t ticks;
+ uint8_t now;
+ } time_args;
} data;
} usrp2_ctrl_data_t;
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index 8e682a675..47e22c473 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -28,6 +28,10 @@ void usrp2_impl::mboard_init(void){
boost::bind(&usrp2_impl::mboard_get, this, _1, _2),
boost::bind(&usrp2_impl::mboard_set, this, _1, _2)
);
+
+ //set the time on the usrp2 as close as possible to the system utc time
+ boost::posix_time::ptime now(boost::posix_time::microsec_clock::universal_time());
+ set_time_spec(time_spec_t(now, get_master_clock_freq()), true);
}
void usrp2_impl::init_clock_config(void){
@@ -64,6 +68,19 @@ void usrp2_impl::update_clock_config(void){
ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_GOT_THE_NEW_CLOCK_CONFIG_DUDE);
}
+void usrp2_impl::set_time_spec(const time_spec_t &time_spec, bool now){
+ //setup the out data
+ usrp2_ctrl_data_t out_data;
+ out_data.id = htonl(USRP2_CTRL_ID_GOT_A_NEW_TIME_FOR_YOU_BRO);
+ out_data.data.time_args.secs = htonl(time_spec.secs);
+ out_data.data.time_args.ticks = htonl(time_spec.ticks);
+ out_data.data.time_args.now = (now)? 1 : 0;
+
+ //send and recv
+ usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data);
+ ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_SWEET_I_GOT_THAT_TIME_DUDE);
+}
+
/***********************************************************************
* MBoard Get Properties
**********************************************************************/
@@ -157,7 +174,7 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){
case MBOARD_PROP_PPS_SOURCE:{
std::string name = wax::cast<std::string>(val);
- ASSERT_THROW(_pps_source_dict.has_key(name));
+ assert_has(_pps_source_dict.get_keys(), name, "usrp2 pps source");
_pps_source = name; //shadow
update_clock_config();
}
@@ -165,7 +182,7 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){
case MBOARD_PROP_PPS_POLARITY:{
std::string name = wax::cast<std::string>(val);
- ASSERT_THROW(_pps_polarity_dict.has_key(name));
+ assert_has(_pps_polarity_dict.get_keys(), name, "usrp2 pps polarity");
_pps_polarity = name; //shadow
update_clock_config();
}
@@ -173,12 +190,22 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){
case MBOARD_PROP_REF_SOURCE:{
std::string name = wax::cast<std::string>(val);
- ASSERT_THROW(_ref_source_dict.has_key(name));
+ assert_has(_ref_source_dict.get_keys(), name, "usrp2 reference source");
_ref_source = name; //shadow
update_clock_config();
}
return;
+ case MBOARD_PROP_TIME_NOW:{
+ set_time_spec(wax::cast<time_spec_t>(val), true);
+ return;
+ }
+
+ case MBOARD_PROP_TIME_NEXT_PPS:{
+ set_time_spec(wax::cast<time_spec_t>(val), false);
+ return;
+ }
+
case MBOARD_PROP_NAME:
case MBOARD_PROP_OTHERS:
case MBOARD_PROP_CLOCK_RATE:
@@ -192,8 +219,6 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){
case MBOARD_PROP_TX_DBOARD_NAMES:
case MBOARD_PROP_PPS_SOURCE_NAMES:
case MBOARD_PROP_REF_SOURCE_NAMES:
- case MBOARD_PROP_TIME_NOW:
- case MBOARD_PROP_TIME_NEXT_PPS:
throw std::runtime_error("Error: trying to set read-only property on usrp2 mboard");
}
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index f4e6054bd..fc713c2bf 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -135,6 +135,7 @@ private:
std::string _pps_source, _pps_polarity, _ref_source;
void init_clock_config(void);
void update_clock_config(void);
+ void set_time_spec(const uhd::time_spec_t &time_spec, bool now);
//mappings from clock config strings to over the wire enums
uhd::dict<std::string, usrp2_pps_source_t> _pps_source_dict;