summaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-10-06 18:41:59 -0700
committerJosh Blum <josh@joshknows.com>2011-11-03 20:37:11 -0700
commit4c4f0810ef06be18e989b6933ff236ff97c13dd0 (patch)
treece506b4f259d31d966b847dde9adddf07f09f753 /host/lib
parentde17ef4614c3c14212f239e3c735bfde3f47a68f (diff)
downloaduhd-4c4f0810ef06be18e989b6933ff236ff97c13dd0.tar.gz
uhd-4c4f0810ef06be18e989b6933ff236ff97c13dd0.tar.bz2
uhd-4c4f0810ef06be18e989b6933ff236ff97c13dd0.zip
usrp1: type conversions and 8-bit work
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/convert/convert_common.hpp12
-rw-r--r--host/lib/convert/gen_convert_general.py102
-rw-r--r--host/lib/usrp/usrp1/io_impl.cpp69
-rw-r--r--host/lib/usrp/usrp1/usrp1_calc_mux.hpp4
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.cpp4
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.hpp4
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);