diff options
Diffstat (limited to 'host/lib/usrp/mboard')
-rw-r--r-- | host/lib/usrp/mboard/usrp2/dsp_impl.cpp | 136 | ||||
-rw-r--r-- | host/lib/usrp/mboard/usrp2/usrp2_impl.cpp | 5 | ||||
-rw-r--r-- | host/lib/usrp/mboard/usrp2/usrp2_impl.hpp | 9 |
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); |