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); | 
