aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-06-29 10:54:28 -0700
committerJosh Blum <josh@joshknows.com>2011-06-29 10:54:28 -0700
commitadbe1a0efe7598a9e0433675e2852aad2e280c62 (patch)
tree3ff0bec87ff979f091e3233bf06118670e2535fe /host/lib/usrp
parentd2f79c07281604c1b48ec81f1cdb2754e97bbe65 (diff)
downloaduhd-adbe1a0efe7598a9e0433675e2852aad2e280c62.tar.gz
uhd-adbe1a0efe7598a9e0433675e2852aad2e280c62.tar.bz2
uhd-adbe1a0efe7598a9e0433675e2852aad2e280c62.zip
uhd: loopback working on usrp2
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/cores/rx_dsp_core_200.cpp15
-rw-r--r--host/lib/usrp/cores/rx_dsp_core_200.hpp3
-rw-r--r--host/lib/usrp/cores/tx_dsp_core_200.cpp9
-rw-r--r--host/lib/usrp/cores/tx_dsp_core_200.hpp3
-rw-r--r--host/lib/usrp/multi_usrp.cpp130
5 files changed, 132 insertions, 28 deletions
diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp
index 3215bea15..8fcf4df96 100644
--- a/host/lib/usrp/cores/rx_dsp_core_200.cpp
+++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp
@@ -22,12 +22,12 @@
#include <boost/math/special_functions/round.hpp>
#include <boost/math/special_functions/sign.hpp>
#include <algorithm>
-#include <algorithm>
#include <cmath>
#define REG_DSP_RX_FREQ _dsp_base + 0
-#define REG_DSP_RX_DECIM _dsp_base + 4
-#define REG_DSP_RX_MUX _dsp_base + 8
+//skip one right here
+#define REG_DSP_RX_DECIM _dsp_base + 8
+#define REG_DSP_RX_MUX _dsp_base + 12
#define FLAG_DSP_RX_MUX_SWAP_IQ (1 << 0)
#define FLAG_DSP_RX_MUX_REAL_MODE (1 << 1)
@@ -123,7 +123,8 @@ public:
}
double set_host_rate(const double rate){
- int decim = boost::math::iround(_tick_rate/rate);
+ const size_t decim_rate = boost::math::iround(_tick_rate/rate);
+ size_t decim = decim_rate;
//determine which half-band filters are activated
int hb0 = 0, hb1 = 0;
@@ -138,7 +139,7 @@ public:
_iface->poke32(REG_DSP_RX_DECIM, (hb1 << 9) | (hb0 << 8) | (decim & 0xff));
- return _tick_rate/decim;
+ return _tick_rate/decim_rate;
}
double set_freq(const double freq_){
@@ -160,6 +161,10 @@ public:
return actual_freq;
}
+ uhd::meta_range_t get_freq_range(void){
+ return uhd::meta_range_t(-_tick_rate/2, +_tick_rate/2, _tick_rate/std::pow(2.0, 32));
+ }
+
void handle_overflow(void){
if (_continuous_streaming) issue_stream_command(stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
}
diff --git a/host/lib/usrp/cores/rx_dsp_core_200.hpp b/host/lib/usrp/cores/rx_dsp_core_200.hpp
index c496fca76..e0b6e18e4 100644
--- a/host/lib/usrp/cores/rx_dsp_core_200.hpp
+++ b/host/lib/usrp/cores/rx_dsp_core_200.hpp
@@ -19,6 +19,7 @@
#define INCLUDED_LIBUHD_USRP_RX_DSP_CORE_200_HPP
#include <uhd/config.hpp>
+#include <uhd/types/ranges.hpp>
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include <uhd/types/stream_cmd.hpp>
@@ -45,6 +46,8 @@ public:
virtual double set_host_rate(const double rate) = 0;
+ virtual uhd::meta_range_t get_freq_range(void) = 0;
+
virtual double set_freq(const double freq) = 0;
virtual void handle_overflow(void) = 0;
diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp
index 293b0b447..d2981bbdb 100644
--- a/host/lib/usrp/cores/tx_dsp_core_200.cpp
+++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp
@@ -69,7 +69,8 @@ public:
}
double set_host_rate(const double rate){
- int interp = boost::math::iround(_tick_rate/rate);
+ const size_t interp_rate = boost::math::iround(_tick_rate/rate);
+ size_t interp = interp_rate;
//determine which half-band filters are activated
int hb0 = 0, hb1 = 0;
@@ -90,7 +91,7 @@ public:
const boost::int16_t scale = boost::math::iround((4096*std::pow(2, ceil_log2(rate_cubed)))/(1.65*rate_cubed));
_iface->poke32(REG_DSP_TX_SCALE_IQ, (boost::uint32_t(scale) << 16) | (boost::uint32_t(scale) << 0));
- return _tick_rate/interp;
+ return _tick_rate/interp_rate;
}
double set_freq(const double freq_){
@@ -112,6 +113,10 @@ public:
return actual_freq;
}
+ uhd::meta_range_t get_freq_range(void){
+ return uhd::meta_range_t(-_tick_rate/2, +_tick_rate/2, _tick_rate/std::pow(2.0, 32));
+ }
+
void set_updates(const size_t cycles_per_up, const size_t packets_per_up){
_iface->poke32(REG_TX_CTRL_CYCLES_PER_UP, (cycles_per_up == 0)? 0 : (FLAG_TX_CTRL_UP_ENB | cycles_per_up));
_iface->poke32(REG_TX_CTRL_PACKETS_PER_UP, (packets_per_up == 0)? 0 : (FLAG_TX_CTRL_UP_ENB | packets_per_up));
diff --git a/host/lib/usrp/cores/tx_dsp_core_200.hpp b/host/lib/usrp/cores/tx_dsp_core_200.hpp
index f218fe8c9..f74ec0bdb 100644
--- a/host/lib/usrp/cores/tx_dsp_core_200.hpp
+++ b/host/lib/usrp/cores/tx_dsp_core_200.hpp
@@ -19,6 +19,7 @@
#define INCLUDED_LIBUHD_USRP_TX_DSP_CORE_200_HPP
#include <uhd/config.hpp>
+#include <uhd/types/ranges.hpp>
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include "wb_iface.hpp"
@@ -37,6 +38,8 @@ public:
virtual double set_host_rate(const double rate) = 0;
+ virtual uhd::meta_range_t get_freq_range(void) = 0;
+
virtual double set_freq(const double freq) = 0;
virtual void set_updates(const size_t cycles_per_up, const size_t packets_per_up) = 0;
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index 935419c18..4c16772b3 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -23,11 +23,6 @@
#include <uhd/exception.hpp>
#include <uhd/utils/msg.hpp>
#include <uhd/utils/gain_group.hpp>
-#include <uhd/usrp/subdev_props.hpp>
-#include <uhd/usrp/mboard_props.hpp>
-#include <uhd/usrp/device_props.hpp>
-#include <uhd/usrp/dboard_props.hpp>
-#include <uhd/usrp/dsp_props.hpp>
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
@@ -71,6 +66,9 @@ static void do_tune_freq_warning_message(
}
}
+/***********************************************************************
+ * Gain helper functions
+ **********************************************************************/
static double get_gain_value(property_tree::sptr tree, const property_tree::path_type &path){
return tree->access<double>(path / "value").get();
}
@@ -92,6 +90,100 @@ static gain_fcns_t make_gain_fcns_from_path(property_tree::sptr tree, const prop
}
/***********************************************************************
+ * Tune Helper Functions
+ **********************************************************************/
+static const double RX_SIGN = +1.0;
+static const double TX_SIGN = -1.0;
+
+static tune_result_t tune_xx_subdev_and_dsp(
+ const double xx_sign,
+ property_tree::sptr tree,
+ const property_tree::path_type &dsp_path,
+ const property_tree::path_type &rf_fe_path,
+ const tune_request_t &tune_request
+){
+ //------------------------------------------------------------------
+ //-- calculate the LO offset, only used with automatic policy
+ //------------------------------------------------------------------
+ double lo_offset = 0.0;
+ if (tree->access<bool>(rf_fe_path / "use_lo_offset").get()){
+ //If the local oscillator will be in the passband, use an offset.
+ //But constrain the LO offset by the width of the filter bandwidth.
+ const double rate = tree->access<double>(dsp_path / "rate" / "value").get();
+ const double bw = tree->access<double>(rf_fe_path / "bandwidth" / "value").get();
+ if (bw > rate) lo_offset = std::min((bw - rate)/2, rate/2);
+ }
+
+ //------------------------------------------------------------------
+ //-- set the RF frequency depending upon the policy
+ //------------------------------------------------------------------
+ double target_rf_freq = 0.0;
+ switch (tune_request.rf_freq_policy){
+ case tune_request_t::POLICY_AUTO:
+ target_rf_freq = tune_request.target_freq + lo_offset;
+ tree->access<double>(rf_fe_path / "freq" / "value").set(target_rf_freq);
+ break;
+
+ case tune_request_t::POLICY_MANUAL:
+ target_rf_freq = tune_request.rf_freq;
+ tree->access<double>(rf_fe_path / "freq" / "value").set(target_rf_freq);
+ break;
+
+ case tune_request_t::POLICY_NONE: break; //does not set
+ }
+ const double actual_rf_freq = tree->access<double>(rf_fe_path / "freq" / "value").get();
+
+ //------------------------------------------------------------------
+ //-- calculate the dsp freq, only used with automatic policy
+ //------------------------------------------------------------------
+ double target_dsp_freq = actual_rf_freq - tune_request.target_freq;
+
+ //invert the sign on the dsp freq for transmit
+ target_dsp_freq *= xx_sign;
+
+ //------------------------------------------------------------------
+ //-- set the dsp frequency depending upon the dsp frequency policy
+ //------------------------------------------------------------------
+ switch (tune_request.dsp_freq_policy){
+ case tune_request_t::POLICY_AUTO:
+ tree->access<double>(dsp_path / "freq" / "value").set(target_dsp_freq);
+ break;
+
+ case tune_request_t::POLICY_MANUAL:
+ target_dsp_freq = tune_request.dsp_freq;
+ tree->access<double>(dsp_path / "freq" / "value").set(target_dsp_freq);
+ break;
+
+ case tune_request_t::POLICY_NONE: break; //does not set
+ }
+ const double actual_dsp_freq = tree->access<double>(dsp_path / "freq" / "value").get();
+
+ //------------------------------------------------------------------
+ //-- load and return the tune result
+ //------------------------------------------------------------------
+ tune_result_t tune_result;
+ tune_result.target_rf_freq = target_rf_freq;
+ tune_result.actual_rf_freq = actual_rf_freq;
+ tune_result.target_dsp_freq = target_dsp_freq;
+ tune_result.actual_dsp_freq = actual_dsp_freq;
+ return tune_result;
+}
+
+static double derive_freq_from_xx_subdev_and_dsp(
+ const double xx_sign,
+ property_tree::sptr tree,
+ const property_tree::path_type &dsp_path,
+ const property_tree::path_type &rf_fe_path
+){
+ //extract actual dsp and IF frequencies
+ const double actual_rf_freq = tree->access<double>(rf_fe_path / "freq" / "value").get();
+ const double actual_dsp_freq = tree->access<double>(dsp_path / "freq" / "value").get();
+
+ //invert the sign on the dsp freq for transmit
+ return actual_rf_freq - actual_dsp_freq * xx_sign;
+}
+
+/***********************************************************************
* Multi USRP Implementation
**********************************************************************/
class multi_usrp_impl : public multi_usrp{
@@ -296,21 +388,19 @@ public:
}
tune_result_t set_rx_freq(const tune_request_t &tune_request, size_t chan){
- //TODO must invent for tree
- //tune_result_t r = tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), tune_request);
- //do_tune_freq_warning_message(tune_request.target_freq, get_rx_freq(chan), "RX");
- //return r;
+ tune_result_t r = tune_xx_subdev_and_dsp(RX_SIGN, _tree, rx_dsp_root(chan), rx_rf_fe_root(chan), tune_request);
+ do_tune_freq_warning_message(tune_request.target_freq, get_rx_freq(chan), "RX");
+ return r;
}
double get_rx_freq(size_t chan){
- //TODO must invent for tree
- //return derive_freq_from_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan));
+ return derive_freq_from_xx_subdev_and_dsp(RX_SIGN, _tree, rx_dsp_root(chan), rx_rf_fe_root(chan));
}
freq_range_t get_rx_freq_range(size_t chan){
meta_range_t range = _tree->access<meta_range_t>(rx_rf_fe_root(chan) / "freq" / "range").get();
- const double tick_rate = get_master_clock_rate(0); //ASSUME
- return meta_range_t(range.start() - tick_rate/2.0, range.stop() + tick_rate/2.0);
+ meta_range_t dsp_range = _tree->access<meta_range_t>(rx_dsp_root(chan) / "freq" / "range").get();
+ return meta_range_t(range.start() + dsp_range.start(), range.stop() + dsp_range.stop(), dsp_range.step());
}
void set_rx_gain(double gain, const std::string &name, size_t chan){
@@ -406,21 +496,19 @@ public:
}
tune_result_t set_tx_freq(const tune_request_t &tune_request, size_t chan){
- //TODO must invent for tree
- //tune_result_t r = tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), tune_request);
- //do_tune_freq_warning_message(tune_request.target_freq, get_tx_freq(chan), "TX");
- //return r;
+ tune_result_t r = tune_xx_subdev_and_dsp(TX_SIGN, _tree, tx_dsp_root(chan), tx_rf_fe_root(chan), tune_request);
+ do_tune_freq_warning_message(tune_request.target_freq, get_tx_freq(chan), "RX");
+ return r;
}
double get_tx_freq(size_t chan){
- //TODO must invent for tree
- //return derive_freq_from_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan));
+ return derive_freq_from_xx_subdev_and_dsp(TX_SIGN, _tree, tx_dsp_root(chan), tx_rf_fe_root(chan));
}
freq_range_t get_tx_freq_range(size_t chan){
meta_range_t range = _tree->access<meta_range_t>(tx_rf_fe_root(chan) / "freq" / "range").get();
- const double tick_rate = get_master_clock_rate(0); //ASSUME
- return meta_range_t(range.start() - tick_rate/2.0, range.stop() + tick_rate/2.0);
+ meta_range_t dsp_range = _tree->access<meta_range_t>(tx_dsp_root(chan) / "freq" / "range").get();
+ return meta_range_t(range.start() + dsp_range.start(), range.stop() + dsp_range.stop(), dsp_range.step());
}
void set_tx_gain(double gain, const std::string &name, size_t chan){