// // 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 . // #include #include #include #include #include using namespace uhd; using namespace uhd::usrp; /*********************************************************************** * Dummy properties objects **********************************************************************/ class dummy_subdev : public wax::obj{ public: dummy_subdev(double resolution): _resolution(resolution) { /* NOP */ } private: void get(const wax::obj &key, wax::obj &val){ switch(key.as()){ case SUBDEV_PROP_FREQ: val = _freq; 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 &val){ switch(key.as()){ case SUBDEV_PROP_FREQ: _freq = _resolution*int(val.as()/_resolution); return; default: UHD_THROW_PROP_SET_ERROR(); } } 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): _codec_rate(codec_rate) { /* NOP */ } private: void get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ case DSP_PROP_CODEC_RATE: val = _codec_rate; return; case DSP_PROP_FREQ_SHIFT: val = _freq_shift; return; case DSP_PROP_FREQ_SHIFT_NAMES: val = prop_names_t(1, ""); return; default: UHD_THROW_PROP_GET_ERROR(); } } void set(const wax::obj &key_, const wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ case DSP_PROP_FREQ_SHIFT: _freq_shift = val.as(); return; default: UHD_THROW_PROP_SET_ERROR(); } } double _codec_rate, _freq_shift; }; /*********************************************************************** * Test cases **********************************************************************/ static const double tolerance = 0.001; BOOST_AUTO_TEST_CASE(test_tune_helper_rx){ dummy_subdev subdev(1e6); dummy_dsp dsp(100e6); std::cout << "Testing tune helper RX automatic LO offset" << std::endl; tune_result_t tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.3451e9); std::cout << tr.to_pp_string() << std::endl; BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.345e9, tolerance); BOOST_CHECK_CLOSE(tr.actual_dsp_freq, -100e3, tolerance); double freq_derived = derive_freq_from_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0); BOOST_CHECK_CLOSE(freq_derived, 2.3451e9, tolerance); } BOOST_AUTO_TEST_CASE(test_tune_helper_tx){ dummy_subdev subdev(1e6); dummy_dsp dsp(100e6); std::cout << "Testing tune helper TX automatic LO offset" << std::endl; tune_result_t tr = tune_tx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.3451e9); std::cout << tr.to_pp_string() << std::endl; BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.345e9, tolerance); BOOST_CHECK_CLOSE(tr.actual_dsp_freq, 100e3, tolerance); double freq_derived = derive_freq_from_tx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0); 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(), 0, 55e6); std::cout << tr.to_pp_string() << std::endl; BOOST_CHECK_CLOSE(tr.actual_inter_freq, 0.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(), 0); BOOST_CHECK_CLOSE(freq_derived, -45e6, tolerance); }