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 | |
| parent | 12aa8ad74cf3a343159ddbb452455bf4e7f435b8 (diff) | |
| download | uhd-1cc8c6c964d4368d9e918e4cb357600453a24c94.tar.gz uhd-1cc8c6c964d4368d9e918e4cb357600453a24c94.tar.bz2 uhd-1cc8c6c964d4368d9e918e4cb357600453a24c94.zip | |
paradigm shift for the dsp abstraction
| -rw-r--r-- | host/examples/rx_timed_samples.cpp | 2 | ||||
| -rw-r--r-- | host/include/uhd/usrp/dsp_props.hpp | 23 | ||||
| -rw-r--r-- | host/include/uhd/usrp/mboard_props.hpp | 3 | ||||
| -rw-r--r-- | host/include/uhd/usrp/simple_usrp.hpp | 2 | ||||
| -rw-r--r-- | host/include/uhd/usrp/subdev_props.hpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_basic_and_lf.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/simple_usrp.cpp | 46 | ||||
| -rw-r--r-- | host/lib/usrp/tune_helper.cpp | 13 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/dsp_impl.cpp | 250 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 62 | 
10 files changed, 168 insertions, 243 deletions
| diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 1292d9b27..7b06981b2 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -57,7 +57,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      std::cout << boost::format("Using Device: %s") % sdev->get_name() << std::endl;      //set properties on the device -    double rx_rate = sdev->get_rx_rates()[4]; //pick some rate +    double rx_rate = 100e6/16; //FIXME get this from somewhere      std::cout << boost::format("Setting RX Rate: %f Msps...") % (rx_rate/1e6) << std::endl;      sdev->set_rx_rate(rx_rate);      std::cout << boost::format("Setting device timestamp to 0...") << std::endl; diff --git a/host/include/uhd/usrp/dsp_props.hpp b/host/include/uhd/usrp/dsp_props.hpp index 60c0df942..75d8c0a60 100644 --- a/host/include/uhd/usrp/dsp_props.hpp +++ b/host/include/uhd/usrp/dsp_props.hpp @@ -24,15 +24,24 @@ namespace uhd{ namespace usrp{      /*!       * Possible device dsp properties: -     *   A dsp can have a wide range of possible properties. -     *   A ddc would have a properties "decim", "freq", "taps"... -     *   Other properties could be gains, complex scalars, enables... -     *   For this reason the only required properties of a dsp is a name -     *   and a property to get list of other possible properties. +     *   A dsp is a black box fpga component found between +     *   the over-the-wire data and the codec pins. +     * +     *   The host rate can be modified to control resampling. +     *   Resampling can take the form of decimation, interpolation, +     *   or more complex fractional resampling techniques. +     *   As usual, read back the host rate after setting it +     *   to get the actual rate that was set (implementation dependent). +     * +     *   A dsp can also shift the digital stream in frequency. +     *   Set the shift property and read it back to get actual shift.       */      enum dsp_prop_t{ -        DSP_PROP_NAME   = 'n', //ro, std::string -        DSP_PROP_OTHERS = 'o'  //ro, prop_names_t +        DSP_PROP_NAME         = 'n', //ro, std::string +        DSP_PROP_OTHERS       = 'o', //ro, prop_names_t +        DSP_PROP_FREQ_SHIFT   = 'f', //rw, double Hz +        DSP_PROP_CODEC_RATE   = 'c', //ro, double Sps +        DSP_PROP_HOST_RATE    = 'h'  //rw, double Sps      };  }} //namespace diff --git a/host/include/uhd/usrp/mboard_props.hpp b/host/include/uhd/usrp/mboard_props.hpp index cfc1f412e..55c11b822 100644 --- a/host/include/uhd/usrp/mboard_props.hpp +++ b/host/include/uhd/usrp/mboard_props.hpp @@ -42,7 +42,8 @@ namespace uhd{ namespace usrp{          MBOARD_PROP_TX_DBOARD_NAMES = 'V', //ro, prop_names_t          MBOARD_PROP_CLOCK_CONFIG    = 'C', //rw, clock_config_t          MBOARD_PROP_TIME_NOW        = 't', //wo, time_spec_t -        MBOARD_PROP_TIME_NEXT_PPS   = 'T'  //wo, time_spec_t +        MBOARD_PROP_TIME_NEXT_PPS   = 'T', //wo, time_spec_t +        MBOARD_PROP_STREAM_CMD      = 's'  //wo, stream_cmd_t      };  }} //namespace diff --git a/host/include/uhd/usrp/simple_usrp.hpp b/host/include/uhd/usrp/simple_usrp.hpp index 2d6ad2a0f..6f74a406b 100644 --- a/host/include/uhd/usrp/simple_usrp.hpp +++ b/host/include/uhd/usrp/simple_usrp.hpp @@ -59,7 +59,6 @@ public:       ******************************************************************/      virtual void set_rx_rate(double rate) = 0;      virtual double get_rx_rate(void) = 0; -    virtual std::vector<double> get_rx_rates(void) = 0;      virtual tune_result_t set_rx_freq(double freq) = 0;      virtual freq_range_t get_rx_freq_range(void) = 0; @@ -77,7 +76,6 @@ public:       ******************************************************************/      virtual void set_tx_rate(double rate) = 0;      virtual double get_tx_rate(void) = 0; -    virtual std::vector<double> get_tx_rates(void) = 0;      virtual tune_result_t set_tx_freq(double freq) = 0;      virtual freq_range_t get_tx_freq_range(void) = 0; diff --git a/host/include/uhd/usrp/subdev_props.hpp b/host/include/uhd/usrp/subdev_props.hpp index 92d18340b..d35793c6b 100644 --- a/host/include/uhd/usrp/subdev_props.hpp +++ b/host/include/uhd/usrp/subdev_props.hpp @@ -39,7 +39,7 @@ namespace uhd{ namespace usrp{          SUBDEV_PROP_QUADRATURE        = 'q', //ro, bool          SUBDEV_PROP_IQ_SWAPPED        = 'i', //ro, bool          SUBDEV_PROP_SPECTRUM_INVERTED = 's', //ro, bool -        SUBDEV_PROP_LO_INTERFERES     = 'l'  //ro, bool +        SUBDEV_PROP_USE_LO_OFFSET     = 'l'  //ro, bool          //SUBDEV_PROP_RSSI,              //ro, float //----> not on all boards, use named prop          //SUBDEV_PROP_BANDWIDTH          //rw, double //----> not on all boards, use named prop      }; diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index be4e646ed..930646f76 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -150,7 +150,7 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){      case SUBDEV_PROP_IQ_SWAPPED:      case SUBDEV_PROP_SPECTRUM_INVERTED: -    case SUBDEV_PROP_LO_INTERFERES: +    case SUBDEV_PROP_USE_LO_OFFSET:          val = false;          return;      } @@ -186,7 +186,7 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){      case SUBDEV_PROP_QUADRATURE:      case SUBDEV_PROP_IQ_SWAPPED:      case SUBDEV_PROP_SPECTRUM_INVERTED: -    case SUBDEV_PROP_LO_INTERFERES: +    case SUBDEV_PROP_USE_LO_OFFSET:          throw std::runtime_error(str(boost::format(              "Error: trying to set read-only property on %s subdev"          ) % dboard_id::to_string(get_rx_id()))); @@ -258,7 +258,7 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){      case SUBDEV_PROP_IQ_SWAPPED:      case SUBDEV_PROP_SPECTRUM_INVERTED: -    case SUBDEV_PROP_LO_INTERFERES: +    case SUBDEV_PROP_USE_LO_OFFSET:          val = false;          return;      } @@ -294,7 +294,7 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){      case SUBDEV_PROP_QUADRATURE:      case SUBDEV_PROP_IQ_SWAPPED:      case SUBDEV_PROP_SPECTRUM_INVERTED: -    case SUBDEV_PROP_LO_INTERFERES: +    case SUBDEV_PROP_USE_LO_OFFSET:          throw std::runtime_error(str(boost::format(              "Error: trying to set read-only property on %s subdev"          ) % dboard_id::to_string(get_tx_id()))); diff --git a/host/lib/usrp/simple_usrp.cpp b/host/lib/usrp/simple_usrp.cpp index a0551a630..bd8bac00f 100644 --- a/host/lib/usrp/simple_usrp.cpp +++ b/host/lib/usrp/simple_usrp.cpp @@ -22,6 +22,7 @@  #include <uhd/usrp/mboard_props.hpp>  #include <uhd/usrp/device_props.hpp>  #include <uhd/usrp/dboard_props.hpp> +#include <uhd/usrp/dsp_props.hpp>  #include <boost/foreach.hpp>  #include <boost/format.hpp>  #include <stdexcept> @@ -30,17 +31,6 @@ using namespace uhd;  using namespace uhd::usrp;  /*********************************************************************** - * Helper Functions - **********************************************************************/ -static std::vector<double> get_xx_rates(wax::obj decerps, wax::obj rate){ -    std::vector<double> rates; -    BOOST_FOREACH(size_t decerp, decerps.as<std::vector<size_t> >()){ -        rates.push_back(rate.as<double>()/decerp); -    } -    return rates; -} - -/***********************************************************************   * Simple Device Implementation   **********************************************************************/  class simple_usrp_impl : public simple_usrp{ @@ -48,8 +38,8 @@ public:      simple_usrp_impl(const device_addr_t &addr){          _dev = device::make(addr);          _mboard = (*_dev)[DEVICE_PROP_MBOARD]; -        _rx_ddc = _mboard[named_prop_t(MBOARD_PROP_RX_DSP, "ddc0")]; -        _tx_duc = _mboard[named_prop_t(MBOARD_PROP_TX_DSP, "duc0")]; +        _rx_dsp = _mboard[named_prop_t(MBOARD_PROP_RX_DSP, "ddc0")]; //FIX string crap +        _tx_dsp = _mboard[named_prop_t(MBOARD_PROP_TX_DSP, "duc0")]; //FIX string crap          //extract rx subdevice          wax::obj rx_dboard = _mboard[MBOARD_PROP_RX_DBOARD]; @@ -86,7 +76,7 @@ public:      }      void issue_stream_cmd(const stream_cmd_t &stream_cmd){ -        _rx_ddc[std::string("stream_cmd")] = stream_cmd; +        _mboard[MBOARD_PROP_STREAM_CMD] = stream_cmd;      }      void set_clock_config(const clock_config_t &clock_config){ @@ -101,21 +91,15 @@ public:       * RX methods       ******************************************************************/      void set_rx_rate(double rate){ -        double samp_rate = _rx_ddc[std::string("if_rate")].as<double>(); -        assert_has(get_rx_rates(), rate, "simple device rx rate"); -        _rx_ddc[std::string("decim")] = size_t(samp_rate/rate); +        _rx_dsp[DSP_PROP_HOST_RATE] = rate;      }      double get_rx_rate(void){ -        return _rx_ddc[std::string("bb_rate")].as<double>(); -    } - -    std::vector<double> get_rx_rates(void){ -        return get_xx_rates(_rx_ddc[std::string("decims")], _rx_ddc[std::string("if_rate")]); +        return _rx_dsp[DSP_PROP_HOST_RATE].as<double>();      }      tune_result_t set_rx_freq(double target_freq){ -        return tune_rx_subdev_and_ddc(_rx_subdev, _rx_ddc, target_freq); +        return tune_rx_subdev_and_ddc(_rx_subdev, _rx_dsp, target_freq);      }      freq_range_t get_rx_freq_range(void){ @@ -150,21 +134,15 @@ public:       * TX methods       ******************************************************************/      void set_tx_rate(double rate){ -        double samp_rate = _tx_duc[std::string("if_rate")].as<double>(); -        assert_has(get_tx_rates(), rate, "simple device tx rate"); -        _tx_duc[std::string("interp")] = size_t(samp_rate/rate); +        _tx_dsp[DSP_PROP_HOST_RATE] = rate;      }      double get_tx_rate(void){ -        return _tx_duc[std::string("bb_rate")].as<double>(); -    } - -    std::vector<double> get_tx_rates(void){ -        return get_xx_rates(_tx_duc[std::string("interps")], _tx_duc[std::string("if_rate")]); +        return _tx_dsp[DSP_PROP_HOST_RATE].as<double>();      }      tune_result_t set_tx_freq(double target_freq){ -        return tune_tx_subdev_and_duc(_tx_subdev, _tx_duc, target_freq); +        return tune_tx_subdev_and_duc(_tx_subdev, _tx_dsp, target_freq);      }      freq_range_t get_tx_freq_range(void){ @@ -198,8 +176,8 @@ public:  private:      device::sptr _dev;      wax::obj _mboard; -    wax::obj _rx_ddc; -    wax::obj _tx_duc; +    wax::obj _rx_dsp; +    wax::obj _tx_dsp;      wax::obj _rx_subdev;      wax::obj _tx_subdev;  }; diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp index 79a6aff7b..2fb15064c 100644 --- a/host/lib/usrp/tune_helper.cpp +++ b/host/lib/usrp/tune_helper.cpp @@ -18,6 +18,7 @@  #include <uhd/usrp/tune_helper.hpp>  #include <uhd/utils/algorithm.hpp>  #include <uhd/usrp/subdev_props.hpp> +#include <uhd/usrp/dsp_props.hpp>  #include <cmath>  using namespace uhd; @@ -34,8 +35,8 @@ static tune_result_t tune_xx_subdev_and_dxc(      wax::obj subdev_freq_proxy = subdev[SUBDEV_PROP_FREQ];      bool subdev_quadrature = subdev[SUBDEV_PROP_QUADRATURE].as<bool>();      bool subdev_spectrum_inverted = subdev[SUBDEV_PROP_SPECTRUM_INVERTED].as<bool>(); -    wax::obj dxc_freq_proxy = dxc[std::string("freq")]; -    double dxc_sample_rate = dxc[std::string("if_rate")].as<double>(); +    wax::obj dxc_freq_proxy = dxc[DSP_PROP_FREQ_SHIFT]; +    double dxc_sample_rate = dxc[DSP_PROP_CODEC_RATE].as<double>();      // Ask the d'board to tune as closely as it can to target_freq+lo_offset      double target_inter_freq = target_freq + lo_offset; @@ -96,8 +97,8 @@ tune_result_t uhd::usrp::tune_rx_subdev_and_ddc(  ){      double lo_offset = 0.0;      //if the local oscillator will be in the passband, use an offset -    if (subdev[SUBDEV_PROP_LO_INTERFERES].as<bool>()){ -        lo_offset = 2.0*ddc[std::string("bb_rate")].as<double>(); +    if (subdev[SUBDEV_PROP_USE_LO_OFFSET].as<bool>()){ +        lo_offset = 2.0*ddc[DSP_PROP_HOST_RATE].as<double>();      }      return tune_rx_subdev_and_ddc(subdev, ddc, target_freq, lo_offset);  } @@ -119,8 +120,8 @@ tune_result_t uhd::usrp::tune_tx_subdev_and_duc(  ){      double lo_offset = 0.0;      //if the local oscillator will be in the passband, use an offset -    if (subdev[SUBDEV_PROP_LO_INTERFERES].as<bool>()){ -        lo_offset = 2.0*duc[std::string("bb_rate")].as<double>(); +    if (subdev[SUBDEV_PROP_USE_LO_OFFSET].as<bool>()){ +        lo_offset = 2.0*duc[DSP_PROP_HOST_RATE].as<double>();      }      return tune_tx_subdev_and_duc(subdev, duc, target_freq, lo_offset);  } 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");      } | 
