diff options
author | Josh Blum <josh@joshknows.com> | 2010-04-05 14:37:21 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2010-04-05 14:37:21 -0700 |
commit | 1cc8c6c964d4368d9e918e4cb357600453a24c94 (patch) | |
tree | 145cea809ec723f006ad384d267ddb6d9eccd249 /host/lib/usrp | |
parent | 12aa8ad74cf3a343159ddbb452455bf4e7f435b8 (diff) | |
download | uhd-1cc8c6c964d4368d9e918e4cb357600453a24c94.tar.gz uhd-1cc8c6c964d4368d9e918e4cb357600453a24c94.tar.bz2 uhd-1cc8c6c964d4368d9e918e4cb357600453a24c94.zip |
paradigm shift for the dsp abstraction
Diffstat (limited to 'host/lib/usrp')
-rw-r--r-- | host/lib/usrp/dboard/db_basic_and_lf.cpp | 8 | ||||
-rw-r--r-- | host/lib/usrp/simple_usrp.cpp | 46 | ||||
-rw-r--r-- | host/lib/usrp/tune_helper.cpp | 13 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/dsp_impl.cpp | 250 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 62 |
5 files changed, 148 insertions, 231 deletions
diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index be4e646ed..930646f76 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -150,7 +150,7 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){ case SUBDEV_PROP_IQ_SWAPPED: case SUBDEV_PROP_SPECTRUM_INVERTED: - case SUBDEV_PROP_LO_INTERFERES: + case SUBDEV_PROP_USE_LO_OFFSET: val = false; return; } @@ -186,7 +186,7 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){ case SUBDEV_PROP_QUADRATURE: case SUBDEV_PROP_IQ_SWAPPED: case SUBDEV_PROP_SPECTRUM_INVERTED: - case SUBDEV_PROP_LO_INTERFERES: + case SUBDEV_PROP_USE_LO_OFFSET: throw std::runtime_error(str(boost::format( "Error: trying to set read-only property on %s subdev" ) % dboard_id::to_string(get_rx_id()))); @@ -258,7 +258,7 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){ case SUBDEV_PROP_IQ_SWAPPED: case SUBDEV_PROP_SPECTRUM_INVERTED: - case SUBDEV_PROP_LO_INTERFERES: + case SUBDEV_PROP_USE_LO_OFFSET: val = false; return; } @@ -294,7 +294,7 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){ case SUBDEV_PROP_QUADRATURE: case SUBDEV_PROP_IQ_SWAPPED: case SUBDEV_PROP_SPECTRUM_INVERTED: - case SUBDEV_PROP_LO_INTERFERES: + case SUBDEV_PROP_USE_LO_OFFSET: throw std::runtime_error(str(boost::format( "Error: trying to set read-only property on %s subdev" ) % dboard_id::to_string(get_tx_id()))); diff --git a/host/lib/usrp/simple_usrp.cpp b/host/lib/usrp/simple_usrp.cpp index a0551a630..bd8bac00f 100644 --- a/host/lib/usrp/simple_usrp.cpp +++ b/host/lib/usrp/simple_usrp.cpp @@ -22,6 +22,7 @@ #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/foreach.hpp> #include <boost/format.hpp> #include <stdexcept> @@ -30,17 +31,6 @@ using namespace uhd; using namespace uhd::usrp; /*********************************************************************** - * Helper Functions - **********************************************************************/ -static std::vector<double> get_xx_rates(wax::obj decerps, wax::obj rate){ - std::vector<double> rates; - BOOST_FOREACH(size_t decerp, decerps.as<std::vector<size_t> >()){ - rates.push_back(rate.as<double>()/decerp); - } - return rates; -} - -/*********************************************************************** * Simple Device Implementation **********************************************************************/ class simple_usrp_impl : public simple_usrp{ @@ -48,8 +38,8 @@ public: simple_usrp_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_dsp = _mboard[named_prop_t(MBOARD_PROP_RX_DSP, "ddc0")]; //FIX string crap + _tx_dsp = _mboard[named_prop_t(MBOARD_PROP_TX_DSP, "duc0")]; //FIX string crap //extract rx subdevice wax::obj rx_dboard = _mboard[MBOARD_PROP_RX_DBOARD]; @@ -86,7 +76,7 @@ public: } void issue_stream_cmd(const stream_cmd_t &stream_cmd){ - _rx_ddc[std::string("stream_cmd")] = stream_cmd; + _mboard[MBOARD_PROP_STREAM_CMD] = stream_cmd; } void set_clock_config(const clock_config_t &clock_config){ @@ -101,21 +91,15 @@ public: * RX methods ******************************************************************/ void set_rx_rate(double rate){ - double samp_rate = _rx_ddc[std::string("if_rate")].as<double>(); - assert_has(get_rx_rates(), rate, "simple device rx rate"); - _rx_ddc[std::string("decim")] = size_t(samp_rate/rate); + _rx_dsp[DSP_PROP_HOST_RATE] = rate; } double get_rx_rate(void){ - return _rx_ddc[std::string("bb_rate")].as<double>(); - } - - std::vector<double> get_rx_rates(void){ - return get_xx_rates(_rx_ddc[std::string("decims")], _rx_ddc[std::string("if_rate")]); + return _rx_dsp[DSP_PROP_HOST_RATE].as<double>(); } tune_result_t set_rx_freq(double target_freq){ - return tune_rx_subdev_and_ddc(_rx_subdev, _rx_ddc, target_freq); + return tune_rx_subdev_and_ddc(_rx_subdev, _rx_dsp, target_freq); } freq_range_t get_rx_freq_range(void){ @@ -150,21 +134,15 @@ public: * TX methods ******************************************************************/ void set_tx_rate(double rate){ - double samp_rate = _tx_duc[std::string("if_rate")].as<double>(); - assert_has(get_tx_rates(), rate, "simple device tx rate"); - _tx_duc[std::string("interp")] = size_t(samp_rate/rate); + _tx_dsp[DSP_PROP_HOST_RATE] = rate; } double get_tx_rate(void){ - return _tx_duc[std::string("bb_rate")].as<double>(); - } - - std::vector<double> get_tx_rates(void){ - return get_xx_rates(_tx_duc[std::string("interps")], _tx_duc[std::string("if_rate")]); + return _tx_dsp[DSP_PROP_HOST_RATE].as<double>(); } tune_result_t set_tx_freq(double target_freq){ - return tune_tx_subdev_and_duc(_tx_subdev, _tx_duc, target_freq); + return tune_tx_subdev_and_duc(_tx_subdev, _tx_dsp, target_freq); } freq_range_t get_tx_freq_range(void){ @@ -198,8 +176,8 @@ public: private: device::sptr _dev; wax::obj _mboard; - wax::obj _rx_ddc; - wax::obj _tx_duc; + wax::obj _rx_dsp; + wax::obj _tx_dsp; wax::obj _rx_subdev; wax::obj _tx_subdev; }; diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp index 79a6aff7b..2fb15064c 100644 --- a/host/lib/usrp/tune_helper.cpp +++ b/host/lib/usrp/tune_helper.cpp @@ -18,6 +18,7 @@ #include <uhd/usrp/tune_helper.hpp> #include <uhd/utils/algorithm.hpp> #include <uhd/usrp/subdev_props.hpp> +#include <uhd/usrp/dsp_props.hpp> #include <cmath> using namespace uhd; @@ -34,8 +35,8 @@ 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>(); bool subdev_spectrum_inverted = subdev[SUBDEV_PROP_SPECTRUM_INVERTED].as<bool>(); - wax::obj dxc_freq_proxy = dxc[std::string("freq")]; - double dxc_sample_rate = dxc[std::string("if_rate")].as<double>(); + wax::obj dxc_freq_proxy = dxc[DSP_PROP_FREQ_SHIFT]; + double dxc_sample_rate = dxc[DSP_PROP_CODEC_RATE].as<double>(); // Ask the d'board to tune as closely as it can to target_freq+lo_offset double target_inter_freq = target_freq + lo_offset; @@ -96,8 +97,8 @@ tune_result_t uhd::usrp::tune_rx_subdev_and_ddc( ){ double lo_offset = 0.0; //if the local oscillator will be in the passband, use an offset - if (subdev[SUBDEV_PROP_LO_INTERFERES].as<bool>()){ - lo_offset = 2.0*ddc[std::string("bb_rate")].as<double>(); + if (subdev[SUBDEV_PROP_USE_LO_OFFSET].as<bool>()){ + lo_offset = 2.0*ddc[DSP_PROP_HOST_RATE].as<double>(); } return tune_rx_subdev_and_ddc(subdev, ddc, target_freq, lo_offset); } @@ -119,8 +120,8 @@ tune_result_t uhd::usrp::tune_tx_subdev_and_duc( ){ double lo_offset = 0.0; //if the local oscillator will be in the passband, use an offset - if (subdev[SUBDEV_PROP_LO_INTERFERES].as<bool>()){ - lo_offset = 2.0*duc[std::string("bb_rate")].as<double>(); + if (subdev[SUBDEV_PROP_USE_LO_OFFSET].as<bool>()){ + lo_offset = 2.0*duc[DSP_PROP_HOST_RATE].as<double>(); } return tune_tx_subdev_and_duc(subdev, duc, target_freq, lo_offset); } diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index 1fe7b7f25..559ea38d8 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -54,6 +54,16 @@ static boost::uint32_t calculate_iq_scale_word(boost::int16_t i, boost::int16_t return (boost::uint16_t(i) << 16) | (boost::uint16_t(q) << 0); } +template <class rate_t> static rate_t +pick_closest_rate(double exact_rate, const std::vector<rate_t> &rates){ + rate_t closest_match = rates.at(0); + BOOST_FOREACH(rate_t possible_rate, rates){ + if(std::abs(exact_rate - possible_rate) < std::abs(exact_rate - closest_match)) + closest_match = possible_rate; + } + return closest_match; +} + void usrp2_impl::init_ddc_config(void){ //create the ddc in the rx dsp dict _rx_dsps["ddc0"] = wax_obj_proxy::make( @@ -81,128 +91,57 @@ void usrp2_impl::update_ddc_config(void){ ); } -void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ - //setup the out data - usrp2_ctrl_data_t out_data; - out_data.id = htonl(USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO); - out_data.data.stream_cmd.now = (stream_cmd.stream_now)? 1 : 0; - out_data.data.stream_cmd.secs = htonl(stream_cmd.time_spec.secs); - out_data.data.stream_cmd.ticks = htonl(stream_cmd.time_spec.ticks); - - //set these to defaults, then change in the switch statement - out_data.data.stream_cmd.continuous = 0; - out_data.data.stream_cmd.chain = 0; - out_data.data.stream_cmd.num_samps = htonl(stream_cmd.num_samps); - - //setup chain, num samps, and continuous below - switch(stream_cmd.stream_mode){ - case stream_cmd_t::STREAM_MODE_START_CONTINUOUS: - out_data.data.stream_cmd.continuous = 1; - break; - - case stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS: - out_data.data.stream_cmd.num_samps = htonl(0); - break; - - case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE: - //all set by defaults above - break; - - case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE: - out_data.data.stream_cmd.chain = 1; - break; - } - - //send and recv - usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); - ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE); -} - /*********************************************************************** * DDC Properties **********************************************************************/ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){ - //handle the case where the key is an expected dsp property - if (key.type() == typeid(dsp_prop_t)){ - switch(key.as<dsp_prop_t>()){ - case DSP_PROP_NAME: - val = std::string("usrp2 ddc0"); - return; - - case DSP_PROP_OTHERS:{ - prop_names_t others = boost::assign::list_of - ("if_rate") - ("bb_rate") - ("decim") - ("decims") - ("freq") - ("stream_cmd") - ; - val = others; - } - return; - } - } - - //handle string-based properties specific to this dsp - std::string key_name = key.as<std::string>(); - if (key_name == "if_rate"){ - val = get_master_clock_freq(); + switch(key.as<dsp_prop_t>()){ + case DSP_PROP_NAME: + val = std::string("usrp2 ddc0"); return; - } - else if (key_name == "bb_rate"){ - val = get_master_clock_freq()/_ddc_decim; + + case DSP_PROP_OTHERS: + val = prop_names_t(); //empty return; - } - else if (key_name == "decim"){ - val = _ddc_decim; + + case DSP_PROP_FREQ_SHIFT: + val = _ddc_freq; return; - } - else if (key_name == "decims"){ - val = _allowed_decim_and_interp_rates; + + case DSP_PROP_CODEC_RATE: + val = get_master_clock_freq(); return; - } - else if (key_name == "freq"){ - val = _ddc_freq; + + case DSP_PROP_HOST_RATE: + val = get_master_clock_freq()/_ddc_decim; return; } - - throw std::invalid_argument(str( - boost::format("error getting: unknown key with name %s") % key_name - )); } void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val){ - //handle string-based properties specific to this dsp - std::string key_name = key.as<std::string>(); - if (key_name == "decim"){ - size_t new_decim = val.as<size_t>(); - assert_has( - _allowed_decim_and_interp_rates, - new_decim, "usrp2 decimation" - ); - _ddc_decim = new_decim; //shadow - update_ddc_config(); - return; - } - else if (key_name == "freq"){ - double new_freq = val.as<double>(); - ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0); - ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0); - _ddc_freq = new_freq; //shadow - this->poke32(FR_DSP_RX_FREQ, - calculate_freq_word_and_update_actual_freq(_ddc_freq, get_master_clock_freq()) - ); + switch(key.as<dsp_prop_t>()){ + + case DSP_PROP_FREQ_SHIFT:{ + double new_freq = val.as<double>(); + ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0); + ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0); + _ddc_freq = new_freq; //shadow + this->poke32(FR_DSP_RX_FREQ, + calculate_freq_word_and_update_actual_freq(_ddc_freq, get_master_clock_freq()) + ); + } return; - } - else if (key_name == "stream_cmd"){ - issue_ddc_stream_cmd(val.as<stream_cmd_t>()); + + case DSP_PROP_HOST_RATE:{ + double extact_rate = get_master_clock_freq()/val.as<double>(); + _ddc_decim = pick_closest_rate(extact_rate, _allowed_decim_and_interp_rates); + update_ddc_config(); + } return; - } - throw std::invalid_argument(str( - boost::format("error setting: unknown key with name %s") % key_name - )); + default: + throw std::runtime_error("Error: trying to set read-only property on usrp2 ddc0"); + } } /*********************************************************************** @@ -241,80 +180,51 @@ void usrp2_impl::update_duc_config(void){ * DUC Properties **********************************************************************/ void usrp2_impl::duc_get(const wax::obj &key, wax::obj &val){ - //handle the case where the key is an expected dsp property - if (key.type() == typeid(dsp_prop_t)){ - switch(key.as<dsp_prop_t>()){ - case DSP_PROP_NAME: - val = std::string("usrp2 duc0"); - return; - - case DSP_PROP_OTHERS:{ - prop_names_t others = boost::assign::list_of - ("if_rate") - ("bb_rate") - ("interp") - ("interps") - ("freq") - ; - val = others; - } - return; - } - } - - //handle string-based properties specific to this dsp - std::string key_name = key.as<std::string>(); - if (key_name == "if_rate"){ - val = get_master_clock_freq(); + switch(key.as<dsp_prop_t>()){ + case DSP_PROP_NAME: + val = std::string("usrp2 duc0"); return; - } - else if (key_name == "bb_rate"){ - val = get_master_clock_freq()/_duc_interp; + + case DSP_PROP_OTHERS: + val = prop_names_t(); //empty return; - } - else if (key_name == "interp"){ - val = _duc_interp; + + case DSP_PROP_FREQ_SHIFT: + val = _duc_freq; return; - } - else if (key_name == "interps"){ - val = _allowed_decim_and_interp_rates; + + case DSP_PROP_CODEC_RATE: + val = get_master_clock_freq(); return; - } - else if (key_name == "freq"){ - val = _duc_freq; + + case DSP_PROP_HOST_RATE: + val = get_master_clock_freq()/_duc_interp; return; } - - throw std::invalid_argument(str( - boost::format("error getting: unknown key with name %s") % key_name - )); } void usrp2_impl::duc_set(const wax::obj &key, const wax::obj &val){ - //handle string-based properties specific to this dsp - std::string key_name = key.as<std::string>(); - if (key_name == "interp"){ - size_t new_interp = val.as<size_t>(); - assert_has( - _allowed_decim_and_interp_rates, - new_interp, "usrp2 interpolation" - ); - _duc_interp = new_interp; //shadow - update_duc_config(); + switch(key.as<dsp_prop_t>()){ + + case DSP_PROP_FREQ_SHIFT:{ + double new_freq = val.as<double>(); + ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0); + ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0); + _duc_freq = new_freq; //shadow + this->poke32(FR_DSP_TX_FREQ, + calculate_freq_word_and_update_actual_freq(_duc_freq, get_master_clock_freq()) + ); + } return; - } - else if (key_name == "freq"){ - double new_freq = val.as<double>(); - ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0); - ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0); - _duc_freq = new_freq; //shadow - this->poke32(FR_DSP_TX_FREQ, - calculate_freq_word_and_update_actual_freq(_duc_freq, get_master_clock_freq()) - ); + + case DSP_PROP_HOST_RATE:{ + double extact_rate = get_master_clock_freq()/val.as<double>(); + _duc_interp = pick_closest_rate(extact_rate, _allowed_decim_and_interp_rates); + update_duc_config(); + } return; - } - throw std::invalid_argument(str( - boost::format("error setting: unknown key with name %s") % key_name - )); + default: + throw std::runtime_error("Error: trying to set read-only property on usrp2 duc0"); + } } diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index ceb2ec98f..0891f9dc8 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -82,6 +82,43 @@ void usrp2_impl::set_time_spec(const time_spec_t &time_spec, bool now){ this->poke32(FR_TIME64_IMM, imm_flags); } +void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO); + out_data.data.stream_cmd.now = (stream_cmd.stream_now)? 1 : 0; + out_data.data.stream_cmd.secs = htonl(stream_cmd.time_spec.secs); + out_data.data.stream_cmd.ticks = htonl(stream_cmd.time_spec.ticks); + + //set these to defaults, then change in the switch statement + out_data.data.stream_cmd.continuous = 0; + out_data.data.stream_cmd.chain = 0; + out_data.data.stream_cmd.num_samps = htonl(stream_cmd.num_samps); + + //setup chain, num samps, and continuous below + switch(stream_cmd.stream_mode){ + case stream_cmd_t::STREAM_MODE_START_CONTINUOUS: + out_data.data.stream_cmd.continuous = 1; + break; + + case stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS: + out_data.data.stream_cmd.num_samps = htonl(0); + break; + + case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE: + //all set by defaults above + break; + + case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE: + out_data.data.stream_cmd.chain = 1; + break; + } + + //send and recv + usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); + ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE); +} + /*********************************************************************** * MBoard Get Properties **********************************************************************/ @@ -179,8 +216,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ val = _clock_config; return; - case MBOARD_PROP_TIME_NOW: - case MBOARD_PROP_TIME_NEXT_PPS: + default: throw std::runtime_error("Error: trying to get write-only property on usrp2 mboard"); } @@ -226,27 +262,19 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){ update_clock_config(); return; - case MBOARD_PROP_TIME_NOW:{ + case MBOARD_PROP_TIME_NOW: set_time_spec(val.as<time_spec_t>(), true); return; - } - case MBOARD_PROP_TIME_NEXT_PPS:{ + case MBOARD_PROP_TIME_NEXT_PPS: set_time_spec(val.as<time_spec_t>(), false); return; - } - case MBOARD_PROP_NAME: - case MBOARD_PROP_OTHERS: - case MBOARD_PROP_CLOCK_RATE: - case MBOARD_PROP_RX_DSP: - case MBOARD_PROP_RX_DSP_NAMES: - case MBOARD_PROP_TX_DSP: - case MBOARD_PROP_TX_DSP_NAMES: - case MBOARD_PROP_RX_DBOARD: - case MBOARD_PROP_RX_DBOARD_NAMES: - case MBOARD_PROP_TX_DBOARD: - case MBOARD_PROP_TX_DBOARD_NAMES: + case MBOARD_PROP_STREAM_CMD: + issue_ddc_stream_cmd(val.as<stream_cmd_t>()); + return; + + default: throw std::runtime_error("Error: trying to set read-only property on usrp2 mboard"); } |