diff options
author | Josh Blum <josh@joshknows.com> | 2011-10-06 18:41:59 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2011-11-03 20:37:11 -0700 |
commit | 4c4f0810ef06be18e989b6933ff236ff97c13dd0 (patch) | |
tree | ce506b4f259d31d966b847dde9adddf07f09f753 | |
parent | de17ef4614c3c14212f239e3c735bfde3f47a68f (diff) | |
download | uhd-4c4f0810ef06be18e989b6933ff236ff97c13dd0.tar.gz uhd-4c4f0810ef06be18e989b6933ff236ff97c13dd0.tar.bz2 uhd-4c4f0810ef06be18e989b6933ff236ff97c13dd0.zip |
usrp1: type conversions and 8-bit work
-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); |