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/usrp2/dsp_impl.cpp | |
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/usrp2/dsp_impl.cpp')
-rw-r--r-- | host/lib/usrp/usrp2/dsp_impl.cpp | 250 |
1 files changed, 80 insertions, 170 deletions
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"); + } } |