diff options
| -rw-r--r-- | host/lib/convert/convert_common.hpp | 12 | ||||
| -rw-r--r-- | host/lib/convert/gen_convert_general.py | 102 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/io_impl.cpp | 69 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/usrp1_calc_mux.hpp | 4 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/usrp1_impl.cpp | 4 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/usrp1_impl.hpp | 4 | 
6 files changed, 143 insertions, 52 deletions
| diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp index 8c8cc88b0..612fa312b 100644 --- a/host/lib/convert/convert_common.hpp +++ b/host/lib/convert/convert_common.hpp @@ -86,19 +86,19 @@ static UHD_INLINE sc16_t item32_to_sc16(item32_t item, double){  /***********************************************************************   * Convert complex float buffer to items32 (no swap)   **********************************************************************/ -static UHD_INLINE item32_t fc32_to_item32(fc32_t num, float scale_factor){ -    boost::uint16_t real = boost::int16_t(num.real()*scale_factor); -    boost::uint16_t imag = boost::int16_t(num.imag()*scale_factor); +static UHD_INLINE item32_t fc32_to_item32(fc32_t num, double scale_factor){ +    boost::uint16_t real = boost::int16_t(num.real()*float(scale_factor)); +    boost::uint16_t imag = boost::int16_t(num.imag()*float(scale_factor));      return (item32_t(real) << 16) | (item32_t(imag) << 0);  }  /***********************************************************************   * Convert items32 buffer to complex float   **********************************************************************/ -static UHD_INLINE fc32_t item32_to_fc32(item32_t item, float scale_factor){ +static UHD_INLINE fc32_t item32_to_fc32(item32_t item, double scale_factor){      return fc32_t( -        float(boost::int16_t(item >> 16)*scale_factor), -        float(boost::int16_t(item >> 0)*scale_factor) +        float(boost::int16_t(item >> 16)*float(scale_factor)), +        float(boost::int16_t(item >> 0)*float(scale_factor))      );  } diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index 0d68a4dd3..a5c4d4cb7 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -28,13 +28,13 @@ TMPL_HEADER = """  using namespace uhd::convert;  """ -TMPL_CONV_TO_FROM_ITEM32_1 = """ +TMPL_CONV_GEN2_COMPLEX = """  DECLARE_CONVERTER($(cpu_type), 1, sc16_item32_$(end), 1, PRIORITY_GENERAL){      const $(cpu_type)_t *input = reinterpret_cast<const $(cpu_type)_t *>(inputs[0]);      item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);      for (size_t i = 0; i < nsamps; i++){ -        output[i] = $(to_wire)($(cpu_type)_to_item32(input[i], float(scale_factor))); +        output[i] = $(to_wire)($(cpu_type)_to_item32(input[i], scale_factor));      }  } @@ -43,33 +43,83 @@ DECLARE_CONVERTER(sc16_item32_$(end), 1, $(cpu_type), 1, PRIORITY_GENERAL){      $(cpu_type)_t *output = reinterpret_cast<$(cpu_type)_t *>(outputs[0]);      for (size_t i = 0; i < nsamps; i++){ -        output[i] = item32_to_$(cpu_type)($(to_host)(input[i]), float(scale_factor)); +        output[i] = item32_to_$(cpu_type)($(to_host)(input[i]), scale_factor);      }  }  """ -TMPL_CONV_TO_FROM_ITEM32_X = """ -DECLARE_CONVERTER($(cpu_type), $(width), sc16_item32_$(end), 1, PRIORITY_GENERAL){ + +TMPL_CONV_USRP1_COMPLEX = """ +DECLARE_CONVERTER($(cpu_type), $(width), sc16_item16_usrp1, 1, PRIORITY_GENERAL){      #for $w in range($width)      const $(cpu_type)_t *input$(w) = reinterpret_cast<const $(cpu_type)_t *>(inputs[$(w)]);      #end for -    item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); +    boost::uint16_t *output = reinterpret_cast<boost::uint16_t *>(outputs[0]); + +    if (scale_factor == 0){} //avoids unused warning      for (size_t i = 0, j = 0; i < nsamps; i++){          #for $w in range($width) -        output[j++] = $(to_wire)($(cpu_type)_to_item32(input$(w)[i], float(scale_factor))); +        output[j++] = $(to_wire)(boost::int16_t(input$(w)[i].real()$(do_scale))); +        output[j++] = $(to_wire)(boost::int16_t(input$(w)[i].imag()$(do_scale)));          #end for      }  } -DECLARE_CONVERTER(sc16_item32_$(end), 1, $(cpu_type), $(width), PRIORITY_GENERAL){ -    const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); +DECLARE_CONVERTER(sc16_item16_usrp1, 1, $(cpu_type), $(width), PRIORITY_GENERAL){ +    const boost::uint16_t *input = reinterpret_cast<const boost::uint16_t *>(inputs[0]);      #for $w in range($width)      $(cpu_type)_t *output$(w) = reinterpret_cast<$(cpu_type)_t *>(outputs[$(w)]);      #end for +    if (scale_factor == 0){} //avoids unused warning +      for (size_t i = 0, j = 0; i < nsamps; i++){          #for $w in range($width) -        output$(w)[i] = item32_to_$(cpu_type)($(to_host)(input[j++]), float(scale_factor)); +        output$(w)[i] = $(cpu_type)_t( +            boost::int16_t($(to_host)(input[j+0]))$(do_scale), +            boost::int16_t($(to_host)(input[j+1]))$(do_scale) +        ); +        j += 2; +        #end for +    } +} + +DECLARE_CONVERTER($(cpu_type), $(width), sc8_item16_usrp1, 1, PRIORITY_GENERAL){ +    #for $w in range($width) +    const $(cpu_type)_t *input$(w) = reinterpret_cast<const $(cpu_type)_t *>(inputs[$(w)]); +    #end for +    boost::uint16_t *output = reinterpret_cast<boost::uint16_t *>(outputs[0]); + +    if (scale_factor == 0){} //avoids unused warning + +    for (size_t i = 0, j = 0; i < nsamps; i++){ +        #for $w in range($width) +        { +        const boost::uint8_t real = boost::int8_t(input$(w)[i].real()$(do_scale)); +        const boost::uint8_t imag = boost::int8_t(input$(w)[i].imag()$(do_scale)); +        output[j++] = $(to_wire)((boost::uint16_t(imag) << 8) | real); +        } +        #end for +    } +} + +DECLARE_CONVERTER(sc8_item16_usrp1, 1, $(cpu_type), $(width), PRIORITY_GENERAL){ +    const boost::uint16_t *input = reinterpret_cast<const boost::uint16_t *>(inputs[0]); +    #for $w in range($width) +    $(cpu_type)_t *output$(w) = reinterpret_cast<$(cpu_type)_t *>(outputs[$(w)]); +    #end for + +    if (scale_factor == 0){} //avoids unused warning + +    for (size_t i = 0, j = 0; i < nsamps; i++){ +        #for $w in range($width) +        { +        const boost::uint16_t num = $(to_host)(input[j++]); +        output$(w)[i] = $(cpu_type)_t( +            boost::int8_t(num)$(do_scale), +            boost::int8_t(num >> 8)$(do_scale) +        ); +        }          #end for      }  } @@ -83,14 +133,28 @@ if __name__ == '__main__':      import sys, os      file = os.path.basename(__file__)      output = parse_tmpl(TMPL_HEADER, file=file) -    for width in 1, 2, 3, 4: -        for end, to_host, to_wire in ( -            ('be', 'uhd::ntohx', 'uhd::htonx'), -            ('le', 'uhd::wtohx', 'uhd::htowx'), + +    #generate complex converters for all gen2 platforms +    for end, to_host, to_wire in ( +        ('be', 'uhd::ntohx', 'uhd::htonx'), +        ('le', 'uhd::wtohx', 'uhd::htowx'), +    ): +        for cpu_type in 'fc64', 'fc32', 'sc16': +            output += parse_tmpl( +                TMPL_CONV_GEN2_COMPLEX, +                end=end, to_host=to_host, to_wire=to_wire, cpu_type=cpu_type +            ) + +    #generate complex converters for usrp1 format +    for width in 1, 2, 4: +        for cpu_type, do_scale in ( +            ('fc64', '*scale_factor'), +            ('fc32', '*float(scale_factor)'), +            ('sc16', ''),          ): -            for cpu_type in 'fc64', 'fc32', 'sc16': -                output += parse_tmpl( -                    TMPL_CONV_TO_FROM_ITEM32_1 if width == 1 else TMPL_CONV_TO_FROM_ITEM32_X, -                    width=width, end=end, to_host=to_host, to_wire=to_wire, cpu_type=cpu_type -                ) +            output += parse_tmpl( +                TMPL_CONV_USRP1_COMPLEX, +                width=width, to_host='uhd::wtohx', to_wire='uhd::htowx', +                cpu_type=cpu_type, do_scale=do_scale +            )      open(sys.argv[1], 'w').write(output) diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp index 03263ed26..7f20a8608 100644 --- a/host/lib/usrp/usrp1/io_impl.cpp +++ b/host/lib/usrp/usrp1/io_impl.cpp @@ -438,41 +438,45 @@ void usrp1_impl::update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){      this->restore_tx(s);  } -double usrp1_impl::update_rx_samp_rate(const double samp_rate){ +double usrp1_impl::update_rx_samp_rate(size_t dspno, const double samp_rate){      const size_t rate = uhd::clip<size_t>( -        boost::math::iround(_master_clock_rate / samp_rate), size_t(std::ceil(_master_clock_rate / 8e6)), 256 +        boost::math::iround(_master_clock_rate / samp_rate), size_t(std::ceil(_master_clock_rate / 16e6)), 256      ); -    bool s = this->disable_rx(); -    _iface->poke32(FR_DECIM_RATE, rate/2 - 1); -    this->restore_rx(s); +    if (dspno == 0){ //only care if dsp0 is set since its homogeneous +        bool s = this->disable_rx(); +        _iface->poke32(FR_DECIM_RATE, rate/2 - 1); +        this->restore_rx(s); -    //update the streamer if created -    boost::shared_ptr<usrp1_recv_packet_streamer> my_streamer = -        boost::dynamic_pointer_cast<usrp1_recv_packet_streamer>(_rx_streamer.lock()); -    if (my_streamer.get() != NULL){ -        my_streamer->set_samp_rate(_master_clock_rate / rate); +        //update the streamer if created +        boost::shared_ptr<usrp1_recv_packet_streamer> my_streamer = +            boost::dynamic_pointer_cast<usrp1_recv_packet_streamer>(_rx_streamer.lock()); +        if (my_streamer.get() != NULL){ +            my_streamer->set_samp_rate(_master_clock_rate / rate); +        }      }      return _master_clock_rate / rate;  } -double usrp1_impl::update_tx_samp_rate(const double samp_rate){ +double usrp1_impl::update_tx_samp_rate(size_t dspno, const double samp_rate){      const size_t rate = uhd::clip<size_t>(          boost::math::iround(_master_clock_rate / samp_rate), size_t(std::ceil(_master_clock_rate / 8e6)), 256      ); -    bool s = this->disable_tx(); -    _iface->poke32(FR_INTERP_RATE, rate/2 - 1); -    this->restore_tx(s); +    if (dspno == 0){ //only care if dsp0 is set since its homogeneous +        bool s = this->disable_tx(); +        _iface->poke32(FR_INTERP_RATE, rate/2 - 1); +        this->restore_tx(s); -    //update the streamer if created -    boost::shared_ptr<usrp1_send_packet_streamer> my_streamer = -        boost::dynamic_pointer_cast<usrp1_send_packet_streamer>(_tx_streamer.lock()); -    if (my_streamer.get() != NULL){ -        my_streamer->set_samp_rate(_master_clock_rate / rate); +        //update the streamer if created +        boost::shared_ptr<usrp1_send_packet_streamer> my_streamer = +            boost::dynamic_pointer_cast<usrp1_send_packet_streamer>(_tx_streamer.lock()); +        if (my_streamer.get() != NULL){ +            my_streamer->set_samp_rate(_master_clock_rate / rate); +        }      }      return _master_clock_rate / rate; @@ -528,6 +532,25 @@ bool usrp1_impl::recv_async_msg(   * Receive streamer   **********************************************************************/  rx_streamer::sptr usrp1_impl::get_rx_stream(const uhd::stream_args_t &args){ +    if (args.otw_format == "sc16"){ +        _iface->poke32(FR_RX_FORMAT, 0 +            | (0 << bmFR_RX_FORMAT_SHIFT_SHIFT) +            | (16 << bmFR_RX_FORMAT_WIDTH_SHIFT) +            | bmFR_RX_FORMAT_WANT_Q +        ); +    } +    else if (args.otw_format == "sc8"){ +        _iface->poke32(FR_RX_FORMAT, 0 +            | (8 << bmFR_RX_FORMAT_SHIFT_SHIFT) +            | (8 << bmFR_RX_FORMAT_WIDTH_SHIFT) +            | bmFR_RX_FORMAT_WANT_Q +            | bmFR_RX_FORMAT_BYPASS_HB //needed for 16Msps +        ); +    } +    else{ +        throw uhd::value_error("USRP1 RX cannot handle requested wire format: " + args.otw_format); +    } +      //map an empty channel set to chan0      const std::vector<size_t> channels = args.channels.empty()? std::vector<size_t>(1, 0) : args.channels; @@ -548,7 +571,7 @@ rx_streamer::sptr usrp1_impl::get_rx_stream(const uhd::stream_args_t &args){      //set the converter      uhd::convert::id_type id; -    id.input_markup = args.otw_format + "_item32_le"; +    id.input_markup = args.otw_format + "_item16_usrp1";      id.num_inputs = 1;      id.output_markup = args.cpu_format;      id.num_outputs = channels.size(); @@ -568,6 +591,10 @@ rx_streamer::sptr usrp1_impl::get_rx_stream(const uhd::stream_args_t &args){   * Transmit streamer   **********************************************************************/  tx_streamer::sptr usrp1_impl::get_tx_stream(const uhd::stream_args_t &args){ +    if (args.otw_format != "sc16"){ +        throw uhd::value_error("USRP1 TX cannot handle requested wire format: " + args.otw_format); +    } +      //map an empty channel set to chan0      const std::vector<size_t> channels = args.channels.empty()? std::vector<size_t>(1, 0) : args.channels; @@ -591,7 +618,7 @@ tx_streamer::sptr usrp1_impl::get_tx_stream(const uhd::stream_args_t &args){      uhd::convert::id_type id;      id.input_markup = args.cpu_format;      id.num_inputs = channels.size(); -    id.output_markup = args.otw_format + "_item32_le"; +    id.output_markup = args.otw_format + "_item16_usrp1";      id.num_outputs = 1;      id.args = args.args;      my_streamer->set_converter(id); diff --git a/host/lib/usrp/usrp1/usrp1_calc_mux.hpp b/host/lib/usrp/usrp1/usrp1_calc_mux.hpp index 31c190db0..d86a7a809 100644 --- a/host/lib/usrp/usrp1/usrp1_calc_mux.hpp +++ b/host/lib/usrp/usrp1/usrp1_calc_mux.hpp @@ -37,7 +37,7 @@ typedef std::pair<std::string, std::string> mapping_pair_t;   *    to account for the reversal in the type conversion routines.   **********************************************************************/  static int calc_rx_mux_pair(int adc_for_i, int adc_for_q){ -    return (adc_for_i << 2) | (adc_for_q << 0); //shift reversal here +    return (adc_for_i << 0) | (adc_for_q << 2);  }  /*! @@ -98,7 +98,7 @@ static boost::uint32_t calc_rx_mux(const std::vector<mapping_pair_t> &mapping){   *    to account for the reversal in the type conversion routines.   **********************************************************************/  static int calc_tx_mux_pair(int chn_for_i, int chn_for_q){ -    return (chn_for_i << 4) | (chn_for_q << 0); //shift reversal here +    return (chn_for_i << 0) | (chn_for_q << 4);  }  /*! diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp index d169c4823..93a301c02 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.cpp +++ b/host/lib/usrp/usrp1/usrp1_impl.cpp @@ -282,7 +282,7 @@ usrp1_impl::usrp1_impl(const device_addr_t &device_addr){          fs_path rx_dsp_path = mb_path / str(boost::format("rx_dsps/%u") % dspno);          _tree->create<double>(rx_dsp_path / "rate/value")              .set(1e6) -            .coerce(boost::bind(&usrp1_impl::update_rx_samp_rate, this, _1)); +            .coerce(boost::bind(&usrp1_impl::update_rx_samp_rate, this, dspno, _1));          _tree->create<double>(rx_dsp_path / "freq/value")              .coerce(boost::bind(&usrp1_impl::update_rx_dsp_freq, this, dspno, _1));          _tree->create<meta_range_t>(rx_dsp_path / "freq/range") @@ -303,7 +303,7 @@ usrp1_impl::usrp1_impl(const device_addr_t &device_addr){          fs_path tx_dsp_path = mb_path / str(boost::format("tx_dsps/%u") % dspno);          _tree->create<double>(tx_dsp_path / "rate/value")              .set(1e6) -            .coerce(boost::bind(&usrp1_impl::update_tx_samp_rate, this, _1)); +            .coerce(boost::bind(&usrp1_impl::update_tx_samp_rate, this, dspno, _1));          _tree->create<double>(tx_dsp_path / "freq/value")              .coerce(boost::bind(&usrp1_impl::update_tx_dsp_freq, this, dspno, _1));          _tree->create<meta_range_t>(tx_dsp_path / "freq/range") //magic scalar comes from codec control: diff --git a/host/lib/usrp/usrp1/usrp1_impl.hpp b/host/lib/usrp/usrp1/usrp1_impl.hpp index c777307ee..cfdcbbcc1 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.hpp +++ b/host/lib/usrp/usrp1/usrp1_impl.hpp @@ -90,8 +90,8 @@ private:      double update_rx_codec_gain(const std::string &, const double); //sets A and B at once      void update_rx_subdev_spec(const uhd::usrp::subdev_spec_t &);      void update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &); -    double update_rx_samp_rate(const double); -    double update_tx_samp_rate(const double); +    double update_rx_samp_rate(size_t dspno, const double); +    double update_tx_samp_rate(size_t dspno, const double);      void update_rates(void);      double update_rx_dsp_freq(const size_t, const double);      double update_tx_dsp_freq(const size_t, const double); | 
