aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/usrp2
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-04-05 14:37:21 -0700
committerJosh Blum <josh@joshknows.com>2010-04-05 14:37:21 -0700
commit1cc8c6c964d4368d9e918e4cb357600453a24c94 (patch)
tree145cea809ec723f006ad384d267ddb6d9eccd249 /host/lib/usrp/usrp2
parent12aa8ad74cf3a343159ddbb452455bf4e7f435b8 (diff)
downloaduhd-1cc8c6c964d4368d9e918e4cb357600453a24c94.tar.gz
uhd-1cc8c6c964d4368d9e918e4cb357600453a24c94.tar.bz2
uhd-1cc8c6c964d4368d9e918e4cb357600453a24c94.zip
paradigm shift for the dsp abstraction
Diffstat (limited to 'host/lib/usrp/usrp2')
-rw-r--r--host/lib/usrp/usrp2/dsp_impl.cpp250
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp62
2 files changed, 125 insertions, 187 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");
+ }
}
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");
}