summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/lib/usrp/mboard/usrp2/dsp_impl.cpp136
-rw-r--r--host/lib/usrp/mboard/usrp2/usrp2_impl.cpp5
-rw-r--r--host/lib/usrp/mboard/usrp2/usrp2_impl.hpp9
3 files changed, 142 insertions, 8 deletions
diff --git a/host/lib/usrp/mboard/usrp2/dsp_impl.cpp b/host/lib/usrp/mboard/usrp2/dsp_impl.cpp
index 3c2471eb6..7c31a5e3a 100644
--- a/host/lib/usrp/mboard/usrp2/dsp_impl.cpp
+++ b/host/lib/usrp/mboard/usrp2/dsp_impl.cpp
@@ -23,9 +23,21 @@
using namespace uhd;
/***********************************************************************
- * Helper Methods
+ * DDC Helper Methods
**********************************************************************/
-void usrp2_impl::ddc_init(size_t which){
+void usrp2_impl::init_ddc_config(size_t which){
+ //load the allowed decim/interp rates
+ //_USRP2_RATES = range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4)
+ for (size_t i = 4; i <= 128; i+=1){
+ _allowed_decim_and_interp_rates.push_back(i);
+ }
+ for (size_t i = 130; i <= 256; i+=2){
+ _allowed_decim_and_interp_rates.push_back(i);
+ }
+ for (size_t i = 260; i <= 512; i+=4){
+ _allowed_decim_and_interp_rates.push_back(i);
+ }
+
//create the ddc in the rx dsp dict
_rx_dsps[str(boost::format("ddc%d") % which)] = wax_obj_proxy(
boost::bind(&usrp2_impl::ddc_get, this, _1, _2, which),
@@ -39,7 +51,7 @@ void usrp2_impl::ddc_init(size_t which){
}
void usrp2_impl::update_ddc_config(size_t){
- //TODO
+ //TODO send it!
}
/***********************************************************************
@@ -57,6 +69,7 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val, size_t which){
prop_names_t others = boost::assign::list_of
("rate")
("decim")
+ ("decim_rates")
("freq")
;
val = others;
@@ -71,11 +84,15 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val, size_t which){
val = get_master_clock_freq();
return;
}
- if (key_name == "decim"){
+ else if (key_name == "decim"){
val = _ddc_decim[which];
return;
}
- if (key_name == "freq"){
+ else if (key_name == "decim_rates"){
+ val = _allowed_decim_and_interp_rates;
+ return;
+ }
+ else if (key_name == "freq"){
val = _ddc_freq[which];
return;
}
@@ -90,12 +107,19 @@ void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val, size_t which)
std::string key_name = wax::cast<std::string>(key);
if (key_name == "decim"){
size_t new_decim = wax::cast<size_t>(val);
+ ASSERT_THROW(std::has(
+ _allowed_decim_and_interp_rates.begin(),
+ _allowed_decim_and_interp_rates.end(),
+ new_decim
+ ));
_ddc_decim[which] = new_decim; //shadow
update_ddc_config(which);
return;
}
- if (key_name == "freq"){
+ else if (key_name == "freq"){
freq_t new_freq = wax::cast<freq_t>(val);
+ ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0);
+ ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0);
_ddc_freq[which] = new_freq; //shadow
update_ddc_config(which);
return;
@@ -107,5 +131,105 @@ void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val, size_t which)
}
/***********************************************************************
+ * DUC Helper Methods
+ **********************************************************************/
+void usrp2_impl::init_duc_config(void){
+ //create the duc in the tx dsp dict
+ _tx_dsps[str(boost::format("duc%d") % 0)] = wax_obj_proxy(
+ boost::bind(&usrp2_impl::duc_get, this, _1, _2),
+ boost::bind(&usrp2_impl::duc_set, this, _1, _2)
+ );
+
+ //initial config and update
+ _duc_interp = 16;
+ _duc_freq = 0;
+ update_duc_config();
+}
+
+void usrp2_impl::update_duc_config(void){
+ // Calculate CIC interpolation (i.e., without halfband interpolators)
+ size_t interp = 0; //TODO
+ while(interp > 128) interp /= 2;
+
+ // Calculate closest multiplier constant to reverse gain absent scale multipliers
+ size_t interp_cubed = pow(interp, 3);
+ size_t scale = rint((4096*pow(2, ceil(log2(interp_cubed))))/(1.65*interp_cubed));
+
+ //TODO send it!
+}
+
+/***********************************************************************
* 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(wax::cast<dsp_prop_t>(key)){
+ case DSP_PROP_NAME:
+ val = str(boost::format("usrp2 duc%d") % 0);
+ return;
+
+ case DSP_PROP_OTHERS:{
+ prop_names_t others = boost::assign::list_of
+ ("rate")
+ ("interp")
+ ("interp_rates")
+ ("freq")
+ ;
+ val = others;
+ }
+ return;
+ }
+ }
+
+ //handle string-based properties specific to this dsp
+ std::string key_name = wax::cast<std::string>(key);
+ if (key_name == "rate"){
+ val = get_master_clock_freq();
+ return;
+ }
+ else if (key_name == "interp"){
+ val = _duc_interp;
+ return;
+ }
+ else if (key_name == "interp_rates"){
+ val = _allowed_decim_and_interp_rates;
+ return;
+ }
+ else if (key_name == "freq"){
+ val = _duc_freq;
+ 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 = wax::cast<std::string>(key);
+ if (key_name == "interp"){
+ size_t new_interp = wax::cast<size_t>(val);
+ ASSERT_THROW(std::has(
+ _allowed_decim_and_interp_rates.begin(),
+ _allowed_decim_and_interp_rates.end(),
+ new_interp
+ ));
+ _duc_interp = new_interp; //shadow
+ update_duc_config();
+ return;
+ }
+ else if (key_name == "freq"){
+ freq_t new_freq = wax::cast<freq_t>(val);
+ 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
+ update_duc_config();
+ return;
+ }
+
+ throw std::invalid_argument(str(
+ boost::format("error setting: unknown key with name %s") % key_name
+ ));
+}
diff --git a/host/lib/usrp/mboard/usrp2/usrp2_impl.cpp b/host/lib/usrp/mboard/usrp2/usrp2_impl.cpp
index 1b985daaa..2bb1e9955 100644
--- a/host/lib/usrp/mboard/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/mboard/usrp2/usrp2_impl.cpp
@@ -40,9 +40,12 @@ usrp2_impl::usrp2_impl(
//init the ddcs (however many we have)
for (size_t i = 0; i < _num_ddc; i++){
- ddc_init(i);
+ init_ddc_config(i);
}
+ //init the duc
+ init_duc_config();
+
//initialize the clock configuration
init_clock_config();
}
diff --git a/host/lib/usrp/mboard/usrp2/usrp2_impl.hpp b/host/lib/usrp/mboard/usrp2/usrp2_impl.hpp
index 2475b3a3c..d2d90b8ed 100644
--- a/host/lib/usrp/mboard/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/mboard/usrp2/usrp2_impl.hpp
@@ -128,12 +128,19 @@ private:
uhd::dict<std::string, wax_obj_proxy> _tx_dboards;
//methods and shadows for the ddc dsp
+ std::vector<size_t> _allowed_decim_and_interp_rates;
static const size_t _num_ddc = 1;
size_t _ddc_decim[_num_ddc];
double _ddc_freq[_num_ddc];
- void ddc_init(size_t which);
+ void init_ddc_config(size_t which);
void update_ddc_config(size_t which_ddc);
+ //methods and shadows for the duc dsp
+ size_t _duc_interp;
+ double _duc_freq;
+ void init_duc_config(void);
+ void update_duc_config(void);
+
//properties interface for ddc
void ddc_get(const wax::obj &, wax::obj &, size_t which);
void ddc_set(const wax::obj &, const wax::obj &, size_t which);