From 75b7967fac3ec72fb35c542da23491215d53a8bb Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 3 Oct 2011 16:46:00 -0700 Subject: convert: reworked convert to use new identification standard --- host/lib/convert/gen_convert_general.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'host/lib/convert/gen_convert_general.py') diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index 8c3138bda..0d68a4dd3 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -29,26 +29,26 @@ using namespace uhd::convert; """ TMPL_CONV_TO_FROM_ITEM32_1 = """ -DECLARE_CONVERTER(convert_$(cpu_type)_1_to_item32_1_$(swap), PRIORITY_GENERAL){ +DECLARE_CONVERTER($(cpu_type), 1, sc16_item32_$(end), 1, PRIORITY_GENERAL){ const $(cpu_type)_t *input = reinterpret_cast(inputs[0]); item32_t *output = reinterpret_cast(outputs[0]); for (size_t i = 0; i < nsamps; i++){ - output[i] = $(swap_fcn)($(cpu_type)_to_item32(input[i], float(scale_factor))); + output[i] = $(to_wire)($(cpu_type)_to_item32(input[i], float(scale_factor))); } } -DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_1_$(swap), PRIORITY_GENERAL){ +DECLARE_CONVERTER(sc16_item32_$(end), 1, $(cpu_type), 1, PRIORITY_GENERAL){ const item32_t *input = reinterpret_cast(inputs[0]); $(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)($(swap_fcn)(input[i]), float(scale_factor)); + output[i] = item32_to_$(cpu_type)($(to_host)(input[i]), float(scale_factor)); } } """ TMPL_CONV_TO_FROM_ITEM32_X = """ -DECLARE_CONVERTER(convert_$(cpu_type)_$(width)_to_item32_1_$(swap), PRIORITY_GENERAL){ +DECLARE_CONVERTER($(cpu_type), $(width), sc16_item32_$(end), 1, PRIORITY_GENERAL){ #for $w in range($width) const $(cpu_type)_t *input$(w) = reinterpret_cast(inputs[$(w)]); #end for @@ -56,12 +56,12 @@ DECLARE_CONVERTER(convert_$(cpu_type)_$(width)_to_item32_1_$(swap), PRIORITY_GEN for (size_t i = 0, j = 0; i < nsamps; i++){ #for $w in range($width) - output[j++] = $(swap_fcn)($(cpu_type)_to_item32(input$(w)[i], float(scale_factor))); + output[j++] = $(to_wire)($(cpu_type)_to_item32(input$(w)[i], float(scale_factor))); #end for } } -DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_$(width)_$(swap), PRIORITY_GENERAL){ +DECLARE_CONVERTER(sc16_item32_$(end), 1, $(cpu_type), $(width), PRIORITY_GENERAL){ const item32_t *input = reinterpret_cast(inputs[0]); #for $w in range($width) $(cpu_type)_t *output$(w) = reinterpret_cast<$(cpu_type)_t *>(outputs[$(w)]); @@ -69,7 +69,7 @@ DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_$(width)_$(swap), PRIORITY_GEN for (size_t i = 0, j = 0; i < nsamps; i++){ #for $w in range($width) - output$(w)[i] = item32_to_$(cpu_type)($(swap_fcn)(input[j++]), float(scale_factor)); + output$(w)[i] = item32_to_$(cpu_type)($(to_host)(input[j++]), float(scale_factor)); #end for } } @@ -84,10 +84,13 @@ if __name__ == '__main__': file = os.path.basename(__file__) output = parse_tmpl(TMPL_HEADER, file=file) for width in 1, 2, 3, 4: - for swap, swap_fcn in (('nswap', ''), ('bswap', 'uhd::byteswap')): + 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_TO_FROM_ITEM32_1 if width == 1 else TMPL_CONV_TO_FROM_ITEM32_X, - width=width, swap=swap, swap_fcn=swap_fcn, cpu_type=cpu_type + width=width, end=end, to_host=to_host, to_wire=to_wire, cpu_type=cpu_type ) open(sys.argv[1], 'w').write(output) -- cgit v1.2.3 From 4c4f0810ef06be18e989b6933ff236ff97c13dd0 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 6 Oct 2011 18:41:59 -0700 Subject: usrp1: type conversions and 8-bit work --- host/lib/convert/convert_common.hpp | 12 ++-- host/lib/convert/gen_convert_general.py | 102 ++++++++++++++++++++++++++------ host/lib/usrp/usrp1/io_impl.cpp | 69 ++++++++++++++------- host/lib/usrp/usrp1/usrp1_calc_mux.hpp | 4 +- host/lib/usrp/usrp1/usrp1_impl.cpp | 4 +- host/lib/usrp/usrp1/usrp1_impl.hpp | 4 +- 6 files changed, 143 insertions(+), 52 deletions(-) (limited to 'host/lib/convert/gen_convert_general.py') 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(inputs[0]); item32_t *output = reinterpret_cast(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(inputs[$(w)]); #end for - item32_t *output = reinterpret_cast(outputs[0]); + boost::uint16_t *output = reinterpret_cast(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(inputs[0]); +DECLARE_CONVERTER(sc16_item16_usrp1, 1, $(cpu_type), $(width), PRIORITY_GENERAL){ + const boost::uint16_t *input = reinterpret_cast(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(inputs[$(w)]); + #end for + boost::uint16_t *output = reinterpret_cast(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(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( - 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 my_streamer = - boost::dynamic_pointer_cast(_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 my_streamer = + boost::dynamic_pointer_cast(_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( 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 my_streamer = - boost::dynamic_pointer_cast(_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 my_streamer = + boost::dynamic_pointer_cast(_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 channels = args.channels.empty()? std::vector(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 channels = args.channels.empty()? std::vector(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 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){ * 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(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(rx_dsp_path / "freq/value") .coerce(boost::bind(&usrp1_impl::update_rx_dsp_freq, this, dspno, _1)); _tree->create(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(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(tx_dsp_path / "freq/value") .coerce(boost::bind(&usrp1_impl::update_tx_dsp_freq, this, dspno, _1)); _tree->create(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); -- cgit v1.2.3 From 65fb4d225204b4ee2b7c73fc0ec393cfff9d6149 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 7 Oct 2011 10:47:56 -0700 Subject: usrp1: various tweaks related to streaming --- host/lib/convert/gen_convert_general.py | 19 ------------------- host/lib/usrp/usrp1/io_impl.cpp | 18 ++++++++++-------- host/lib/usrp/usrp1/soft_time_ctrl.cpp | 7 +++---- host/lib/usrp/usrp1/soft_time_ctrl.hpp | 2 +- host/lib/usrp/usrp1/usrp1_impl.cpp | 2 -- 5 files changed, 14 insertions(+), 34 deletions(-) (limited to 'host/lib/convert/gen_convert_general.py') diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index a5c4d4cb7..0cd4155fa 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -84,25 +84,6 @@ DECLARE_CONVERTER(sc16_item16_usrp1, 1, $(cpu_type), $(width), PRIORITY_GENERAL) } } -DECLARE_CONVERTER($(cpu_type), $(width), sc8_item16_usrp1, 1, PRIORITY_GENERAL){ - #for $w in range($width) - const $(cpu_type)_t *input$(w) = reinterpret_cast(inputs[$(w)]); - #end for - boost::uint16_t *output = reinterpret_cast(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(inputs[0]); #for $w in range($width) diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp index 7f20a8608..835c78ecc 100644 --- a/host/lib/usrp/usrp1/io_impl.cpp +++ b/host/lib/usrp/usrp1/io_impl.cpp @@ -22,6 +22,7 @@ #include "../../transport/super_send_packet_handler.hpp" #include "usrp1_calc_mux.hpp" #include "fpga_regs_standard.h" +#include "fpga_regs_common.h" #include "usrp_commands.h" #include "usrp1_impl.hpp" #include @@ -367,7 +368,7 @@ public: const uhd::tx_metadata_t &metadata, double timeout ){ - if (_stc->send_pre(metadata, timeout)) return 0; + _stc->send_pre(metadata, timeout); _tx_enb_fcn(true); //always enable (it will do the right thing) size_t num_samps_sent = sph::send_packet_handler::send( @@ -440,13 +441,14 @@ void usrp1_impl::update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){ double usrp1_impl::update_rx_samp_rate(size_t dspno, const double samp_rate){ + const size_t div = 2; const size_t rate = uhd::clip( - boost::math::iround(_master_clock_rate / samp_rate), size_t(std::ceil(_master_clock_rate / 16e6)), 256 - ); + boost::math::iround(_master_clock_rate / samp_rate), 4, 256) & ~(div-1); 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); + _iface->poke32(FR_RX_SAMPLE_RATE_DIV, div - 1); + _iface->poke32(FR_DECIM_RATE, rate/div - 1); this->restore_rx(s); //update the streamer if created @@ -462,13 +464,14 @@ double usrp1_impl::update_rx_samp_rate(size_t dspno, const double samp_rate){ double usrp1_impl::update_tx_samp_rate(size_t dspno, const double samp_rate){ + const size_t div = 2; const size_t rate = uhd::clip( - 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), 8, 256) & ~(div-1); 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); + _iface->poke32(FR_TX_SAMPLE_RATE_DIV, div - 1); + _iface->poke32(FR_INTERP_RATE, rate/div - 1); this->restore_tx(s); //update the streamer if created @@ -544,7 +547,6 @@ rx_streamer::sptr usrp1_impl::get_rx_stream(const uhd::stream_args_t &args){ | (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{ diff --git a/host/lib/usrp/usrp1/soft_time_ctrl.cpp b/host/lib/usrp/usrp1/soft_time_ctrl.cpp index 78481c3ff..b8af8af06 100644 --- a/host/lib/usrp/usrp1/soft_time_ctrl.cpp +++ b/host/lib/usrp/usrp1/soft_time_ctrl.cpp @@ -131,8 +131,8 @@ public: /******************************************************************* * Transmit control ******************************************************************/ - bool send_pre(const tx_metadata_t &md, double &timeout){ - if (not md.has_time_spec) return false; + void send_pre(const tx_metadata_t &md, double &timeout){ + if (not md.has_time_spec) return; boost::mutex::scoped_lock lock(_update_mutex); @@ -146,12 +146,11 @@ public: metadata.time_spec = this->time_now(); metadata.event_code = async_metadata_t::EVENT_CODE_TIME_ERROR; _async_msg_queue.push_with_pop_on_full(metadata); - return true; + return; } timeout -= (time_at - time_now()).get_real_secs(); sleep_until_time(lock, time_at); - return false; } /******************************************************************* diff --git a/host/lib/usrp/usrp1/soft_time_ctrl.hpp b/host/lib/usrp/usrp1/soft_time_ctrl.hpp index e91aaf6a2..b92b51252 100644 --- a/host/lib/usrp/usrp1/soft_time_ctrl.hpp +++ b/host/lib/usrp/usrp1/soft_time_ctrl.hpp @@ -57,7 +57,7 @@ public: virtual size_t recv_post(rx_metadata_t &md, const size_t nsamps) = 0; //! Call before the internal send function - virtual bool send_pre(const tx_metadata_t &md, double &timeout) = 0; + virtual void send_pre(const tx_metadata_t &md, double &timeout) = 0; //! Issue a stream command to receive virtual void issue_stream_cmd(const stream_cmd_t &cmd) = 0; diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp index 93a301c02..108fdc9ac 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.cpp +++ b/host/lib/usrp/usrp1/usrp1_impl.cpp @@ -187,8 +187,6 @@ usrp1_impl::usrp1_impl(const device_addr_t &device_addr){ // Normal mode with no loopback or Rx counting _iface->poke32(FR_MODE, 0x00000000); _iface->poke32(FR_DEBUG_EN, 0x00000000); - _iface->poke32(FR_RX_SAMPLE_RATE_DIV, 0x00000001); //divide by 2 - _iface->poke32(FR_TX_SAMPLE_RATE_DIV, 0x00000001); //divide by 2 _iface->poke32(FR_DC_OFFSET_CL_EN, 0x0000000f); // Reset offset correction registers -- cgit v1.2.3 From 861e66848f05001fcaca4fe91dbf67cd186649dc Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 7 Oct 2011 17:30:42 -0700 Subject: usrp2: work on alternative OTW formats --- host/lib/convert/convert_common.hpp | 66 +++++++++++++++++++++++------ host/lib/convert/convert_fc32_with_sse2.cpp | 16 +++---- host/lib/convert/convert_fc64_with_sse2.cpp | 8 ++-- host/lib/convert/gen_convert_general.py | 32 +++++++++++++- host/lib/usrp/cores/rx_dsp_core_200.cpp | 21 ++++++++- host/lib/usrp/cores/rx_dsp_core_200.hpp | 1 + host/lib/usrp/usrp1/io_impl.cpp | 4 ++ host/lib/usrp/usrp2/io_impl.cpp | 7 ++- 8 files changed, 126 insertions(+), 29 deletions(-) (limited to 'host/lib/convert/gen_convert_general.py') diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp index 612fa312b..56b718292 100644 --- a/host/lib/convert/convert_common.hpp +++ b/host/lib/convert/convert_common.hpp @@ -65,18 +65,18 @@ typedef boost::int8_t s8_t; typedef boost::uint32_t item32_t; /*********************************************************************** - * Convert complex short buffer to items32 + * Convert complex short buffer to items32 sc16 **********************************************************************/ -static UHD_INLINE item32_t sc16_to_item32(sc16_t num, double){ +static UHD_INLINE item32_t sc16_to_item32_sc16(sc16_t num, double){ boost::uint16_t real = num.real(); boost::uint16_t imag = num.imag(); return (item32_t(real) << 16) | (item32_t(imag) << 0); } /*********************************************************************** - * Convert items32 buffer to complex short + * Convert items32 sc16 buffer to complex short **********************************************************************/ -static UHD_INLINE sc16_t item32_to_sc16(item32_t item, double){ +static UHD_INLINE sc16_t item32_sc16_to_sc16(item32_t item, double){ return sc16_t( boost::int16_t(item >> 16), boost::int16_t(item >> 0) @@ -84,18 +84,18 @@ static UHD_INLINE sc16_t item32_to_sc16(item32_t item, double){ } /*********************************************************************** - * Convert complex float buffer to items32 (no swap) + * Convert complex float buffer to items32 sc16 **********************************************************************/ -static UHD_INLINE item32_t fc32_to_item32(fc32_t num, double scale_factor){ +static UHD_INLINE item32_t fc32_to_item32_sc16(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 + * Convert items32 sc16 buffer to complex float **********************************************************************/ -static UHD_INLINE fc32_t item32_to_fc32(item32_t item, double scale_factor){ +static UHD_INLINE fc32_t item32_sc16_to_fc32(item32_t item, double scale_factor){ return fc32_t( float(boost::int16_t(item >> 16)*float(scale_factor)), float(boost::int16_t(item >> 0)*float(scale_factor)) @@ -103,22 +103,64 @@ static UHD_INLINE fc32_t item32_to_fc32(item32_t item, double scale_factor){ } /*********************************************************************** - * Convert complex double buffer to items32 (no swap) + * Convert complex double buffer to items32 sc16 **********************************************************************/ -static UHD_INLINE item32_t fc64_to_item32(fc64_t num, double scale_factor){ +static UHD_INLINE item32_t fc64_to_item32_sc16(fc64_t num, double scale_factor){ boost::uint16_t real = boost::int16_t(num.real()*scale_factor); boost::uint16_t imag = boost::int16_t(num.imag()*scale_factor); return (item32_t(real) << 16) | (item32_t(imag) << 0); } /*********************************************************************** - * Convert items32 buffer to complex double + * Convert items32 sc16 buffer to complex double **********************************************************************/ -static UHD_INLINE fc64_t item32_to_fc64(item32_t item, double scale_factor){ +static UHD_INLINE fc64_t item32_sc16_to_fc64(item32_t item, double scale_factor){ return fc64_t( float(boost::int16_t(item >> 16)*scale_factor), float(boost::int16_t(item >> 0)*scale_factor) ); } +/*********************************************************************** + * Convert items32 sc8 buffer to complex short + **********************************************************************/ +static UHD_INLINE void item32_sc8_to_sc16(item32_t item, sc16_t &out0, sc16_t &out1, double){ + out0 = sc16_t( + boost::int8_t(item >> 8), + boost::int8_t(item >> 0) + ); + out1 = sc16_t( + boost::int8_t(item >> 24), + boost::int8_t(item >> 16) + ); +} + +/*********************************************************************** + * Convert items32 sc8 buffer to complex float + **********************************************************************/ +static UHD_INLINE void item32_sc8_to_fc32(item32_t item, fc32_t &out0, fc32_t &out1, double scale_factor){ + out0 = fc32_t( + float(boost::int8_t(item >> 8)*float(scale_factor)), + float(boost::int8_t(item >> 0)*float(scale_factor)) + ); + out1 = fc32_t( + float(boost::int8_t(item >> 24)*float(scale_factor)), + float(boost::int8_t(item >> 16)*float(scale_factor)) + ); +} + +/*********************************************************************** + * Convert items32 sc8 buffer to complex double + **********************************************************************/ +static UHD_INLINE void item32_sc8_to_fc64(item32_t item, fc64_t &out0, fc64_t &out1, double scale_factor){ + out0 = fc64_t( + float(boost::int8_t(item >> 8)*scale_factor), + float(boost::int8_t(item >> 0)*scale_factor) + ); + out1 = fc64_t( + float(boost::int8_t(item >> 24)*scale_factor), + float(boost::int8_t(item >> 16)*scale_factor) + ); +} + #endif /* INCLUDED_LIBUHD_CONVERT_COMMON_HPP */ diff --git a/host/lib/convert/convert_fc32_with_sse2.cpp b/host/lib/convert/convert_fc32_with_sse2.cpp index 34c85db80..b8d1aa8cc 100644 --- a/host/lib/convert/convert_fc32_with_sse2.cpp +++ b/host/lib/convert/convert_fc32_with_sse2.cpp @@ -51,7 +51,7 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_CUSTOM){ //dispatch according to alignment switch (size_t(input) & 0xf){ case 0x8: - output[i] = fc32_to_item32(input[i], float(scale_factor)); i++; + output[i] = fc32_to_item32_sc16(input[i], float(scale_factor)); i++; case 0x0: convert_fc32_1_to_item32_1_nswap_guts(_) break; @@ -60,7 +60,7 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_CUSTOM){ //convert remainder for (; i < nsamps; i++){ - output[i] = fc32_to_item32(input[i], float(scale_factor)); + output[i] = fc32_to_item32_sc16(input[i], float(scale_factor)); } } @@ -93,7 +93,7 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_be, 1, PRIORITY_CUSTOM){ //dispatch according to alignment switch (size_t(input) & 0xf){ case 0x8: - output[i] = uhd::byteswap(fc32_to_item32(input[i], float(scale_factor))); i++; + output[i] = uhd::byteswap(fc32_to_item32_sc16(input[i], float(scale_factor))); i++; case 0x0: convert_fc32_1_to_item32_1_bswap_guts(_) break; @@ -102,7 +102,7 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_be, 1, PRIORITY_CUSTOM){ //convert remainder for (; i < nsamps; i++){ - output[i] = uhd::byteswap(fc32_to_item32(input[i], float(scale_factor))); + output[i] = uhd::byteswap(fc32_to_item32_sc16(input[i], float(scale_factor))); } } @@ -138,7 +138,7 @@ DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_CUSTOM){ //dispatch according to alignment switch (size_t(output) & 0xf){ case 0x8: - output[i] = item32_to_fc32(input[i], float(scale_factor)); i++; + output[i] = item32_sc16_to_fc32(input[i], float(scale_factor)); i++; case 0x0: convert_item32_1_to_fc32_1_nswap_guts(_) break; @@ -147,7 +147,7 @@ DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_CUSTOM){ //convert remainder for (; i < nsamps; i++){ - output[i] = item32_to_fc32(input[i], float(scale_factor)); + output[i] = item32_sc16_to_fc32(input[i], float(scale_factor)); } } @@ -182,7 +182,7 @@ DECLARE_CONVERTER(sc16_item32_be, 1, fc32, 1, PRIORITY_CUSTOM){ //dispatch according to alignment switch (size_t(output) & 0xf){ case 0x8: - output[i] = item32_to_fc32(uhd::byteswap(input[i]), float(scale_factor)); i++; + output[i] = item32_sc16_to_fc32(uhd::byteswap(input[i]), float(scale_factor)); i++; case 0x0: convert_item32_1_to_fc32_1_bswap_guts(_) break; @@ -191,6 +191,6 @@ DECLARE_CONVERTER(sc16_item32_be, 1, fc32, 1, PRIORITY_CUSTOM){ //convert remainder for (; i < nsamps; i++){ - output[i] = item32_to_fc32(uhd::byteswap(input[i]), float(scale_factor)); + output[i] = item32_sc16_to_fc32(uhd::byteswap(input[i]), float(scale_factor)); } } diff --git a/host/lib/convert/convert_fc64_with_sse2.cpp b/host/lib/convert/convert_fc64_with_sse2.cpp index 2093cf476..a4f2df2e7 100644 --- a/host/lib/convert/convert_fc64_with_sse2.cpp +++ b/host/lib/convert/convert_fc64_with_sse2.cpp @@ -64,7 +64,7 @@ DECLARE_CONVERTER(fc64, 1, sc16_item32_le, 1, PRIORITY_CUSTOM){ //convert remainder for (; i < nsamps; i++){ - output[i] = fc64_to_item32(input[i], scale_factor); + output[i] = fc64_to_item32_sc16(input[i], scale_factor); } } @@ -110,7 +110,7 @@ DECLARE_CONVERTER(fc64, 1, sc16_item32_be, 1, PRIORITY_CUSTOM){ //convert remainder for (; i < nsamps; i++){ - output[i] = uhd::byteswap(fc64_to_item32(input[i], scale_factor)); + output[i] = uhd::byteswap(fc64_to_item32_sc16(input[i], scale_factor)); } } @@ -159,7 +159,7 @@ DECLARE_CONVERTER(sc16_item32_le, 1, fc64, 1, PRIORITY_CUSTOM){ //convert remainder for (; i < nsamps; i++){ - output[i] = item32_to_fc64(input[i], scale_factor); + output[i] = item32_sc16_to_fc64(input[i], scale_factor); } } @@ -207,6 +207,6 @@ DECLARE_CONVERTER(sc16_item32_be, 1, fc64, 1, PRIORITY_CUSTOM){ //convert remainder for (; i < nsamps; i++){ - output[i] = item32_to_fc64(uhd::byteswap(input[i]), scale_factor); + output[i] = item32_sc16_to_fc64(uhd::byteswap(input[i]), scale_factor); } } diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index 0cd4155fa..43e1f9967 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -34,7 +34,7 @@ DECLARE_CONVERTER($(cpu_type), 1, sc16_item32_$(end), 1, PRIORITY_GENERAL){ item32_t *output = reinterpret_cast(outputs[0]); for (size_t i = 0; i < nsamps; i++){ - output[i] = $(to_wire)($(cpu_type)_to_item32(input[i], scale_factor)); + output[i] = $(to_wire)($(cpu_type)_to_item32_sc16(input[i], scale_factor)); } } @@ -43,7 +43,35 @@ 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]), scale_factor); + output[i] = item32_sc16_to_$(cpu_type)($(to_host)(input[i]), scale_factor); + } +} + +DECLARE_CONVERTER(sc8_item32_$(end), 1, $(cpu_type), 1, PRIORITY_GENERAL){ + const item32_t *input = reinterpret_cast(size_t(inputs[0]) & ~0x3); + $(cpu_type)_t *output = reinterpret_cast<$(cpu_type)_t *>(outputs[0]); + $(cpu_type)_t dummy; + + const bool head_case = ((size_t(inputs[0]) & 0x3) != 0); + const bool tail_case = ((nsamps & 0x1) == 0)? head_case : not head_case; + const size_t num_pairs = (head_case? nsamps-1 : nsamps)/2; + size_t i = 0, j = 0; + + //special head case, probably from a partial recv + if (head_case){ + const item32_t item0 = $(to_host)(input[i++]); + item32_sc8_to_$(cpu_type)(item0, dummy, output[j++], scale_factor); + } + + for (; i < num_pairs; i++, j+=2){ + const item32_t item_i = $(to_host)(input[i]); + item32_sc8_to_$(cpu_type)(item_i, output[j], output[j+1], scale_factor); + } + + //special tail case, finished on an odd number + if (tail_case){ + const item32_t item_i = $(to_host)(input[i]); + item32_sc8_to_$(cpu_type)(item_i, output[j], dummy, scale_factor); } } """ diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index d562c64db..023216a09 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -42,6 +42,7 @@ #define REG_RX_CTRL_VRT_TLR _ctrl_base + 24 #define REG_RX_CTRL_NSAMPS_PP _ctrl_base + 28 #define REG_RX_CTRL_NCHANNELS _ctrl_base + 32 +#define REG_RX_CTRL_FORMAT _ctrl_base + 36 template T ceil_log2(T num){ return std::ceil(std::log(num)/std::log(T(2))); @@ -162,7 +163,7 @@ public: } double get_scaling_adjustment(void){ - return _scaling_adjustment; + return _scaling_adjustment/_fxpt_scale_adj; } double set_freq(const double freq_){ @@ -192,12 +193,28 @@ public: if (_continuous_streaming) issue_stream_command(stream_cmd_t::STREAM_MODE_START_CONTINUOUS); } + void set_format(const std::string &format, const unsigned scale){ + unsigned format_word = 0; + if (format == "sc16"){ + format_word = 0; + _fxpt_scale_adj = 32767.; + } + else if (format == "sc8"){ + format_word = (1 << 18); + _fxpt_scale_adj = 32767./scale; + } + else throw uhd::value_error("USRP RX cannot handle requested wire format: " + format); + + const unsigned scale_word = scale & 0x3ffff; //18 bits; + _iface->poke32(REG_RX_CTRL_FORMAT, format_word | scale_word); + } + private: wb_iface::sptr _iface; const size_t _dsp_base, _ctrl_base; double _tick_rate, _link_rate; bool _continuous_streaming; - double _scaling_adjustment; + double _scaling_adjustment, _fxpt_scale_adj; }; rx_dsp_core_200::sptr rx_dsp_core_200::make(wb_iface::sptr iface, const size_t dsp_base, const size_t ctrl_base, const boost::uint32_t sid, const bool lingering_packet){ diff --git a/host/lib/usrp/cores/rx_dsp_core_200.hpp b/host/lib/usrp/cores/rx_dsp_core_200.hpp index 391cc8441..ddd6f2abf 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.hpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.hpp @@ -56,6 +56,7 @@ public: virtual void handle_overflow(void) = 0; + virtual void set_format(const std::string &format, const unsigned scale) = 0; }; #endif /* INCLUDED_LIBUHD_USRP_RX_DSP_CORE_200_HPP */ diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp index 835c78ecc..eaa6d02b4 100644 --- a/host/lib/usrp/usrp1/io_impl.cpp +++ b/host/lib/usrp/usrp1/io_impl.cpp @@ -564,6 +564,10 @@ rx_streamer::sptr usrp1_impl::get_rx_stream(const uhd::stream_args_t &args){ boost::shared_ptr my_streamer = boost::make_shared(spp, _soft_time_ctrl); + //special scale factor change for sc8 + if (args.otw_format == "sc8") + my_streamer->set_scale_factor(1.0/127); + //init some streamer stuff my_streamer->set_tick_rate(_master_clock_rate); my_streamer->set_vrt_unpacker(&usrp1_bs_vrt_unpacker); diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index d37be403b..f917a35db 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -290,7 +290,7 @@ void usrp2_impl::update_rx_samp_rate(const std::string &mb, const size_t dsp, co my_streamer->set_samp_rate(rate); const double adj = _mbc[mb].rx_dsps[dsp]->get_scaling_adjustment(); - my_streamer->set_scale_factor(adj/32767.); + my_streamer->set_scale_factor(adj); } void usrp2_impl::update_tx_samp_rate(const std::string &mb, const size_t dsp, const double rate){ @@ -404,6 +404,7 @@ rx_streamer::sptr usrp2_impl::get_rx_stream(const uhd::stream_args_t &args){ if (chan < num_chan_so_far){ const size_t dsp = num_chan_so_far - chan - 1; _mbc[mb].rx_dsps[dsp]->set_nsamps_per_packet(spp); //seems to be a good place to set this + _mbc[mb].rx_dsps[dsp]->set_format(args.otw_format, 0x400); my_streamer->set_xport_chan_get_buff(chan_i, boost::bind( &zero_copy_if::get_recv_buff, _mbc[mb].rx_dsp_xports[dsp], _1 )); @@ -427,6 +428,10 @@ rx_streamer::sptr usrp2_impl::get_rx_stream(const uhd::stream_args_t &args){ * Transmit streamer **********************************************************************/ tx_streamer::sptr usrp2_impl::get_tx_stream(const uhd::stream_args_t &args){ + if (args.otw_format != "sc16"){ + throw uhd::value_error("USRP TX cannot handle requested wire format: " + args.otw_format); + } + //map an empty channel set to chan0 const std::vector channels = args.channels.empty()? std::vector(1, 0) : args.channels; -- cgit v1.2.3 From 522bc87d9f61668f3d22e067c39a98e5f33fc6c5 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 12 Oct 2011 20:05:57 -0700 Subject: uhd: fixed 8sc item32 converter on head/tail cases --- host/examples/rx_timed_samples.cpp | 2 +- host/lib/convert/gen_convert_general.py | 24 ++++++++++-------------- 2 files changed, 11 insertions(+), 15 deletions(-) (limited to 'host/lib/convert/gen_convert_general.py') diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 0851593cd..143bceb03 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -98,7 +98,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ while(num_acc_samps < total_num_samps){ //receive a single packet size_t num_rx_samps = rx_stream->recv( - &buff.front(), buff.size(), md, timeout + &buff.front(), buff.size(), md, timeout, true ); //use a small timeout for subsequent packets diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index 43e1f9967..9a1135b0b 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -51,27 +51,23 @@ DECLARE_CONVERTER(sc8_item32_$(end), 1, $(cpu_type), 1, PRIORITY_GENERAL){ const item32_t *input = reinterpret_cast(size_t(inputs[0]) & ~0x3); $(cpu_type)_t *output = reinterpret_cast<$(cpu_type)_t *>(outputs[0]); $(cpu_type)_t dummy; + size_t num_samps = nsamps; - const bool head_case = ((size_t(inputs[0]) & 0x3) != 0); - const bool tail_case = ((nsamps & 0x1) == 0)? head_case : not head_case; - const size_t num_pairs = (head_case? nsamps-1 : nsamps)/2; - size_t i = 0, j = 0; - - //special head case, probably from a partial recv - if (head_case){ - const item32_t item0 = $(to_host)(input[i++]); - item32_sc8_to_$(cpu_type)(item0, dummy, output[j++], scale_factor); + if ((size_t(inputs[0]) & 0x3) != 0){ + const item32_t item0 = $(to_host)(*input++); + item32_sc8_to_$(cpu_type)(item0, dummy, *output++, scale_factor); + num_samps--; } - for (; i < num_pairs; i++, j+=2){ + const size_t num_pairs = num_samps/2; + for (size_t i = 0, j = 0; i < num_pairs; i++, j+=2){ const item32_t item_i = $(to_host)(input[i]); item32_sc8_to_$(cpu_type)(item_i, output[j], output[j+1], scale_factor); } - //special tail case, finished on an odd number - if (tail_case){ - const item32_t item_i = $(to_host)(input[i]); - item32_sc8_to_$(cpu_type)(item_i, output[j], dummy, scale_factor); + if (num_samps != num_pairs*2){ + const item32_t item_n = $(to_host)(input[num_pairs]); + item32_sc8_to_$(cpu_type)(item_n, output[num_samps-1], dummy, scale_factor); } } """ -- cgit v1.2.3 From 00b6d8359de6ea616f7bd6573d7f87d635d78a79 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 13 Oct 2011 13:08:12 -0700 Subject: uhd: added trailer parsing for occupancy --- host/include/uhd/transport/vrt_if_packet.hpp | 1 + host/lib/convert/gen_convert_general.py | 1 + host/lib/transport/gen_vrt_if_packet.py | 51 ++++++++++++++++-------- host/lib/transport/super_recv_packet_handler.hpp | 11 ++--- host/lib/transport/super_send_packet_handler.hpp | 3 +- host/lib/usrp/cores/rx_dsp_core_200.cpp | 3 +- host/lib/usrp/cores/tx_dsp_core_200.cpp | 3 +- host/lib/usrp/usrp1/io_impl.cpp | 1 + 8 files changed, 46 insertions(+), 28 deletions(-) (limited to 'host/lib/convert/gen_convert_general.py') diff --git a/host/include/uhd/transport/vrt_if_packet.hpp b/host/include/uhd/transport/vrt_if_packet.hpp index 51bd81bb1..1be480874 100644 --- a/host/include/uhd/transport/vrt_if_packet.hpp +++ b/host/include/uhd/transport/vrt_if_packet.hpp @@ -44,6 +44,7 @@ namespace vrt{ //size fields size_t num_payload_words32; //required in pack, derived in unpack + size_t num_payload_bytes; //required in pack, derived in unpack size_t num_header_words32; //derived in pack, derived in unpack size_t num_packet_words32; //derived in pack, required in unpack diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index 9a1135b0b..be5a65130 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -48,6 +48,7 @@ DECLARE_CONVERTER(sc16_item32_$(end), 1, $(cpu_type), 1, PRIORITY_GENERAL){ } DECLARE_CONVERTER(sc8_item32_$(end), 1, $(cpu_type), 1, PRIORITY_GENERAL){ + if (nsamps == 0) return; //otherwise segfault const item32_t *input = reinterpret_cast(size_t(inputs[0]) & ~0x3); $(cpu_type)_t *output = reinterpret_cast<$(cpu_type)_t *>(outputs[0]); $(cpu_type)_t dummy; diff --git a/host/lib/transport/gen_vrt_if_packet.py b/host/lib/transport/gen_vrt_if_packet.py index 5f048d8c7..245a7ddbd 100755 --- a/host/lib/transport/gen_vrt_if_packet.py +++ b/host/lib/transport/gen_vrt_if_packet.py @@ -70,6 +70,10 @@ static pred_table_type get_pred_unpack_table(void){ static const pred_table_type pred_unpack_table(get_pred_unpack_table()); +//maps trailer bits to num empty bytes +//maps num empty bytes to trailer bits +static const size_t occ_table[] = {0, 2, 1, 3}; + ######################################################################## #def gen_code($XE_MACRO, $suffix) ######################################################################## @@ -122,14 +126,6 @@ void vrt::if_hdr_pack_$(suffix)( #set $num_header_words += 1 #set $flags |= (0x1 << 20); #end if - ########## Trailer ########## - #if $pred & $tlr_p - //packet_buff[$num_header_words+if_packet_info.num_payload_words32] = $(XE_MACRO)(if_packet_info.tlr); - #set $flags |= (0x1 << 26); - #set $num_trailer_words = 1; - #else - #set $num_trailer_words = 0; - #end if ########## Burst Flags ########## #if $pred & $eob_p #set $flags |= (0x1 << 24); @@ -137,6 +133,18 @@ void vrt::if_hdr_pack_$(suffix)( #if $pred & $sob_p #set $flags |= (0x1 << 25); #end if + ########## Trailer ########## + #if $pred & $tlr_p + { + const size_t empty_bytes = if_packet_info.num_payload_words32*sizeof(boost::uint32_t) - if_packet_info.num_payload_bytes; + if_packet_info.tlr |= (0x3 << 22) | (occ_table[empty_bytes & 0x3] << 10); + } + packet_buff[$num_header_words+if_packet_info.num_payload_words32] = $(XE_MACRO)(if_packet_info.tlr); + #set $flags |= (0x1 << 26); + #set $num_trailer_words = 1; + #else + #set $num_trailer_words = 0; + #end if ########## Variables ########## if_packet_info.num_header_words32 = $num_header_words; if_packet_info.num_packet_words32 = $($num_header_words + $num_trailer_words) + if_packet_info.num_payload_words32; @@ -172,6 +180,8 @@ void vrt::if_hdr_unpack_$(suffix)( const pred_type pred = pred_unpack_table[pred_table_index(vrt_hdr_word)]; + size_t empty_bytes = 0; + switch(pred){ #for $pred in range(2**7) case $pred: @@ -211,15 +221,6 @@ void vrt::if_hdr_unpack_$(suffix)( #else if_packet_info.has_tsf = false; #end if - ########## Trailer ########## - #if $pred & $tlr_p - if_packet_info.has_tlr = true; - if_packet_info.tlr = $(XE_MACRO)(packet_buff[packet_words32-1]); - #set $num_trailer_words = 1; - #else - if_packet_info.has_tlr = false; - #set $num_trailer_words = 0; - #end if ########## Burst Flags ########## #if $pred & $eob_p if_packet_info.eob = true; @@ -231,12 +232,28 @@ void vrt::if_hdr_unpack_$(suffix)( #else if_packet_info.sob = false; #end if + ########## Trailer ########## + #if $pred & $tlr_p + if_packet_info.has_tlr = true; + if_packet_info.tlr = $(XE_MACRO)(packet_buff[packet_words32-1]); + #set $num_trailer_words = 1; + { + const int indicators = (if_packet_info.tlr >> 20) & (if_packet_info.tlr >> 8); + if ((indicators & (1 << 0)) != 0) if_packet_info.eob = true; + if ((indicators & (1 << 1)) != 0) if_packet_info.sob = true; + empty_bytes = occ_table[(indicators >> 2) & 0x3]; + } + #else + if_packet_info.has_tlr = false; + #set $num_trailer_words = 0; + #end if ########## Variables ########## //another failure case if (packet_words32 < $($num_header_words + $num_trailer_words)) throw uhd::value_error("bad vrt header or invalid packet length"); if_packet_info.num_header_words32 = $num_header_words; if_packet_info.num_payload_words32 = packet_words32 - $($num_header_words + $num_trailer_words); + if_packet_info.num_payload_bytes = if_packet_info.num_payload_words32*sizeof(boost::uint32_t) - empty_bytes; break; #end for } diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp index 2310d6aea..48b0acdb9 100644 --- a/host/lib/transport/super_recv_packet_handler.hpp +++ b/host/lib/transport/super_recv_packet_handler.hpp @@ -327,7 +327,7 @@ private: info.alignment_time = info[index].time; info.indexes_todo.set(); info.indexes_todo.reset(index); - info.data_bytes_to_copy = info[index].ifpi.num_payload_words32*sizeof(boost::uint32_t); + info.data_bytes_to_copy = info[index].ifpi.num_payload_bytes; } //if the sequence id matches: @@ -471,13 +471,8 @@ private: curr_info.metadata.time_spec = curr_info[0].time; curr_info.metadata.more_fragments = false; curr_info.metadata.fragment_offset = 0; - /* TODO SOB on RX not supported in hardware - static const int tlr_sob_flags = (1 << 21) | (1 << 9); //enable and indicator bits - curr_info.metadata.start_of_burst = curr_info[0].ifpi.has_tlr and (int(curr_info[0].ifpi.tlr & tlr_sob_flags) != 0); - */ - curr_info.metadata.start_of_burst = false; - static const int tlr_eob_flags = (1 << 20) | (1 << 8); //enable and indicator bits - curr_info.metadata.end_of_burst = curr_info[0].ifpi.has_tlr and (int(curr_info[0].ifpi.tlr & tlr_eob_flags) != 0); + curr_info.metadata.start_of_burst = curr_info[0].ifpi.sob; + curr_info.metadata.end_of_burst = curr_info[0].ifpi.eob; curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_NONE; } diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp index 779259d4f..5696b5d39 100644 --- a/host/lib/transport/super_send_packet_handler.hpp +++ b/host/lib/transport/super_send_packet_handler.hpp @@ -219,7 +219,8 @@ private: const size_t buffer_offset_bytes = 0 ){ //load the rest of the if_packet_info in here - if_packet_info.num_payload_words32 = (nsamps_per_buff*_io_buffs.size()*_bytes_per_otw_item)/sizeof(boost::uint32_t); + if_packet_info.num_payload_bytes = nsamps_per_buff*_io_buffs.size()*_bytes_per_otw_item; + if_packet_info.num_payload_words32 = (if_packet_info.num_payload_bytes + 3/*round up*/)/sizeof(boost::uint32_t); if_packet_info.packet_count = _next_packet_seq; size_t buff_index = 0; diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index 023216a09..b121bc849 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -130,7 +130,8 @@ public: } void set_link_rate(const double rate){ - _link_rate = rate/sizeof(boost::uint32_t); //in samps/s + //_link_rate = rate/sizeof(boost::uint32_t); //in samps/s + _link_rate = rate/sizeof(boost::uint16_t); //in samps/s (allows for 8sc) } double set_host_rate(const double rate){ diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp index 04e9f5da4..f37b53527 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp @@ -70,7 +70,8 @@ public: } void set_link_rate(const double rate){ - _link_rate = rate/sizeof(boost::uint32_t); //in samps/s + //_link_rate = rate/sizeof(boost::uint32_t); //in samps/s + _link_rate = rate/sizeof(boost::uint16_t); //in samps/s (allows for 8sc) } double set_host_rate(const double rate){ diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp index 534d33959..12950d385 100644 --- a/host/lib/usrp/usrp1/io_impl.cpp +++ b/host/lib/usrp/usrp1/io_impl.cpp @@ -111,6 +111,7 @@ static void usrp1_bs_vrt_unpacker( ){ if_packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; if_packet_info.num_payload_words32 = if_packet_info.num_packet_words32; + if_packet_info.num_payload_bytes = if_packet_info.num_packet_words32*sizeof(boost::uint32_t); if_packet_info.num_header_words32 = 0; if_packet_info.packet_count = 0; if_packet_info.sob = false; -- cgit v1.2.3 From 929571756901c96a984bbb4e415478ac3deb1784 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 13 Oct 2011 13:26:07 -0700 Subject: uhd: added converter for item32 as cpu type --- host/lib/convert/gen_convert_general.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'host/lib/convert/gen_convert_general.py') diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index be5a65130..eafb145e6 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -28,6 +28,30 @@ TMPL_HEADER = """ using namespace uhd::convert; """ +TMPL_CONV_GEN2_ITEM32 = """ +DECLARE_CONVERTER(item32, 1, sc16_item32_$(end), 1, PRIORITY_GENERAL){ + const item32_t *input = reinterpret_cast(inputs[0]); + item32_t *output = reinterpret_cast(outputs[0]); + + if (scale_factor == 0){} //avoids unused warning + + for (size_t i = 0; i < nsamps; i++){ + output[i] = $(to_wire)(input[i]); + } +} + +DECLARE_CONVERTER(sc16_item32_$(end), 1, item32, 1, PRIORITY_GENERAL){ + const item32_t *input = reinterpret_cast(inputs[0]); + item32_t *output = reinterpret_cast(outputs[0]); + + if (scale_factor == 0){} //avoids unused warning + + for (size_t i = 0; i < nsamps; i++){ + output[i] = $(to_host)(input[i]); + } +} +""" + TMPL_CONV_GEN2_COMPLEX = """ DECLARE_CONVERTER($(cpu_type), 1, sc16_item32_$(end), 1, PRIORITY_GENERAL){ const $(cpu_type)_t *input = reinterpret_cast(inputs[0]); @@ -150,6 +174,10 @@ if __name__ == '__main__': TMPL_CONV_GEN2_COMPLEX, end=end, to_host=to_host, to_wire=to_wire, cpu_type=cpu_type ) + output += parse_tmpl( + TMPL_CONV_GEN2_ITEM32, + end=end, to_host=to_host, to_wire=to_wire + ) #generate complex converters for usrp1 format for width in 1, 2, 4: -- cgit v1.2.3 From d28e3ac765273d7684386c1985802000d22eeea6 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 7 Nov 2011 16:34:13 -0800 Subject: uhd: dont pass 0 sample buffs to converter (avoid segfaults) --- host/lib/convert/gen_convert_general.py | 1 - host/lib/transport/super_recv_packet_handler.hpp | 4 +++- host/lib/transport/super_send_packet_handler.hpp | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'host/lib/convert/gen_convert_general.py') diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index eafb145e6..52b4212b4 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -72,7 +72,6 @@ DECLARE_CONVERTER(sc16_item32_$(end), 1, $(cpu_type), 1, PRIORITY_GENERAL){ } DECLARE_CONVERTER(sc8_item32_$(end), 1, $(cpu_type), 1, PRIORITY_GENERAL){ - if (nsamps == 0) return; //otherwise segfault const item32_t *input = reinterpret_cast(size_t(inputs[0]) & ~0x3); $(cpu_type)_t *output = reinterpret_cast<$(cpu_type)_t *>(outputs[0]); $(cpu_type)_t dummy; diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp index 48b0acdb9..57aae96b1 100644 --- a/host/lib/transport/super_recv_packet_handler.hpp +++ b/host/lib/transport/super_recv_packet_handler.hpp @@ -523,7 +523,9 @@ private: } //copy-convert the samples from the recv buffer - _converter(buff_info.copy_buff, _io_buffs, nsamps_to_copy_per_io_buff, _scale_factor); + if (nsamps_to_copy_per_io_buff != 0) _converter( + buff_info.copy_buff, _io_buffs, nsamps_to_copy_per_io_buff, _scale_factor + ); //update the rx copy buffer to reflect the bytes copied buff_info.copy_buff += bytes_to_copy; diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp index 5696b5d39..c3ffcc861 100644 --- a/host/lib/transport/super_send_packet_handler.hpp +++ b/host/lib/transport/super_send_packet_handler.hpp @@ -239,7 +239,9 @@ private: otw_mem += if_packet_info.num_header_words32; //copy-convert the samples into the send buffer - _converter(_io_buffs, otw_mem, nsamps_per_buff, _scale_factor); + if (nsamps_per_buff != 0) _converter( + _io_buffs, otw_mem, nsamps_per_buff, _scale_factor + ); //commit the samples to the zero-copy interface size_t num_bytes_total = (_header_offset_words32+if_packet_info.num_packet_words32)*sizeof(boost::uint32_t); -- cgit v1.2.3