From b25e610868752ac55b6f8e0c05bc2e0f7b18e223 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 15 Jul 2010 22:59:37 -0700 Subject: usrp: added functions to derive tuned frequency, tweaked logic, added unit test --- host/lib/usrp/tune_helper.cpp | 99 +++++++++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 37 deletions(-) (limited to 'host/lib/usrp/tune_helper.cpp') diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp index 082c39f6d..1d584913c 100644 --- a/host/lib/usrp/tune_helper.cpp +++ b/host/lib/usrp/tune_helper.cpp @@ -19,16 +19,28 @@ #include #include #include +#include //unit_t #include using namespace uhd; using namespace uhd::usrp; /*********************************************************************** - * Tune Helper Function + * Tune Helper Functions **********************************************************************/ +static bool invert_dxc_freq( + bool outside_of_nyquist, + bool subdev_spectrum_inverted, + bool subdev_quadrature, + dboard_iface::unit_t unit +){ + bool is_tx = unit == dboard_iface::UNIT_TX; + if (subdev_quadrature) return is_tx; + return outside_of_nyquist xor subdev_spectrum_inverted xor is_tx; +} + static tune_result_t tune_xx_subdev_and_dxc( - bool is_tx, + dboard_iface::unit_t unit, wax::obj subdev, wax::obj dxc, double target_freq, double lo_offset ){ @@ -43,55 +55,61 @@ static tune_result_t tune_xx_subdev_and_dxc( subdev_freq_proxy = target_inter_freq; double actual_inter_freq = subdev_freq_proxy.as(); - // Calculate the DDC setting that will downconvert the baseband from the - // daughterboard to our target frequency. - double delta_freq = target_freq - actual_inter_freq; - int delta_sign = std::signum(delta_freq); - delta_freq *= delta_sign; - delta_freq = std::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; + //perform the correction correction for dxc rates outside of nyquist + double target_dxc_freq = std::fmod(target_freq - actual_inter_freq, dxc_sample_rate); + if (target_dxc_freq >= dxc_sample_rate/2.0) target_dxc_freq -= dxc_sample_rate; + else if (target_dxc_freq < -dxc_sample_rate/2.0) target_dxc_freq += dxc_sample_rate; + else target_dxc_freq *= -1.0; + + //invert the sign on the dxc freq given the following conditions + bool outside_of_nyquist = std::abs(target_freq - actual_inter_freq) > dxc_sample_rate/2.0; + if (invert_dxc_freq( + outside_of_nyquist, subdev_spectrum_inverted, subdev_quadrature, unit + )) target_dxc_freq *= -1.0; dxc_freq_proxy = target_dxc_freq; double actual_dxc_freq = dxc_freq_proxy.as(); - //return some kind of tune result tuple/struct + //load and return the tune result tune_result_t tune_result; tune_result.target_inter_freq = target_inter_freq; tune_result.actual_inter_freq = actual_inter_freq; tune_result.target_dsp_freq = target_dxc_freq; tune_result.actual_dsp_freq = actual_dxc_freq; - tune_result.spectrum_inverted = inverted; return tune_result; } +static double derive_freq_from_xx_subdev_and_dxc( + dboard_iface::unit_t unit, + wax::obj subdev, wax::obj dxc +){ + //extract subdev properties + bool subdev_quadrature = subdev[SUBDEV_PROP_QUADRATURE].as(); + bool subdev_spectrum_inverted = subdev[SUBDEV_PROP_SPECTRUM_INVERTED].as(); + + //extract actual dsp and IF frequencies + double actual_inter_freq = subdev[SUBDEV_PROP_FREQ].as(); + double actual_dxc_freq = dxc[DSP_PROP_FREQ_SHIFT].as(); + + //invert the sign on the dxc freq given the following conditions + if (invert_dxc_freq( + false, subdev_spectrum_inverted, subdev_quadrature, unit + )) actual_dxc_freq *= -1.0; + + return actual_inter_freq - actual_dxc_freq; +} + /*********************************************************************** * RX Tune **********************************************************************/ -tune_result_t uhd::usrp::tune_rx_subdev_and_ddc( +tune_result_t usrp::tune_rx_subdev_and_dsp( wax::obj subdev, wax::obj ddc, double target_freq, double lo_offset ){ - bool is_tx = false; - return tune_xx_subdev_and_dxc(is_tx, subdev, ddc, target_freq, lo_offset); + return tune_xx_subdev_and_dxc(dboard_iface::UNIT_RX, subdev, ddc, target_freq, lo_offset); } -tune_result_t uhd::usrp::tune_rx_subdev_and_ddc( +tune_result_t usrp::tune_rx_subdev_and_dsp( wax::obj subdev, wax::obj ddc, double target_freq ){ @@ -100,21 +118,24 @@ tune_result_t uhd::usrp::tune_rx_subdev_and_ddc( if (subdev[SUBDEV_PROP_USE_LO_OFFSET].as()){ lo_offset = 2.0*ddc[DSP_PROP_HOST_RATE].as(); } - return tune_rx_subdev_and_ddc(subdev, ddc, target_freq, lo_offset); + return tune_rx_subdev_and_dsp(subdev, ddc, target_freq, lo_offset); +} + +double usrp::derive_freq_from_rx_subdev_and_dsp(wax::obj subdev, wax::obj ddc){ + return derive_freq_from_xx_subdev_and_dxc(dboard_iface::UNIT_RX, subdev, ddc); } /*********************************************************************** * TX Tune **********************************************************************/ -tune_result_t uhd::usrp::tune_tx_subdev_and_duc( +tune_result_t usrp::tune_tx_subdev_and_dsp( wax::obj subdev, wax::obj duc, double target_freq, double lo_offset ){ - bool is_tx = true; - return tune_xx_subdev_and_dxc(is_tx, subdev, duc, target_freq, lo_offset); + return tune_xx_subdev_and_dxc(dboard_iface::UNIT_TX, subdev, duc, target_freq, lo_offset); } -tune_result_t uhd::usrp::tune_tx_subdev_and_duc( +tune_result_t usrp::tune_tx_subdev_and_dsp( wax::obj subdev, wax::obj duc, double target_freq ){ @@ -123,5 +144,9 @@ tune_result_t uhd::usrp::tune_tx_subdev_and_duc( if (subdev[SUBDEV_PROP_USE_LO_OFFSET].as()){ lo_offset = 2.0*duc[DSP_PROP_HOST_RATE].as(); } - return tune_tx_subdev_and_duc(subdev, duc, target_freq, lo_offset); + return tune_tx_subdev_and_dsp(subdev, duc, target_freq, lo_offset); +} + +double usrp::derive_freq_from_tx_subdev_and_dsp(wax::obj subdev, wax::obj duc){ + return derive_freq_from_xx_subdev_and_dxc(dboard_iface::UNIT_TX, subdev, duc); } -- cgit v1.2.3 From 2a3d0e653e9d38dc3eed729d1442f3d98aadb1e5 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 15 Jul 2010 14:57:30 -0700 Subject: usrp: removed spectrum inverted property from subdev code and tune helper (it wasnt used) --- host/include/uhd/usrp/subdev_props.hpp | 1 - host/lib/usrp/dboard/db_basic_and_lf.cpp | 8 -------- host/lib/usrp/dboard/db_rfx.cpp | 8 -------- host/lib/usrp/dboard/db_unknown.cpp | 8 -------- host/lib/usrp/dboard/db_wbx.cpp | 8 -------- host/lib/usrp/dboard/db_xcvr2450.cpp | 8 -------- host/lib/usrp/tune_helper.cpp | 13 +++---------- host/test/tune_helper_test.cpp | 13 ++++--------- host/utils/uhd_usrp_probe.cpp | 1 - 9 files changed, 7 insertions(+), 61 deletions(-) (limited to 'host/lib/usrp/tune_helper.cpp') diff --git a/host/include/uhd/usrp/subdev_props.hpp b/host/include/uhd/usrp/subdev_props.hpp index 1f8e91d68..cb7027ff1 100644 --- a/host/include/uhd/usrp/subdev_props.hpp +++ b/host/include/uhd/usrp/subdev_props.hpp @@ -38,7 +38,6 @@ namespace uhd{ namespace usrp{ SUBDEV_PROP_LO_LOCKED = 'L', //ro, bool SUBDEV_PROP_QUADRATURE = 'q', //ro, bool SUBDEV_PROP_IQ_SWAPPED = 'i', //ro, bool - SUBDEV_PROP_SPECTRUM_INVERTED = 's', //ro, bool SUBDEV_PROP_USE_LO_OFFSET = 'l', //ro, bool SUBDEV_PROP_RSSI = 'R', //ro, float SUBDEV_PROP_BANDWIDTH = 'B' //rw, double diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index 766deac78..b40be9dea 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -146,10 +146,6 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){ val = false; return; - case SUBDEV_PROP_SPECTRUM_INVERTED: - val = false; - return; - case SUBDEV_PROP_USE_LO_OFFSET: val = false; return; @@ -245,10 +241,6 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){ val = false; return; - case SUBDEV_PROP_SPECTRUM_INVERTED: - val = false; - return; - case SUBDEV_PROP_USE_LO_OFFSET: val = false; return; diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 2d6088983..9e5fcd6c6 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -434,10 +434,6 @@ void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ val = true; return; - case SUBDEV_PROP_SPECTRUM_INVERTED: - val = false; - return; - case SUBDEV_PROP_USE_LO_OFFSET: val = false; return; @@ -524,10 +520,6 @@ void rfx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ val = false; return; - case SUBDEV_PROP_SPECTRUM_INVERTED: - val = false; - return; - case SUBDEV_PROP_USE_LO_OFFSET: val = true; return; diff --git a/host/lib/usrp/dboard/db_unknown.cpp b/host/lib/usrp/dboard/db_unknown.cpp index ced27e34d..8b247c289 100644 --- a/host/lib/usrp/dboard/db_unknown.cpp +++ b/host/lib/usrp/dboard/db_unknown.cpp @@ -127,10 +127,6 @@ void unknown_rx::rx_get(const wax::obj &key_, wax::obj &val){ val = false; return; - case SUBDEV_PROP_SPECTRUM_INVERTED: - val = false; - return; - case SUBDEV_PROP_USE_LO_OFFSET: val = false; return; @@ -226,10 +222,6 @@ void unknown_tx::tx_get(const wax::obj &key_, wax::obj &val){ val = false; return; - case SUBDEV_PROP_SPECTRUM_INVERTED: - val = false; - return; - case SUBDEV_PROP_USE_LO_OFFSET: val = false; return; diff --git a/host/lib/usrp/dboard/db_wbx.cpp b/host/lib/usrp/dboard/db_wbx.cpp index 28bd6317b..23eb5ca44 100644 --- a/host/lib/usrp/dboard/db_wbx.cpp +++ b/host/lib/usrp/dboard/db_wbx.cpp @@ -518,10 +518,6 @@ void wbx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ val = false; return; - case SUBDEV_PROP_SPECTRUM_INVERTED: - val = false; - return; - case SUBDEV_PROP_USE_LO_OFFSET: val = false; return; @@ -612,10 +608,6 @@ void wbx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ val = false; return; - case SUBDEV_PROP_SPECTRUM_INVERTED: - val = false; - return; - case SUBDEV_PROP_USE_LO_OFFSET: val = false; return; diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index 5032b6f31..fabf3dffd 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -489,10 +489,6 @@ void xcvr2450::rx_get(const wax::obj &key_, wax::obj &val){ val = false; return; - case SUBDEV_PROP_SPECTRUM_INVERTED: - val = false; - return; - case SUBDEV_PROP_USE_LO_OFFSET: val = false; return; @@ -587,10 +583,6 @@ void xcvr2450::tx_get(const wax::obj &key_, wax::obj &val){ val = true; return; - case SUBDEV_PROP_SPECTRUM_INVERTED: - val = false; - return; - case SUBDEV_PROP_USE_LO_OFFSET: val = false; return; diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp index 1d584913c..dd2985d88 100644 --- a/host/lib/usrp/tune_helper.cpp +++ b/host/lib/usrp/tune_helper.cpp @@ -30,13 +30,12 @@ using namespace uhd::usrp; **********************************************************************/ static bool invert_dxc_freq( bool outside_of_nyquist, - bool subdev_spectrum_inverted, bool subdev_quadrature, dboard_iface::unit_t unit ){ bool is_tx = unit == dboard_iface::UNIT_TX; if (subdev_quadrature) return is_tx; - return outside_of_nyquist xor subdev_spectrum_inverted xor is_tx; + return outside_of_nyquist xor is_tx; } static tune_result_t tune_xx_subdev_and_dxc( @@ -46,7 +45,6 @@ static tune_result_t tune_xx_subdev_and_dxc( ){ wax::obj subdev_freq_proxy = subdev[SUBDEV_PROP_FREQ]; bool subdev_quadrature = subdev[SUBDEV_PROP_QUADRATURE].as(); - bool subdev_spectrum_inverted = subdev[SUBDEV_PROP_SPECTRUM_INVERTED].as(); wax::obj dxc_freq_proxy = dxc[DSP_PROP_FREQ_SHIFT]; double dxc_sample_rate = dxc[DSP_PROP_CODEC_RATE].as(); @@ -63,9 +61,7 @@ static tune_result_t tune_xx_subdev_and_dxc( //invert the sign on the dxc freq given the following conditions bool outside_of_nyquist = std::abs(target_freq - actual_inter_freq) > dxc_sample_rate/2.0; - if (invert_dxc_freq( - outside_of_nyquist, subdev_spectrum_inverted, subdev_quadrature, unit - )) target_dxc_freq *= -1.0; + if (invert_dxc_freq(outside_of_nyquist, subdev_quadrature, unit)) target_dxc_freq *= -1.0; dxc_freq_proxy = target_dxc_freq; double actual_dxc_freq = dxc_freq_proxy.as(); @@ -85,16 +81,13 @@ static double derive_freq_from_xx_subdev_and_dxc( ){ //extract subdev properties bool subdev_quadrature = subdev[SUBDEV_PROP_QUADRATURE].as(); - bool subdev_spectrum_inverted = subdev[SUBDEV_PROP_SPECTRUM_INVERTED].as(); //extract actual dsp and IF frequencies double actual_inter_freq = subdev[SUBDEV_PROP_FREQ].as(); double actual_dxc_freq = dxc[DSP_PROP_FREQ_SHIFT].as(); //invert the sign on the dxc freq given the following conditions - if (invert_dxc_freq( - false, subdev_spectrum_inverted, subdev_quadrature, unit - )) actual_dxc_freq *= -1.0; + if (invert_dxc_freq(false, subdev_quadrature, unit)) actual_dxc_freq *= -1.0; return actual_inter_freq - actual_dxc_freq; } diff --git a/host/test/tune_helper_test.cpp b/host/test/tune_helper_test.cpp index 47b47beda..a6e6f4cc9 100644 --- a/host/test/tune_helper_test.cpp +++ b/host/test/tune_helper_test.cpp @@ -29,9 +29,8 @@ using namespace uhd::usrp; **********************************************************************/ class dummy_subdev : public wax::obj{ public: - dummy_subdev(bool is_quadrature, bool is_spectrum_inverted, double resolution): + dummy_subdev(bool is_quadrature, double resolution): _is_quadrature(is_quadrature), - _is_spectrum_inverted(is_spectrum_inverted), _resolution(resolution) { /* NOP */ @@ -43,10 +42,6 @@ private: val = _is_quadrature; return; - case SUBDEV_PROP_SPECTRUM_INVERTED: - val = _is_spectrum_inverted; - return; - case SUBDEV_PROP_FREQ: val = _freq; return; @@ -69,7 +64,7 @@ private: } } - bool _is_quadrature, _is_spectrum_inverted; + bool _is_quadrature; double _freq, _resolution; }; @@ -114,7 +109,7 @@ private: static const double tolerance = 0.001; BOOST_AUTO_TEST_CASE(test_tune_helper_rx){ - dummy_subdev subdev(true, false, 1e6); + dummy_subdev subdev(true, 1e6); dummy_dsp dsp(100e6); std::cout << "Testing tune helper RX automatic LO offset" << std::endl; @@ -128,7 +123,7 @@ BOOST_AUTO_TEST_CASE(test_tune_helper_rx){ } BOOST_AUTO_TEST_CASE(test_tune_helper_tx){ - dummy_subdev subdev(true, false, 1e6); + dummy_subdev subdev(true, 1e6); dummy_dsp dsp(100e6); std::cout << "Testing tune helper TX automatic LO offset" << std::endl; diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp index 1e8e726d2..611c6919d 100644 --- a/host/utils/uhd_usrp_probe.cpp +++ b/host/utils/uhd_usrp_probe.cpp @@ -90,7 +90,6 @@ static std::string get_subdev_pp_string(const std::string &type, wax::obj subdev ss << boost::format("Is Quadrature: %s") % (subdev[usrp::SUBDEV_PROP_QUADRATURE].as()? "Yes" : "No") << std::endl; ss << boost::format("Is IQ Swapped: %s") % (subdev[usrp::SUBDEV_PROP_IQ_SWAPPED].as()? "Yes" : "No") << std::endl; - ss << boost::format("Is Spectrum Inverted: %s") % (subdev[usrp::SUBDEV_PROP_SPECTRUM_INVERTED].as()? "Yes" : "No") << std::endl; ss << boost::format("Uses LO offset: %s") % (subdev[usrp::SUBDEV_PROP_USE_LO_OFFSET].as()? "Yes" : "No") << std::endl; return ss.str(); -- cgit v1.2.3 From 9a9ca6dfad4b81c42f3cda6a44b018358999d701 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 16 Jul 2010 16:43:06 -0700 Subject: uhd: work on tune logic, and subdev connection logic --- host/include/uhd/usrp/subdev_props.hpp | 21 ++++++++++-- host/lib/usrp/dboard/db_basic_and_lf.cpp | 24 +++++++------- host/lib/usrp/dboard/db_rfx.cpp | 16 +++------- host/lib/usrp/dboard/db_unknown.cpp | 16 +++------- host/lib/usrp/dboard/db_wbx.cpp | 16 +++------- host/lib/usrp/dboard/db_xcvr2450.cpp | 16 +++------- host/lib/usrp/dsp_utils.hpp | 40 +++++++++++------------ host/lib/usrp/tune_helper.cpp | 27 ++++------------ host/lib/usrp/usrp2/dboard_impl.cpp | 5 ++- host/test/tune_helper_test.cpp | 55 ++++++++++++++++++++++++++------ host/utils/uhd_usrp_probe.cpp | 3 +- 11 files changed, 121 insertions(+), 118 deletions(-) (limited to 'host/lib/usrp/tune_helper.cpp') diff --git a/host/include/uhd/usrp/subdev_props.hpp b/host/include/uhd/usrp/subdev_props.hpp index cb7027ff1..f7bdcd161 100644 --- a/host/include/uhd/usrp/subdev_props.hpp +++ b/host/include/uhd/usrp/subdev_props.hpp @@ -22,6 +22,22 @@ namespace uhd{ namespace usrp{ + /*! + * Possible subdev connection types: + * + * A complex subdevice is physically connected to both channels, + * which may be connected in one of two ways: IQ or QI (swapped). + * + * A real subdevice is only physically connected one channel, + * either only the I channel or only the Q channel. + */ + enum subdev_conn_t{ + SUBDEV_CONN_COMPLEX_IQ = 'C', + SUBDEV_CONN_COMPLEX_QI = 'c', + SUBDEV_CONN_REAL_I = 'R', + SUBDEV_CONN_REAL_Q = 'r' + }; + /*! * Possible device subdev properties */ @@ -36,8 +52,9 @@ namespace uhd{ namespace usrp{ SUBDEV_PROP_ANTENNA = 'a', //rw, std::string SUBDEV_PROP_ANTENNA_NAMES = 'A', //ro, prop_names_t SUBDEV_PROP_LO_LOCKED = 'L', //ro, bool - SUBDEV_PROP_QUADRATURE = 'q', //ro, bool - SUBDEV_PROP_IQ_SWAPPED = 'i', //ro, bool + SUBDEV_PROP_CONNECTION = 'c', //ro, subdev_conn_t + //SUBDEV_PROP_QUADRATURE = 'q', //ro, bool + //SUBDEV_PROP_IQ_SWAPPED = 'i', //ro, bool SUBDEV_PROP_USE_LO_OFFSET = 'l', //ro, bool SUBDEV_PROP_RSSI = 'R', //ro, float SUBDEV_PROP_BANDWIDTH = 'B' //rw, double diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index b40be9dea..9180828d8 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -16,6 +16,7 @@ // #include +#include #include #include #include @@ -138,13 +139,14 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){ val = prop_names_t(1, ""); //vector of 1 empty string return; - case SUBDEV_PROP_QUADRATURE: - val = (get_subdev_name() == "AB"); //only quadrature in ab mode - return; - - case SUBDEV_PROP_IQ_SWAPPED: - val = false; - return; + case SUBDEV_PROP_CONNECTION:{ + static const uhd::dict name_to_conn = map_list_of + ("A", SUBDEV_CONN_REAL_I) + ("B", SUBDEV_CONN_REAL_Q) + ("AB", SUBDEV_CONN_COMPLEX_IQ) + ; + val = name_to_conn[get_subdev_name()]; + } return; case SUBDEV_PROP_USE_LO_OFFSET: val = false; @@ -233,12 +235,8 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){ val = prop_names_t(1, ""); //vector of 1 empty string return; - case SUBDEV_PROP_QUADRATURE: - val = true; - return; - - case SUBDEV_PROP_IQ_SWAPPED: - val = false; + case SUBDEV_PROP_CONNECTION: + val = SUBDEV_CONN_COMPLEX_IQ; return; case SUBDEV_PROP_USE_LO_OFFSET: diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 9e5fcd6c6..914ca5e19 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -426,12 +426,8 @@ void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ val = rfx_rx_antennas; return; - case SUBDEV_PROP_QUADRATURE: - val = true; - return; - - case SUBDEV_PROP_IQ_SWAPPED: - val = true; + case SUBDEV_PROP_CONNECTION: + val = SUBDEV_CONN_COMPLEX_QI; return; case SUBDEV_PROP_USE_LO_OFFSET: @@ -512,12 +508,8 @@ void rfx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ val = rfx_tx_antennas; return; - case SUBDEV_PROP_QUADRATURE: - val = true; - return; - - case SUBDEV_PROP_IQ_SWAPPED: - val = false; + case SUBDEV_PROP_CONNECTION: + val = SUBDEV_CONN_COMPLEX_IQ; return; case SUBDEV_PROP_USE_LO_OFFSET: diff --git a/host/lib/usrp/dboard/db_unknown.cpp b/host/lib/usrp/dboard/db_unknown.cpp index 8b247c289..9dd9b550b 100644 --- a/host/lib/usrp/dboard/db_unknown.cpp +++ b/host/lib/usrp/dboard/db_unknown.cpp @@ -119,12 +119,8 @@ void unknown_rx::rx_get(const wax::obj &key_, wax::obj &val){ val = prop_names_t(1, ""); //vector of 1 empty string return; - case SUBDEV_PROP_QUADRATURE: - val = false; - return; - - case SUBDEV_PROP_IQ_SWAPPED: - val = false; + case SUBDEV_PROP_CONNECTION: + val = SUBDEV_CONN_COMPLEX_IQ; return; case SUBDEV_PROP_USE_LO_OFFSET: @@ -214,12 +210,8 @@ void unknown_tx::tx_get(const wax::obj &key_, wax::obj &val){ val = prop_names_t(1, ""); //vector of 1 empty string return; - case SUBDEV_PROP_QUADRATURE: - val = true; - return; - - case SUBDEV_PROP_IQ_SWAPPED: - val = false; + case SUBDEV_PROP_CONNECTION: + val = SUBDEV_CONN_COMPLEX_IQ; return; case SUBDEV_PROP_USE_LO_OFFSET: diff --git a/host/lib/usrp/dboard/db_wbx.cpp b/host/lib/usrp/dboard/db_wbx.cpp index 23eb5ca44..3038ce30b 100644 --- a/host/lib/usrp/dboard/db_wbx.cpp +++ b/host/lib/usrp/dboard/db_wbx.cpp @@ -510,12 +510,8 @@ void wbx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ val = wbx_rx_antennas; return; - case SUBDEV_PROP_QUADRATURE: - val = true; - return; - - case SUBDEV_PROP_IQ_SWAPPED: - val = false; + case SUBDEV_PROP_CONNECTION: + val = SUBDEV_CONN_COMPLEX_IQ; return; case SUBDEV_PROP_USE_LO_OFFSET: @@ -600,12 +596,8 @@ void wbx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ val = wbx_tx_antennas; return; - case SUBDEV_PROP_QUADRATURE: - val = true; - return; - - case SUBDEV_PROP_IQ_SWAPPED: - val = false; + case SUBDEV_PROP_CONNECTION: + val = SUBDEV_CONN_COMPLEX_IQ; return; case SUBDEV_PROP_USE_LO_OFFSET: diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index fabf3dffd..2c94bcd2d 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -481,12 +481,8 @@ void xcvr2450::rx_get(const wax::obj &key_, wax::obj &val){ val = xcvr_antennas; return; - case SUBDEV_PROP_QUADRATURE: - val = true; - return; - - case SUBDEV_PROP_IQ_SWAPPED: - val = false; + case SUBDEV_PROP_CONNECTION: + val = SUBDEV_CONN_COMPLEX_IQ; return; case SUBDEV_PROP_USE_LO_OFFSET: @@ -575,12 +571,8 @@ void xcvr2450::tx_get(const wax::obj &key_, wax::obj &val){ val = xcvr_antennas; return; - case SUBDEV_PROP_QUADRATURE: - val = true; - return; - - case SUBDEV_PROP_IQ_SWAPPED: - val = true; + case SUBDEV_PROP_CONNECTION: + val = SUBDEV_CONN_COMPLEX_QI; return; case SUBDEV_PROP_USE_LO_OFFSET: diff --git a/host/lib/usrp/dsp_utils.hpp b/host/lib/usrp/dsp_utils.hpp index 13186f354..2f246c788 100644 --- a/host/lib/usrp/dsp_utils.hpp +++ b/host/lib/usrp/dsp_utils.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -37,37 +38,36 @@ namespace dsp_type1{ /*! * Calculate the rx mux word from properties. - * \param is_quadrature true if the subdev is complex - * \param is_iq_swapped true if the i and q are reversed + * \param subdev_conn the subdev connection type * \param the 32-bit rx mux control word */ static inline boost::uint32_t calc_rx_mux_word( - bool is_quadrature, - bool is_iq_swapped + subdev_conn_t subdev_conn ){ - boost::uint32_t rx_mux = 0; - if (is_quadrature){ - rx_mux = (0x01 << 2) | (0x00 << 0); //Q=ADC1, I=ADC0 - }else{ - rx_mux = (0x11 << 2) | (0x00 << 0); //Q=ZERO, I=ADC0 + switch(subdev_conn){ + case SUBDEV_CONN_COMPLEX_IQ: return (0x1 << 2) | (0x0 << 0); //DDC0Q=ADC1, DDC0I=ADC0 + case SUBDEV_CONN_COMPLEX_QI: return (0x0 << 2) | (0x1 << 0); //DDC0Q=ADC0, DDC0I=ADC1 + case SUBDEV_CONN_REAL_I: return (0x3 << 2) | (0x0 << 0); //DDC0Q=ZERO, DDC0I=ADC0 + case SUBDEV_CONN_REAL_Q: return (0x1 << 2) | (0x3 << 0); //DDC0Q=ADC1, DDC0I=ZERO + default: UHD_THROW_INVALID_CODE_PATH(); } - if (is_iq_swapped){ - rx_mux = (rx_mux << 2) | (rx_mux >> 2); - } - return rx_mux; } /*! * Calculate the tx mux word from properties. - * \param is_iq_swapped true if the i and q are reversed + * \param subdev_conn the subdev connection type * \param the 32-bit tx mux control word */ - static inline boost::uint32_t calc_tx_mux_word(bool is_iq_swapped){ - boost::uint32_t tx_mux = 0x10; - if (is_iq_swapped){ - tx_mux = (tx_mux << 4) | (tx_mux >> 4); + static inline boost::uint32_t calc_tx_mux_word( + subdev_conn_t subdev_conn + ){ + switch(subdev_conn){ + case SUBDEV_CONN_COMPLEX_IQ: return (0x1 << 4) | (0x0 << 0); //DAC1=DUC0Q, DAC0=DUC0I + case SUBDEV_CONN_COMPLEX_QI: return (0x0 << 4) | (0x1 << 0); //DAC1=DUC0I, DAC0=DUC0Q + case SUBDEV_CONN_REAL_I: return (0xf << 4) | (0x0 << 0); //DAC1=ZERO, DAC0=DUC0I + case SUBDEV_CONN_REAL_Q: return (0x0 << 4) | (0xf << 0); //DAC1=DUC0I, DAC0=ZERO + default: UHD_THROW_INVALID_CODE_PATH(); } - return tx_mux; } /*! @@ -82,7 +82,7 @@ namespace dsp_type1{ double &freq, double codec_rate ){ - UHD_ASSERT_THROW(std::abs(freq) < codec_rate/2.0); + UHD_ASSERT_THROW(freq >= -codec_rate/2.0 and freq < codec_rate/2.0); static const double scale_factor = std::pow(2.0, 32); //calculate the freq register word (signed) diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp index dd2985d88..c5cce3ecf 100644 --- a/host/lib/usrp/tune_helper.cpp +++ b/host/lib/usrp/tune_helper.cpp @@ -28,23 +28,12 @@ using namespace uhd::usrp; /*********************************************************************** * Tune Helper Functions **********************************************************************/ -static bool invert_dxc_freq( - bool outside_of_nyquist, - bool subdev_quadrature, - dboard_iface::unit_t unit -){ - bool is_tx = unit == dboard_iface::UNIT_TX; - if (subdev_quadrature) return is_tx; - return outside_of_nyquist xor is_tx; -} - static tune_result_t tune_xx_subdev_and_dxc( dboard_iface::unit_t unit, wax::obj subdev, wax::obj dxc, double target_freq, double lo_offset ){ wax::obj subdev_freq_proxy = subdev[SUBDEV_PROP_FREQ]; - bool subdev_quadrature = subdev[SUBDEV_PROP_QUADRATURE].as(); wax::obj dxc_freq_proxy = dxc[DSP_PROP_FREQ_SHIFT]; double dxc_sample_rate = dxc[DSP_PROP_CODEC_RATE].as(); @@ -54,14 +43,13 @@ static tune_result_t tune_xx_subdev_and_dxc( double actual_inter_freq = subdev_freq_proxy.as(); //perform the correction correction for dxc rates outside of nyquist - double target_dxc_freq = std::fmod(target_freq - actual_inter_freq, dxc_sample_rate); - if (target_dxc_freq >= dxc_sample_rate/2.0) target_dxc_freq -= dxc_sample_rate; - else if (target_dxc_freq < -dxc_sample_rate/2.0) target_dxc_freq += dxc_sample_rate; - else target_dxc_freq *= -1.0; + double delta_freq = std::fmod(target_freq - actual_inter_freq, dxc_sample_rate); + bool outside_of_nyquist = std::abs(delta_freq) > dxc_sample_rate/2.0; + double target_dxc_freq = (outside_of_nyquist)? + std::signum(delta_freq)*dxc_sample_rate - delta_freq : -delta_freq; //invert the sign on the dxc freq given the following conditions - bool outside_of_nyquist = std::abs(target_freq - actual_inter_freq) > dxc_sample_rate/2.0; - if (invert_dxc_freq(outside_of_nyquist, subdev_quadrature, unit)) target_dxc_freq *= -1.0; + if (unit == dboard_iface::UNIT_TX) target_dxc_freq *= -1.0; dxc_freq_proxy = target_dxc_freq; double actual_dxc_freq = dxc_freq_proxy.as(); @@ -79,15 +67,12 @@ static double derive_freq_from_xx_subdev_and_dxc( dboard_iface::unit_t unit, wax::obj subdev, wax::obj dxc ){ - //extract subdev properties - bool subdev_quadrature = subdev[SUBDEV_PROP_QUADRATURE].as(); - //extract actual dsp and IF frequencies double actual_inter_freq = subdev[SUBDEV_PROP_FREQ].as(); double actual_dxc_freq = dxc[DSP_PROP_FREQ_SHIFT].as(); //invert the sign on the dxc freq given the following conditions - if (invert_dxc_freq(false, subdev_quadrature, unit)) actual_dxc_freq *= -1.0; + if (unit == dboard_iface::UNIT_TX) actual_dxc_freq *= -1.0; return actual_inter_freq - actual_dxc_freq; } diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index fa8d1a674..8942f9d31 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -104,8 +104,7 @@ void usrp2_mboard_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ wax::obj rx_subdev = _dboard_manager->get_rx_subdev(_rx_subdevs_in_use.at(0)); std::cout << "Using: " << rx_subdev[SUBDEV_PROP_NAME].as() << std::endl; _iface->poke32(U2_REG_DSP_RX_MUX, dsp_type1::calc_rx_mux_word( - rx_subdev[SUBDEV_PROP_QUADRATURE].as(), - rx_subdev[SUBDEV_PROP_IQ_SWAPPED].as() + rx_subdev[SUBDEV_PROP_CONNECTION].as() )); } return; @@ -164,7 +163,7 @@ void usrp2_mboard_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){ wax::obj tx_subdev = _dboard_manager->get_tx_subdev(_tx_subdevs_in_use.at(0)); std::cout << "Using: " << tx_subdev[SUBDEV_PROP_NAME].as() << std::endl; _iface->poke32(U2_REG_DSP_TX_MUX, dsp_type1::calc_tx_mux_word( - tx_subdev[SUBDEV_PROP_IQ_SWAPPED].as() + tx_subdev[SUBDEV_PROP_CONNECTION].as() )); } return; diff --git a/host/test/tune_helper_test.cpp b/host/test/tune_helper_test.cpp index a6e6f4cc9..3df1f2471 100644 --- a/host/test/tune_helper_test.cpp +++ b/host/test/tune_helper_test.cpp @@ -29,8 +29,7 @@ using namespace uhd::usrp; **********************************************************************/ class dummy_subdev : public wax::obj{ public: - dummy_subdev(bool is_quadrature, double resolution): - _is_quadrature(is_quadrature), + dummy_subdev(double resolution): _resolution(resolution) { /* NOP */ @@ -38,9 +37,6 @@ public: private: void get(const wax::obj &key, wax::obj &val){ switch(key.as()){ - case SUBDEV_PROP_QUADRATURE: - val = _is_quadrature; - return; case SUBDEV_PROP_FREQ: val = _freq; @@ -64,10 +60,37 @@ private: } } - bool _is_quadrature; double _freq, _resolution; }; +class dummy_subdev_basic : public wax::obj{ +private: + void get(const wax::obj &key, wax::obj &val){ + switch(key.as()){ + + case SUBDEV_PROP_FREQ: + val = double(0.0); //always zero + return; + + case SUBDEV_PROP_USE_LO_OFFSET: + val = false; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } + } + + void set(const wax::obj &key, const wax::obj &){ + switch(key.as()){ + case SUBDEV_PROP_FREQ: + // do nothing + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } + } +}; + class dummy_dsp : public wax::obj{ public: dummy_dsp(double codec_rate): @@ -104,12 +127,12 @@ private: }; /*********************************************************************** - * Tests + * Test cases **********************************************************************/ static const double tolerance = 0.001; BOOST_AUTO_TEST_CASE(test_tune_helper_rx){ - dummy_subdev subdev(true, 1e6); + dummy_subdev subdev(1e6); dummy_dsp dsp(100e6); std::cout << "Testing tune helper RX automatic LO offset" << std::endl; @@ -123,7 +146,7 @@ BOOST_AUTO_TEST_CASE(test_tune_helper_rx){ } BOOST_AUTO_TEST_CASE(test_tune_helper_tx){ - dummy_subdev subdev(true, 1e6); + dummy_subdev subdev(1e6); dummy_dsp dsp(100e6); std::cout << "Testing tune helper TX automatic LO offset" << std::endl; @@ -135,3 +158,17 @@ BOOST_AUTO_TEST_CASE(test_tune_helper_tx){ double freq_derived = derive_freq_from_tx_subdev_and_dsp(subdev.get_link(), dsp.get_link()); BOOST_CHECK_CLOSE(freq_derived, 2.3451e9, tolerance); } + +BOOST_AUTO_TEST_CASE(test_tune_helper_rx_nyquist){ + dummy_subdev_basic subdev; + dummy_dsp dsp(100e6); + + std::cout << "Testing tune helper RX dummy basic board" << std::endl; + tune_result_t tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 55e6); + std::cout << tr.to_pp_string() << std::endl; + BOOST_CHECK_CLOSE(tr.actual_inter_freq, 0, tolerance); + BOOST_CHECK_CLOSE(tr.actual_dsp_freq, 45e6, tolerance); + + double freq_derived = derive_freq_from_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link()); + BOOST_CHECK_CLOSE(freq_derived, -45e6, tolerance); +} diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp index 611c6919d..1b73b5788 100644 --- a/host/utils/uhd_usrp_probe.cpp +++ b/host/utils/uhd_usrp_probe.cpp @@ -88,8 +88,7 @@ static std::string get_subdev_pp_string(const std::string &type, wax::obj subdev ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % gain_name % gain_range.min % gain_range.max % gain_range.step << std::endl; } - ss << boost::format("Is Quadrature: %s") % (subdev[usrp::SUBDEV_PROP_QUADRATURE].as()? "Yes" : "No") << std::endl; - ss << boost::format("Is IQ Swapped: %s") % (subdev[usrp::SUBDEV_PROP_IQ_SWAPPED].as()? "Yes" : "No") << std::endl; + ss << boost::format("Connection Type: %c") % (subdev[usrp::SUBDEV_PROP_CONNECTION].as()) << std::endl; ss << boost::format("Uses LO offset: %s") % (subdev[usrp::SUBDEV_PROP_USE_LO_OFFSET].as()? "Yes" : "No") << std::endl; return ss.str(); -- cgit v1.2.3 From 1e2f457ee118f55d753a4c124315ab17f8eb5f1b Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 22 Jul 2010 23:27:57 -0700 Subject: usrp: fix the N/2 cordic tune issue, use boost math sign inplace of my signum --- host/include/uhd/utils/algorithm.hpp | 11 ----------- host/lib/usrp/dsp_utils.hpp | 4 ++-- host/lib/usrp/tune_helper.cpp | 4 ++-- 3 files changed, 4 insertions(+), 15 deletions(-) (limited to 'host/lib/usrp/tune_helper.cpp') diff --git a/host/include/uhd/utils/algorithm.hpp b/host/include/uhd/utils/algorithm.hpp index b52edc6b5..54bc78494 100644 --- a/host/include/uhd/utils/algorithm.hpp +++ b/host/include/uhd/utils/algorithm.hpp @@ -111,17 +111,6 @@ namespace std{ std::equal(boost::begin(range1), boost::end(range1), boost::begin(range2)); } - /*! - * A templated signum implementation. - * \param n the comparable to process - * \return -1 when n negative, +1 when n positive, otherwise 0 - */ - template inline int signum(T n){ - if (n < 0) return -1; - if (n > 0) return +1; - return 0; - } - /*! * A templated clip implementation. * \param val the value to clip between an upper and lower limit diff --git a/host/lib/usrp/dsp_utils.hpp b/host/lib/usrp/dsp_utils.hpp index 2f246c788..ebed12c41 100644 --- a/host/lib/usrp/dsp_utils.hpp +++ b/host/lib/usrp/dsp_utils.hpp @@ -82,11 +82,11 @@ namespace dsp_type1{ double &freq, double codec_rate ){ - UHD_ASSERT_THROW(freq >= -codec_rate/2.0 and freq < codec_rate/2.0); + UHD_ASSERT_THROW(std::abs(freq) <= codec_rate/2.0); static const double scale_factor = std::pow(2.0, 32); //calculate the freq register word (signed) - boost::int32_t freq_word = boost::math::iround((freq / codec_rate) * scale_factor); + boost::int32_t freq_word = boost::int32_t(boost::math::round((freq / codec_rate) * scale_factor)); //update the actual frequency freq = (double(freq_word) / scale_factor) * codec_rate; diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp index c5cce3ecf..e516477d3 100644 --- a/host/lib/usrp/tune_helper.cpp +++ b/host/lib/usrp/tune_helper.cpp @@ -16,10 +16,10 @@ // #include -#include #include #include #include //unit_t +#include #include using namespace uhd; @@ -46,7 +46,7 @@ static tune_result_t tune_xx_subdev_and_dxc( double delta_freq = std::fmod(target_freq - actual_inter_freq, dxc_sample_rate); bool outside_of_nyquist = std::abs(delta_freq) > dxc_sample_rate/2.0; double target_dxc_freq = (outside_of_nyquist)? - std::signum(delta_freq)*dxc_sample_rate - delta_freq : -delta_freq; + boost::math::sign(delta_freq)*dxc_sample_rate - delta_freq : -delta_freq; //invert the sign on the dxc freq given the following conditions if (unit == dboard_iface::UNIT_TX) target_dxc_freq *= -1.0; -- cgit v1.2.3