diff options
26 files changed, 539 insertions, 113 deletions
diff --git a/fpga/usrp2/sdr_lib/dspengine_16to8.v b/fpga/usrp2/sdr_lib/dspengine_16to8.v index 448c57d35..1d6746dd1 100644 --- a/fpga/usrp2/sdr_lib/dspengine_16to8.v +++ b/fpga/usrp2/sdr_lib/dspengine_16to8.v @@ -1,5 +1,5 @@ -// Copyright 2011-2012 Ettus Research LLC +// Copyright 2011-2013 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -181,8 +181,8 @@ module dspengine_16to8 assign access_dat_o = (dsp_state == DSP_WRITE_HEADER) ? { 4'h1, new_header } : (dsp_state == DSP_WRITE_TRAILER) ? { 4'h2, new_trailer } : - (last_o&~even_o) ? {4'h0, 16'd0, i8, q8 } : - {4'h0, i8, q8, i8_reg, q8_reg }; + (last_o&~even_o) ? {4'h0, i8, q8, 16'd0 } : + {4'h0, i8_reg, q8_reg, i8, q8 }; assign access_adr = (stb_write|(dsp_state == DSP_WRITE_HEADER)|(dsp_state == DSP_WRITE_TRAILER)) ? write_adr : read_adr; diff --git a/fpga/usrp2/sdr_lib/dspengine_8to16.v b/fpga/usrp2/sdr_lib/dspengine_8to16.v index 85187d78d..64246ac13 100644 --- a/fpga/usrp2/sdr_lib/dspengine_8to16.v +++ b/fpga/usrp2/sdr_lib/dspengine_8to16.v @@ -1,5 +1,5 @@ -// Copyright 2012 Ettus Research LLC +// Copyright 2012-2013 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -75,13 +75,13 @@ module dspengine_8to16 wire [15:0] data_in_lenx2 = {data_in_len[14:0], 1'b0} - is_odd; reg [7:0] i8_0, q8_0; - wire [7:0] i8_1 = access_dat_i[31:24]; - wire [7:0] q8_1 = access_dat_i[23:16]; + wire [7:0] i8_1 = access_dat_i[15:8]; + wire [7:0] q8_1 = access_dat_i[7:0]; reg skip; always @(posedge clk) - { i8_0, q8_0 } <= access_dat_i[15:0]; + { i8_0, q8_0 } <= access_dat_i[31:16]; always @(posedge clk) if(reset | clear) diff --git a/fpga/usrp2/top/B100/u1plus_core.v b/fpga/usrp2/top/B100/u1plus_core.v index 9fe09c60e..7f137f0d1 100644 --- a/fpga/usrp2/top/B100/u1plus_core.v +++ b/fpga/usrp2/top/B100/u1plus_core.v @@ -1,5 +1,5 @@ // -// Copyright 2011-2012 Ettus Research LLC +// Copyright 2011-2013 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -71,7 +71,7 @@ module u1plus_core localparam SR_GPIO = 224; // 5 //compatibility number -> increment when the fpga has been sufficiently altered - localparam compat_num = {16'd11, 16'd3}; //major, minor + localparam compat_num = {16'd11, 16'd4}; //major, minor //assign run signals used for ATR logic wire [NUM_RX_DSPS-1:0] run_rx_n; diff --git a/fpga/usrp2/top/N2x0/u2plus_core.v b/fpga/usrp2/top/N2x0/u2plus_core.v index e2539e183..f616681d2 100644 --- a/fpga/usrp2/top/N2x0/u2plus_core.v +++ b/fpga/usrp2/top/N2x0/u2plus_core.v @@ -1,5 +1,5 @@ // -// Copyright 2011-2012 Ettus Research LLC +// Copyright 2011-2013 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -448,7 +448,7 @@ module u2plus_core // Buffer Pool Status -- Slave #5 //compatibility number -> increment when the fpga has been sufficiently altered - localparam compat_num = {16'd10, 16'd0}; //major, minor + localparam compat_num = {16'd10, 16'd1}; //major, minor wire [31:0] irq_readback = {18'b0, button, spi_ready, clk_status, serdes_link_up, 10'b0}; diff --git a/fpga/usrp2/top/USRP2/u2_core.v b/fpga/usrp2/top/USRP2/u2_core.v index d8fe8cf10..aed69a9bd 100644 --- a/fpga/usrp2/top/USRP2/u2_core.v +++ b/fpga/usrp2/top/USRP2/u2_core.v @@ -1,5 +1,5 @@ // -// Copyright 2011-2012 Ettus Research LLC +// Copyright 2011-2013 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -456,7 +456,7 @@ module u2_core // Buffer Pool Status -- Slave #5 //compatibility number -> increment when the fpga has been sufficiently altered - localparam compat_num = {16'd10, 16'd0}; //major, minor + localparam compat_num = {16'd10, 16'd1}; //major, minor wire [31:0] irq_readback = {19'b0, spi_ready, clk_status, serdes_link_up, 10'b0}; diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index d6851156a..9630240cf 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -110,7 +110,7 @@ IF(MSVC) -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE ) - ADD_DEFINITIONS(/MP) + ADD_DEFINITIONS(/MP) #multi-threaded build ENDIF(MSVC) IF(CYGWIN) diff --git a/host/lib/convert/CMakeLists.txt b/host/lib/convert/CMakeLists.txt index 28defa8bc..00e129b78 100644 --- a/host/lib/convert/CMakeLists.txt +++ b/host/lib/convert/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2011-2012 Ettus Research LLC +# Copyright 2011-2013 Ettus Research LLC # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -121,4 +121,7 @@ LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/convert_with_tables.cpp ${CMAKE_CURRENT_SOURCE_DIR}/convert_impl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/convert_item32.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/convert_pack_sc12.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/convert_unpack_sc12.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/convert_fc32_item32.cpp ) diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp index 933978a8f..ceaa1151c 100644 --- a/host/lib/convert/convert_common.hpp +++ b/host/lib/convert/convert_common.hpp @@ -1,5 +1,5 @@ // -// Copyright 2011-2012 Ettus Research LLC +// Copyright 2011-2013 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -150,10 +150,10 @@ UHD_INLINE void item32_sc16_to_xx( template <typename T> UHD_INLINE item32_t xx_to_item32_sc8_x1( const std::complex<T> &in0, const std::complex<T> &in1, const double scale_factor ){ - boost::uint8_t real0 = boost::int8_t(in0.real()*float(scale_factor)); - boost::uint8_t imag0 = boost::int8_t(in0.imag()*float(scale_factor)); - boost::uint8_t real1 = boost::int8_t(in1.real()*float(scale_factor)); - boost::uint8_t imag1 = boost::int8_t(in1.imag()*float(scale_factor)); + boost::uint8_t real1 = boost::int8_t(in0.real()*float(scale_factor)); + boost::uint8_t imag1 = boost::int8_t(in0.imag()*float(scale_factor)); + boost::uint8_t real0 = boost::int8_t(in1.real()*float(scale_factor)); + boost::uint8_t imag0 = boost::int8_t(in1.imag()*float(scale_factor)); return (item32_t(real0) << 8) | (item32_t(imag0) << 0) | (item32_t(real1) << 24) | (item32_t(imag1) << 16) @@ -163,10 +163,10 @@ template <typename T> UHD_INLINE item32_t xx_to_item32_sc8_x1( template <> UHD_INLINE item32_t xx_to_item32_sc8_x1( const sc16_t &in0, const sc16_t &in1, const double ){ - boost::uint8_t real0 = boost::int8_t(in0.real()); - boost::uint8_t imag0 = boost::int8_t(in0.imag()); - boost::uint8_t real1 = boost::int8_t(in1.real()); - boost::uint8_t imag1 = boost::int8_t(in1.imag()); + boost::uint8_t real1 = boost::int8_t(in0.real()); + boost::uint8_t imag1 = boost::int8_t(in0.imag()); + boost::uint8_t real0 = boost::int8_t(in1.real()); + boost::uint8_t imag0 = boost::int8_t(in1.imag()); return (item32_t(real0) << 8) | (item32_t(imag0) << 0) | (item32_t(real1) << 24) | (item32_t(imag1) << 16) @@ -176,10 +176,10 @@ template <> UHD_INLINE item32_t xx_to_item32_sc8_x1( template <> UHD_INLINE item32_t xx_to_item32_sc8_x1( const sc8_t &in0, const sc8_t &in1, const double ){ - boost::uint8_t real0 = boost::int8_t(in0.real()); - boost::uint8_t imag0 = boost::int8_t(in0.imag()); - boost::uint8_t real1 = boost::int8_t(in1.real()); - boost::uint8_t imag1 = boost::int8_t(in1.imag()); + boost::uint8_t real1 = boost::int8_t(in0.real()); + boost::uint8_t imag1 = boost::int8_t(in0.imag()); + boost::uint8_t real0 = boost::int8_t(in1.real()); + boost::uint8_t imag0 = boost::int8_t(in1.imag()); return (item32_t(real0) << 8) | (item32_t(imag0) << 0) | (item32_t(real1) << 24) | (item32_t(imag1) << 16) @@ -211,11 +211,11 @@ UHD_INLINE void xx_to_item32_sc8( template <typename T> UHD_INLINE void item32_sc8_x1_to_xx( const item32_t item, std::complex<T> &out0, std::complex<T> &out1, const double scale_factor ){ - out0 = std::complex<T>( + out1 = std::complex<T>( T(boost::int8_t(item >> 8)*float(scale_factor)), T(boost::int8_t(item >> 0)*float(scale_factor)) ); - out1 = std::complex<T>( + out0 = std::complex<T>( T(boost::int8_t(item >> 24)*float(scale_factor)), T(boost::int8_t(item >> 16)*float(scale_factor)) ); @@ -224,11 +224,11 @@ template <typename T> UHD_INLINE void item32_sc8_x1_to_xx( template <> UHD_INLINE void item32_sc8_x1_to_xx( const item32_t item, sc16_t &out0, sc16_t &out1, const double ){ - out0 = sc16_t( + out1 = sc16_t( boost::int16_t(boost::int8_t(item >> 8)), boost::int16_t(boost::int8_t(item >> 0)) ); - out1 = sc16_t( + out0 = sc16_t( boost::int16_t(boost::int8_t(item >> 24)), boost::int16_t(boost::int8_t(item >> 16)) ); @@ -237,11 +237,11 @@ template <> UHD_INLINE void item32_sc8_x1_to_xx( template <> UHD_INLINE void item32_sc8_x1_to_xx( const item32_t item, sc8_t &out0, sc8_t &out1, const double ){ - out0 = sc8_t( + out1 = sc8_t( boost::int8_t(boost::int8_t(item >> 8)), boost::int8_t(boost::int8_t(item >> 0)) ); - out1 = sc8_t( + out0 = sc8_t( boost::int8_t(boost::int8_t(item >> 24)), boost::int8_t(boost::int8_t(item >> 16)) ); diff --git a/host/lib/convert/convert_fc32_item32.cpp b/host/lib/convert/convert_fc32_item32.cpp new file mode 100644 index 000000000..29bfefd46 --- /dev/null +++ b/host/lib/convert/convert_fc32_item32.cpp @@ -0,0 +1,113 @@ +// +// Copyright 2013 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include "convert_common.hpp" +#include <uhd/utils/byteswap.hpp> +#include <uhd/utils/msg.hpp> +#include <boost/math/special_functions/round.hpp> +#include <vector> + +using namespace uhd::convert; + +typedef boost::uint32_t (*to32_type)(boost::uint32_t); + +template <typename type, to32_type tohost> +struct convert_fc32_item32_1_to_star_1 : public converter +{ + convert_fc32_item32_1_to_star_1(void) + { + //NOP + } + + void set_scalar(const double scalar) + { + _scalar = scalar; + } + + void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps) + { + const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); + std::complex<type> *output = reinterpret_cast<std::complex<type> *>(outputs[0]); + + size_t i = 0; + for (size_t o = 0; o < nsamps; o++) + { + const item32_t i32 = tohost(input[i++]); + const item32_t q32 = tohost(input[i++]); + const float i_f32 = reinterpret_cast<const float &>(i32); + const float q_f32 = reinterpret_cast<const float &>(q32); + output[o] = std::complex<type>(type(i_f32*_scalar), type(q_f32*_scalar)); + } + } + + double _scalar; +}; + +template <typename type, to32_type towire> +struct convert_star_1_to_fc32_item32_1 : public converter +{ + convert_star_1_to_fc32_item32_1(void) + { + //NOP + } + + void set_scalar(const double scalar) + { + _scalar = scalar; + } + + void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps) + { + const std::complex<type> *input = reinterpret_cast<const std::complex<type> *>(inputs[0]); + item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); + + size_t o = 0; + for (size_t i = 0; i < nsamps; i++) + { + const float i_f32 = type(input[i].real()*_scalar); + const float q_f32 = type(input[i].imag()*_scalar); + const item32_t i32 = towire(reinterpret_cast<const item32_t &>(i_f32)); + const item32_t q32 = towire(reinterpret_cast<const item32_t &>(q_f32)); + output[o++] = i32; output[o++] = q32; + } + } + + double _scalar; +}; + +#define __make_registrations(itype, otype, fcn, type, conv) \ +static converter::sptr make_convert_ ## itype ## _1_ ## otype ## _1(void) \ +{ \ + return converter::sptr(new fcn<type, conv>()); \ +} \ +UHD_STATIC_BLOCK(register_convert_ ## itype ## _1_ ## otype ## _1) \ +{ \ + uhd::convert::id_type id; \ + id.num_inputs = 1; id.num_outputs = 1; \ + id.input_format = #itype; id.output_format = #otype; \ + uhd::convert::register_converter(id, &make_convert_ ## itype ## _1_ ## otype ## _1, PRIORITY_GENERAL); \ +} + +__make_registrations(fc32_item32_le, fc32, convert_fc32_item32_1_to_star_1, float, uhd::wtohx) +__make_registrations(fc32_item32_be, fc32, convert_fc32_item32_1_to_star_1, float, uhd::ntohx) +__make_registrations(fc32_item32_le, fc64, convert_fc32_item32_1_to_star_1, double, uhd::wtohx) +__make_registrations(fc32_item32_be, fc64, convert_fc32_item32_1_to_star_1, double, uhd::ntohx) + +__make_registrations(fc32, fc32_item32_le, convert_star_1_to_fc32_item32_1, float, uhd::wtohx) +__make_registrations(fc32, fc32_item32_be, convert_star_1_to_fc32_item32_1, float, uhd::ntohx) +__make_registrations(fc64, fc32_item32_le, convert_star_1_to_fc32_item32_1, double, uhd::wtohx) +__make_registrations(fc64, fc32_item32_be, convert_star_1_to_fc32_item32_1, double, uhd::ntohx) diff --git a/host/lib/convert/convert_orc.orc b/host/lib/convert/convert_orc.orc index f7075606e..ffb298f26 100644 --- a/host/lib/convert/convert_orc.orc +++ b/host/lib/convert/convert_orc.orc @@ -75,6 +75,5 @@ swapl dst, src .floatparam 4 scalar x2 mulf tmp, src, scalar x2 convfl tmp, tmp -swaplq tmp, tmp x2 convlw tmp2, tmp x2 convwb dst, tmp2 diff --git a/host/lib/convert/convert_pack_sc12.cpp b/host/lib/convert/convert_pack_sc12.cpp new file mode 100644 index 000000000..680814994 --- /dev/null +++ b/host/lib/convert/convert_pack_sc12.cpp @@ -0,0 +1,144 @@ +// +// Copyright 2013 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include "convert_common.hpp" +#include <uhd/utils/byteswap.hpp> +#include <uhd/utils/msg.hpp> +#include <boost/math/special_functions/round.hpp> +#include <vector> + +using namespace uhd::convert; + +typedef boost::uint32_t (*towire32_type)(boost::uint32_t); + +struct item32_sc12_3x +{ + item32_t line0; + item32_t line1; + item32_t line2; +}; + +template <typename type, towire32_type towire> +void convert_star_4_to_sc12_item32_3 +( + const std::complex<type> &in0, + const std::complex<type> &in1, + const std::complex<type> &in2, + const std::complex<type> &in3, + item32_sc12_3x &output, + const double scalar +) +{ + const item32_t i0 = boost::int32_t(type(in0.real()*scalar)) & 0xfff; + const item32_t q0 = boost::int32_t(type(in0.imag()*scalar)) & 0xfff; + + const item32_t i1 = boost::int32_t(type(in1.real()*scalar)) & 0xfff; + const item32_t q1 = boost::int32_t(type(in1.imag()*scalar)) & 0xfff; + + const item32_t i2 = boost::int32_t(type(in2.real()*scalar)) & 0xfff; + const item32_t q2 = boost::int32_t(type(in2.imag()*scalar)) & 0xfff; + + const item32_t i3 = boost::int32_t(type(in3.real()*scalar)) & 0xfff; + const item32_t q3 = boost::int32_t(type(in3.imag()*scalar)) & 0xfff; + + const item32_t line0 = (i0 << 20) | (q0 << 8) | (i1 >> 4); + const item32_t line1 = (i1 << 28) | (q1 << 16) | (i2 << 4) | (q2 >> 8); + const item32_t line2 = (q2 << 24) | (i3 << 12) | (q3); + + output.line0 = towire(line0); + output.line1 = towire(line1); + output.line2 = towire(line2); +} + +template <typename type, towire32_type towire> +struct convert_star_1_to_sc12_item32_1 : public converter +{ + convert_star_1_to_sc12_item32_1(void) + { + //NOP + } + + void set_scalar(const double scalar) + { + _scalar = scalar; + } + + void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps) + { + const std::complex<type> *input = reinterpret_cast<const std::complex<type> *>(inputs[0]); + item32_sc12_3x *output = reinterpret_cast<item32_sc12_3x *>(size_t(outputs[0]) & ~0x3); + + //helper variables + size_t i = 0, o = 0; + + //handle the head case + const size_t head_samps = size_t(outputs[0]) & 0x3; + switch (head_samps) + { + case 0: break; //no head + case 1: convert_star_4_to_sc12_item32_3<type, towire>(0, 0, 0, input[0], output[o++], _scalar); break; + case 2: convert_star_4_to_sc12_item32_3<type, towire>(0, 0, input[0], input[1], output[o++], _scalar); break; + case 3: convert_star_4_to_sc12_item32_3<type, towire>(0, input[0], input[1], input[2], output[o++], _scalar); break; + } + i += head_samps; + + //convert the body + while (i+3 < nsamps) + { + convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], input[i+1], input[i+2], input[i+3], output[o], _scalar); + o++; i += 4; + } + + //handle the tail case + const size_t tail_samps = nsamps - i; + switch (tail_samps) + { + case 0: break; //no tail + case 1: convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], 0, 0, 0, output[o], _scalar); break; + case 2: convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], input[i+1], 0, 0, output[o], _scalar); break; + case 3: convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], input[i+1], input[i+2], 0, output[o], _scalar); break; + } + } + + double _scalar; +}; + +static converter::sptr make_convert_fc32_1_to_sc12_item32_le_1(void) +{ + return converter::sptr(new convert_star_1_to_sc12_item32_1<float, uhd::wtohx>()); +} + +static converter::sptr make_convert_fc32_1_to_sc12_item32_be_1(void) +{ + return converter::sptr(new convert_star_1_to_sc12_item32_1<float, uhd::ntohx>()); +} + +UHD_STATIC_BLOCK(register_convert_pack_sc12) +{ + //uhd::convert::register_bytes_per_item("sc12", 3/*bytes*/); //registered in unpack + + uhd::convert::id_type id; + id.num_inputs = 1; + id.num_outputs = 1; + id.input_format = "fc32"; + + id.output_format = "sc12_item32_le"; + uhd::convert::register_converter(id, &make_convert_fc32_1_to_sc12_item32_le_1, PRIORITY_GENERAL); + + id.output_format = "sc12_item32_be"; + uhd::convert::register_converter(id, &make_convert_fc32_1_to_sc12_item32_be_1, PRIORITY_GENERAL); +} diff --git a/host/lib/convert/convert_unpack_sc12.cpp b/host/lib/convert/convert_unpack_sc12.cpp new file mode 100644 index 000000000..f578b6c95 --- /dev/null +++ b/host/lib/convert/convert_unpack_sc12.cpp @@ -0,0 +1,152 @@ +// +// Copyright 2013 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include "convert_common.hpp" +#include <uhd/utils/byteswap.hpp> +#include <uhd/utils/msg.hpp> +#include <boost/math/special_functions/round.hpp> +#include <vector> + +using namespace uhd::convert; + +typedef boost::uint32_t (*tohost32_type)(boost::uint32_t); + +struct item32_sc12_3x +{ + item32_t line0; + item32_t line1; + item32_t line2; +}; + +template <typename type, tohost32_type tohost> +void convert_sc12_item32_3_to_star_4 +( + const item32_sc12_3x &input, + std::complex<type> &out0, + std::complex<type> &out1, + std::complex<type> &out2, + std::complex<type> &out3, + const double scalar +) +{ + //step 0: extract the lines from the input buffer + const item32_t line0 = tohost(input.line0); + const item32_t line1 = tohost(input.line1); + const item32_t line2 = tohost(input.line2); + const boost::uint64_t line01 = (boost::uint64_t(line0) << 32) | line1; + const boost::uint64_t line12 = (boost::uint64_t(line1) << 32) | line2; + + //step 1: shift out and mask off the individual numbers + const type i0 = type(boost::int16_t(line0 >> 16)*scalar); + const type q0 = type(boost::int16_t(line0 >> 4)*scalar); + + const type i1 = type(boost::int16_t(line01 >> 24)*scalar); + const type q1 = type(boost::int16_t(line1 >> 12)*scalar); + + const type i2 = type(boost::int16_t(line1 >> 0)*scalar); + const type q2 = type(boost::int16_t(line12 >> 20)*scalar); + + const type i3 = type(boost::int16_t(line2 >> 8)*scalar); + const type q3 = type(boost::int16_t(line2 << 4)*scalar); + + //step 2: load the outputs + out0 = std::complex<type>(i0, q0); + out1 = std::complex<type>(i1, q1); + out2 = std::complex<type>(i2, q2); + out3 = std::complex<type>(i3, q3); +} + +template <typename type, tohost32_type tohost> +struct convert_sc12_item32_1_to_star_1 : public converter +{ + convert_sc12_item32_1_to_star_1(void) + { + //NOP + } + + void set_scalar(const double scalar) + { + const int unpack_growth = 16; + _scalar = scalar/unpack_growth; + } + + void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps) + { + const item32_sc12_3x *input = reinterpret_cast<const item32_sc12_3x *>(size_t(inputs[0]) & ~0x3); + std::complex<type> *output = reinterpret_cast<std::complex<type> *>(outputs[0]); + + //helper variables + std::complex<type> dummy0, dummy1, dummy2; + size_t i = 0, o = 0; + + //handle the head case + const size_t head_samps = size_t(inputs[0]) & 0x3; + switch (head_samps) + { + case 0: break; //no head + case 1: convert_sc12_item32_3_to_star_4<type, tohost>(input[i++], dummy0, dummy1, dummy2, output[0], _scalar); break; + case 2: convert_sc12_item32_3_to_star_4<type, tohost>(input[i++], dummy0, dummy1, output[0], output[1], _scalar); break; + case 3: convert_sc12_item32_3_to_star_4<type, tohost>(input[i++], dummy0, output[0], output[1], output[2], _scalar); break; + } + o += head_samps; + + //convert the body + while (o+3 < nsamps) + { + convert_sc12_item32_3_to_star_4<type, tohost>(input[i], output[o+0], output[o+1], output[o+2], output[o+3], _scalar); + i++; o += 4; + } + + //handle the tail case + const size_t tail_samps = nsamps - o; + switch (tail_samps) + { + case 0: break; //no tail + case 1: convert_sc12_item32_3_to_star_4<type, tohost>(input[i], output[o+0], dummy0, dummy1, dummy2, _scalar); break; + case 2: convert_sc12_item32_3_to_star_4<type, tohost>(input[i], output[o+0], output[o+1], dummy1, dummy2, _scalar); break; + case 3: convert_sc12_item32_3_to_star_4<type, tohost>(input[i], output[o+0], output[o+1], output[o+2], dummy2, _scalar); break; + } + } + + double _scalar; +}; + +static converter::sptr make_convert_sc12_item32_le_1_to_fc32_1(void) +{ + return converter::sptr(new convert_sc12_item32_1_to_star_1<float, uhd::wtohx>()); +} + +static converter::sptr make_convert_sc12_item32_be_1_to_fc32_1(void) +{ + return converter::sptr(new convert_sc12_item32_1_to_star_1<float, uhd::ntohx>()); +} + +UHD_STATIC_BLOCK(register_convert_unpack_sc12) +{ + uhd::convert::register_bytes_per_item("sc12", 3/*bytes*/); + + uhd::convert::id_type id; + id.num_inputs = 1; + id.num_outputs = 1; + id.output_format = "fc32"; + + id.input_format = "sc12_item32_le"; + uhd::convert::register_converter(id, &make_convert_sc12_item32_le_1_to_fc32_1, PRIORITY_GENERAL); + + id.input_format = "sc12_item32_be"; + uhd::convert::register_converter(id, &make_convert_sc12_item32_be_1_to_fc32_1, PRIORITY_GENERAL); +} diff --git a/host/lib/convert/convert_with_orc.cpp b/host/lib/convert/convert_with_orc.cpp index e44c8ca73..19755fa44 100644 --- a/host/lib/convert/convert_with_orc.cpp +++ b/host/lib/convert/convert_with_orc.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2013 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -57,9 +57,9 @@ DECLARE_CONVERTER(sc16_item32_le, 1, sc16, 1, PRIORITY_LIBORC){ DECLARE_CONVERTER(fc32, 1, sc8_item32_be, 1, PRIORITY_LIBORC){ _convert_fc32_1_to_sc8_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps); - _convert_swap_byte_pairs_orc(outputs[0], outputs[0], (nsamps + 1)/2); } DECLARE_CONVERTER(fc32, 1, sc8_item32_le, 1, PRIORITY_LIBORC){ _convert_fc32_1_to_sc8_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps); + _convert_swap_byte_pairs_orc(outputs[0], outputs[0], (nsamps + 1)/2); } diff --git a/host/lib/convert/convert_with_tables.cpp b/host/lib/convert/convert_with_tables.cpp index cd7773d4b..4d295fa01 100644 --- a/host/lib/convert/convert_with_tables.cpp +++ b/host/lib/convert/convert_with_tables.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011-2012 Ettus Research LLC +// Copyright 2011-2013 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -59,16 +59,16 @@ public: item32_t lookup(const sc16_t &in0, const sc16_t &in1){ if (swap){ //hope this compiles out, its a template constant return - (item32_t(_table[boost::uint16_t(in0.real())]) << 16) | - (item32_t(_table[boost::uint16_t(in0.imag())]) << 24) | - (item32_t(_table[boost::uint16_t(in1.real())]) << 0) | - (item32_t(_table[boost::uint16_t(in1.imag())]) << 8) ; + (item32_t(_table[boost::uint16_t(in1.real())]) << 16) | + (item32_t(_table[boost::uint16_t(in1.imag())]) << 24) | + (item32_t(_table[boost::uint16_t(in0.real())]) << 0) | + (item32_t(_table[boost::uint16_t(in0.imag())]) << 8) ; } return - (item32_t(_table[boost::uint16_t(in0.real())]) << 8) | - (item32_t(_table[boost::uint16_t(in0.imag())]) << 0) | - (item32_t(_table[boost::uint16_t(in1.real())]) << 24) | - (item32_t(_table[boost::uint16_t(in1.imag())]) << 16) ; + (item32_t(_table[boost::uint16_t(in1.real())]) << 8) | + (item32_t(_table[boost::uint16_t(in1.imag())]) << 0) | + (item32_t(_table[boost::uint16_t(in0.real())]) << 24) | + (item32_t(_table[boost::uint16_t(in0.imag())]) << 16) ; } private: @@ -196,27 +196,27 @@ static converter::sptr make_convert_sc16_item32_le_1_to_fc64_1(void){ } static converter::sptr make_convert_sc8_item32_be_1_to_fc32_1(void){ - return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<float, uhd::ntohx, SHIFT_PAIR1>()); + return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<float, uhd::ntohx, SHIFT_PAIR0>()); } static converter::sptr make_convert_sc8_item32_be_1_to_fc64_1(void){ - return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<double, uhd::ntohx, SHIFT_PAIR1>()); + return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<double, uhd::ntohx, SHIFT_PAIR0>()); } static converter::sptr make_convert_sc8_item32_le_1_to_fc32_1(void){ - return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<float, uhd::wtohx, SHIFT_PAIR0>()); + return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<float, uhd::wtohx, SHIFT_PAIR1>()); } static converter::sptr make_convert_sc8_item32_le_1_to_fc64_1(void){ - return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<double, uhd::wtohx, SHIFT_PAIR0>()); + return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<double, uhd::wtohx, SHIFT_PAIR1>()); } static converter::sptr make_convert_sc8_item32_be_1_to_sc16_1(void){ - return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<s16_t, uhd::ntohx, SHIFT_PAIR1>()); + return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<s16_t, uhd::ntohx, SHIFT_PAIR0>()); } static converter::sptr make_convert_sc8_item32_le_1_to_sc16_1(void){ - return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<s16_t, uhd::wtohx, SHIFT_PAIR0>()); + return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<s16_t, uhd::wtohx, SHIFT_PAIR1>()); } static converter::sptr make_convert_sc16_1_to_sc8_item32_be_1(void){ diff --git a/host/lib/convert/sse2_fc32_to_sc8.cpp b/host/lib/convert/sse2_fc32_to_sc8.cpp index dd884640d..36aa68b0e 100644 --- a/host/lib/convert/sse2_fc32_to_sc8.cpp +++ b/host/lib/convert/sse2_fc32_to_sc8.cpp @@ -1,5 +1,5 @@ // -// Copyright 2012 Ettus Research LLC +// Copyright 2012-2013 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -47,7 +47,7 @@ DECLARE_CONVERTER(fc32, 1, sc8_item32_be, 1, PRIORITY_SIMD){ item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); const __m128 scalar = _mm_set_ps1(float(scale_factor)); - const int shuf = _MM_SHUFFLE(1, 0, 3, 2); + const int shuf = _MM_SHUFFLE(3, 2, 1, 0); #define convert_fc32_1_to_sc8_item32_1_bswap_guts(_al_) \ for (size_t j = 0; i+7 < nsamps; i+=8, j+=4){ \ @@ -83,7 +83,7 @@ DECLARE_CONVERTER(fc32, 1, sc8_item32_le, 1, PRIORITY_SIMD){ item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); const __m128 scalar = _mm_set_ps1(float(scale_factor)); - const int shuf = _MM_SHUFFLE(2, 3, 0, 1); + const int shuf = _MM_SHUFFLE(0, 1, 2, 3); #define convert_fc32_1_to_sc8_item32_1_nswap_guts(_al_) \ for (size_t j = 0; i+7 < nsamps; i+=8, j+=4){ \ diff --git a/host/lib/convert/sse2_fc64_to_sc8.cpp b/host/lib/convert/sse2_fc64_to_sc8.cpp index bf3719e13..82a8e0bb0 100644 --- a/host/lib/convert/sse2_fc64_to_sc8.cpp +++ b/host/lib/convert/sse2_fc64_to_sc8.cpp @@ -1,5 +1,5 @@ // -// Copyright 2012 Ettus Research LLC +// Copyright 2012-2013 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -59,10 +59,10 @@ DECLARE_CONVERTER(fc64, 1, sc8_item32_be, 1, PRIORITY_SIMD){ \ /* interleave */ \ const __m128i tmpi = pack_sc8_item32_4x( \ - pack_sc32_4x(tmp0, tmp1, scalar), \ - pack_sc32_4x(tmp2, tmp3, scalar), \ - pack_sc32_4x(tmp4, tmp5, scalar), \ - pack_sc32_4x(tmp6, tmp7, scalar) \ + pack_sc32_4x(tmp1, tmp0, scalar), \ + pack_sc32_4x(tmp3, tmp2, scalar), \ + pack_sc32_4x(tmp5, tmp4, scalar), \ + pack_sc32_4x(tmp7, tmp6, scalar) \ ); \ \ /* store to output */ \ @@ -103,10 +103,10 @@ DECLARE_CONVERTER(fc64, 1, sc8_item32_le, 1, PRIORITY_SIMD){ \ /* interleave */ \ __m128i tmpi = pack_sc8_item32_4x( \ - pack_sc32_4x(tmp1, tmp0, scalar), \ - pack_sc32_4x(tmp3, tmp2, scalar), \ - pack_sc32_4x(tmp5, tmp4, scalar), \ - pack_sc32_4x(tmp7, tmp6, scalar) \ + pack_sc32_4x(tmp0, tmp1, scalar), \ + pack_sc32_4x(tmp2, tmp3, scalar), \ + pack_sc32_4x(tmp4, tmp5, scalar), \ + pack_sc32_4x(tmp6, tmp7, scalar) \ ); \ tmpi = _mm_or_si128(_mm_srli_epi16(tmpi, 8), _mm_slli_epi16(tmpi, 8)); /*byteswap*/\ \ diff --git a/host/lib/convert/sse2_sc8_to_fc32.cpp b/host/lib/convert/sse2_sc8_to_fc32.cpp index c0e561814..724af0225 100644 --- a/host/lib/convert/sse2_sc8_to_fc32.cpp +++ b/host/lib/convert/sse2_sc8_to_fc32.cpp @@ -1,5 +1,5 @@ // -// Copyright 2012 Ettus Research LLC +// Copyright 2012-2013 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -48,7 +48,7 @@ DECLARE_CONVERTER(sc8_item32_be, 1, fc32, 1, PRIORITY_SIMD){ fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]); const __m128 scalar = _mm_set_ps1(float(scale_factor)/(1 << 24)); - const int shuf = _MM_SHUFFLE(1, 0, 3, 2); + const int shuf = _MM_SHUFFLE(3, 2, 1, 0); size_t i = 0, j = 0; fc32_t dummy; @@ -92,7 +92,7 @@ DECLARE_CONVERTER(sc8_item32_le, 1, fc32, 1, PRIORITY_SIMD){ fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]); const __m128 scalar = _mm_set_ps1(float(scale_factor)/(1 << 24)); - const int shuf = _MM_SHUFFLE(2, 3, 0, 1); + const int shuf = _MM_SHUFFLE(0, 1, 2, 3); size_t i = 0, j = 0; fc32_t dummy; diff --git a/host/lib/convert/sse2_sc8_to_fc64.cpp b/host/lib/convert/sse2_sc8_to_fc64.cpp index ef9c0fdb4..94d8911f6 100644 --- a/host/lib/convert/sse2_sc8_to_fc64.cpp +++ b/host/lib/convert/sse2_sc8_to_fc64.cpp @@ -1,5 +1,5 @@ // -// Copyright 2012 Ettus Research LLC +// Copyright 2012-2013 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -77,7 +77,7 @@ DECLARE_CONVERTER(sc8_item32_be, 1, fc64, 1, PRIORITY_SIMD){ \ /* unpack */ \ __m128d tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; \ - unpack_sc32_8x(tmpi, tmp1, tmp0, tmp3, tmp2, tmp5, tmp4, tmp7, tmp6, scalar); \ + unpack_sc32_8x(tmpi, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, scalar); \ \ /* store to output */ \ _mm_store ## _al_ ## pd(reinterpret_cast<double *>(output+j+0), tmp0); \ @@ -125,7 +125,7 @@ DECLARE_CONVERTER(sc8_item32_le, 1, fc64, 1, PRIORITY_SIMD){ /* unpack */ \ __m128d tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; \ tmpi = _mm_or_si128(_mm_srli_epi16(tmpi, 8), _mm_slli_epi16(tmpi, 8)); /*byteswap*/\ - unpack_sc32_8x(tmpi, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, scalar); \ + unpack_sc32_8x(tmpi, tmp1, tmp0, tmp3, tmp2, tmp5, tmp4, tmp7, tmp6, scalar); \ \ /* store to output */ \ _mm_store ## _al_ ## pd(reinterpret_cast<double *>(output+j+0), tmp0); \ diff --git a/host/lib/transport/gen_vrt_if_packet.py b/host/lib/transport/gen_vrt_if_packet.py index 56e7c61bf..98f6804ae 100644 --- a/host/lib/transport/gen_vrt_if_packet.py +++ b/host/lib/transport/gen_vrt_if_packet.py @@ -79,24 +79,26 @@ static const size_t occ_table[] = {0, 2, 1, 3}; const boost::uint32_t VRLP = ('V' << 24) | ('R' << 16) | ('L' << 8) | ('P' << 0); const boost::uint32_t VEND = ('V' << 24) | ('E' << 16) | ('N' << 8) | ('D' << 0); -UHD_INLINE static boost::uint32_t chdr_to_vrt(const boost::uint32_t chdr, size_t &packet_count) +UHD_INLINE static boost::uint32_t chdr_to_vrt(const boost::uint32_t chdr, if_packet_info_t &info) { - boost::uint32_t vrt = chdr & 0xffff; //words32 - packet_count = (chdr >> 16) & 0xfff; + const boost::uint32_t bytes = chdr & 0xffff; + boost::uint32_t vrt = (bytes + 3)/4; + info.packet_count = (chdr >> 16) & 0xfff; vrt |= ((chdr >> 31) & 0x1) << 30; //context packet - vrt |= ((chdr >> 30) & 0x1) << 26; //has tlr vrt |= ((chdr >> 29) & 0x1) << 20; //has tsf vrt |= ((chdr >> 28) & 0x1) << 24; //has eob vrt |= (0x1) << 28; //has sid (always) return vrt; } -UHD_INLINE static boost::uint32_t vrt_to_chdr(const boost::uint32_t vrt, const size_t packet_count) +UHD_INLINE static boost::uint32_t vrt_to_chdr(const boost::uint32_t vrt, const if_packet_info_t &info) { - boost::uint32_t chdr = vrt & 0xffff; //words32 - chdr |= (packet_count & 0xfff) << 16; + const boost::uint32_t words32 = vrt & 0xffff; + int bytes_rem = info.num_payload_bytes % 4; + if (bytes_rem != 0) bytes_rem -= 4; //adjust for round up + boost::uint32_t chdr = (words32 * 4) + bytes_rem; + chdr |= (info.packet_count & 0xfff) << 16; chdr |= ((vrt >> 30) & 0x1) << 31; //context packet - chdr |= ((vrt >> 26) & 0x1) << 30; //has tlr chdr |= ((vrt >> 20) & 0x1) << 29; //has tsf chdr |= ((vrt >> 24) & 0x1) << 28; //has eob return chdr; @@ -311,7 +313,7 @@ void vrt::if_hdr_pack_$(suffix)( case if_packet_info_t::LINK_TYPE_CHDR: { __if_hdr_pack_$(suffix)(packet_buff, if_packet_info, vrt_hdr_word32); - const boost::uint32_t chdr = vrt_to_chdr(vrt_hdr_word32, if_packet_info.packet_count); + const boost::uint32_t chdr = vrt_to_chdr(vrt_hdr_word32, if_packet_info); packet_buff[0] = $(XE_MACRO)(chdr); break; } @@ -349,9 +351,10 @@ void vrt::if_hdr_unpack_$(suffix)( case if_packet_info_t::LINK_TYPE_CHDR: { const boost::uint32_t chdr = $(XE_MACRO)(packet_buff[0]); - size_t packet_count = 0; - vrt_hdr_word32 = chdr_to_vrt(chdr, packet_count); + vrt_hdr_word32 = chdr_to_vrt(chdr, if_packet_info); + size_t packet_count = if_packet_info.packet_count; __if_hdr_unpack_$(suffix)(packet_buff, if_packet_info, vrt_hdr_word32); + if_packet_info.num_payload_bytes -= (~chdr + 1) & 0x3; if_packet_info.packet_count = packet_count; break; } diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp index f7ed35e50..09c0d3979 100644 --- a/host/lib/usrp/b200/b200_impl.cpp +++ b/host/lib/usrp/b200/b200_impl.cpp @@ -252,7 +252,7 @@ b200_impl::b200_impl(const device_addr_t &device_addr) //////////////////////////////////////////////////////////////////// // Local control endpoint //////////////////////////////////////////////////////////////////// - _local_ctrl = radio_ctrl_core_3000::make(vrt::if_packet_info_t::LINK_TYPE_CHDR, _ctrl_transport, zero_copy_if::sptr()/*null*/, B200_LOCAL_CTRL_SID); + _local_ctrl = radio_ctrl_core_3000::make(false/*lilE*/, _ctrl_transport, zero_copy_if::sptr()/*null*/, B200_LOCAL_CTRL_SID); _local_ctrl->hold_task(_async_task); _async_task_data->local_ctrl = _local_ctrl; //weak this->check_fpga_compat(); @@ -488,7 +488,7 @@ void b200_impl::setup_radio(const size_t dspno) // radio control //////////////////////////////////////////////////////////////////// const boost::uint32_t sid = (dspno == 0)? B200_CTRL0_MSG_SID : B200_CTRL1_MSG_SID; - perif.ctrl = radio_ctrl_core_3000::make(vrt::if_packet_info_t::LINK_TYPE_CHDR, _ctrl_transport, zero_copy_if::sptr()/*null*/, sid); + perif.ctrl = radio_ctrl_core_3000::make(false/*lilE*/, _ctrl_transport, zero_copy_if::sptr()/*null*/, sid); perif.ctrl->hold_task(_async_task); _async_task_data->radio_ctrl[dspno] = perif.ctrl; //weak _tree->access<time_spec_t>(mb_path / "time" / "cmd") diff --git a/host/lib/usrp/b200/b200_io_impl.cpp b/host/lib/usrp/b200/b200_io_impl.cpp index 5a588f902..d643ef855 100644 --- a/host/lib/usrp/b200/b200_io_impl.cpp +++ b/host/lib/usrp/b200/b200_io_impl.cpp @@ -214,11 +214,7 @@ rx_streamer::sptr b200_impl::get_rx_stream(const uhd::stream_args_t &args_) stream_args_t args = args_; //setup defaults for unspecified values - if (not args.otw_format.empty() and args.otw_format != "sc16") - { - throw uhd::value_error("b200_impl::get_rx_stream only supports otw_format sc16"); - } - args.otw_format = "sc16"; + if (args.otw_format.empty()) args.otw_format = "sc16"; args.channels = args.channels.empty()? std::vector<size_t>(1, 0) : args.channels; boost::shared_ptr<sph::recv_packet_streamer> my_streamer; @@ -226,6 +222,10 @@ rx_streamer::sptr b200_impl::get_rx_stream(const uhd::stream_args_t &args_) { const size_t chan = args.channels[stream_i]; radio_perifs_t &perif = _radio_perifs[chan]; + if (args.otw_format == "sc16") perif.ctrl->poke32(TOREG(SR_RX_FMT), 0); + if (args.otw_format == "sc12") perif.ctrl->poke32(TOREG(SR_RX_FMT), 1); + if (args.otw_format == "fc32") perif.ctrl->poke32(TOREG(SR_RX_FMT), 2); + if (args.otw_format == "sc8") perif.ctrl->poke32(TOREG(SR_RX_FMT), 3); const boost::uint32_t sid = chan?B200_RX_DATA1_SID:B200_RX_DATA0_SID; //calculate packet size @@ -238,7 +238,7 @@ rx_streamer::sptr b200_impl::get_rx_stream(const uhd::stream_args_t &args_) const size_t bpp = _data_transport->get_recv_frame_size() - hdr_size; const size_t bpi = convert::get_bytes_per_item(args.otw_format); size_t spp = unsigned(args.args.cast<double>("spp", bpp/bpi)); - spp = std::min<size_t>(2041, spp); //magic maximum for framing at full rate + spp = std::min<size_t>(2000, spp); //magic maximum for framing at full rate //make the new streamer given the samples per packet if (not my_streamer) my_streamer = boost::make_shared<sph::recv_packet_streamer>(spp); @@ -316,11 +316,7 @@ tx_streamer::sptr b200_impl::get_tx_stream(const uhd::stream_args_t &args_) stream_args_t args = args_; //setup defaults for unspecified values - if (not args.otw_format.empty() and args.otw_format != "sc16") - { - throw uhd::value_error("b200_impl::get_rx_stream only supports otw_format sc16"); - } - args.otw_format = "sc16"; + if (args.otw_format.empty()) args.otw_format = "sc16"; args.channels = args.channels.empty()? std::vector<size_t>(1, 0) : args.channels; boost::shared_ptr<sph::send_packet_streamer> my_streamer; @@ -328,6 +324,10 @@ tx_streamer::sptr b200_impl::get_tx_stream(const uhd::stream_args_t &args_) { const size_t chan = args.channels[stream_i]; radio_perifs_t &perif = _radio_perifs[chan]; + if (args.otw_format == "sc16") perif.ctrl->poke32(TOREG(SR_TX_FMT), 0); + if (args.otw_format == "sc12") perif.ctrl->poke32(TOREG(SR_TX_FMT), 1); + if (args.otw_format == "fc32") perif.ctrl->poke32(TOREG(SR_TX_FMT), 2); + if (args.otw_format == "sc8") perif.ctrl->poke32(TOREG(SR_TX_FMT), 3); //calculate packet size static const size_t hdr_size = 0 diff --git a/host/lib/usrp/b200/b200_regs.hpp b/host/lib/usrp/b200/b200_regs.hpp index ae39b95b2..c64066b27 100644 --- a/host/lib/usrp/b200/b200_regs.hpp +++ b/host/lib/usrp/b200/b200_regs.hpp @@ -43,6 +43,8 @@ localparam SR_RX_CTRL = 96; localparam SR_RX_DSP = 144; localparam SR_TX_DSP = 184; localparam SR_TIME = 128; +localparam SR_RX_FMT = 136; +localparam SR_TX_FMT = 138; localparam RB32_TEST = 0; localparam RB64_TIME_NOW = 8; diff --git a/host/lib/usrp/cores/radio_ctrl_core_3000.cpp b/host/lib/usrp/cores/radio_ctrl_core_3000.cpp index 616903920..5298fd213 100644 --- a/host/lib/usrp/cores/radio_ctrl_core_3000.cpp +++ b/host/lib/usrp/cores/radio_ctrl_core_3000.cpp @@ -22,6 +22,7 @@ #include <uhd/utils/byteswap.hpp> #include <uhd/utils/safe_call.hpp> #include <uhd/transport/bounded_buffer.hpp> +#include <uhd/transport/vrt_if_packet.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/thread.hpp> #include <boost/format.hpp> @@ -32,7 +33,7 @@ using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; -static const double ACK_TIMEOUT = 0.5; +static const double ACK_TIMEOUT = 2.0; //supposed to be worst case practical timeout static const double MASSIVE_TIMEOUT = 10.0; //for when we wait on a timed command static const size_t SR_READBACK = 32; @@ -41,15 +42,15 @@ class radio_ctrl_core_3000_impl : public radio_ctrl_core_3000 public: radio_ctrl_core_3000_impl( - vrt::if_packet_info_t::link_type_t link_type, + const bool big_endian, uhd::transport::zero_copy_if::sptr ctrl_xport, uhd::transport::zero_copy_if::sptr resp_xport, const boost::uint32_t sid, const std::string &name ): - _link_type(link_type), + _link_type(vrt::if_packet_info_t::LINK_TYPE_CHDR), _packet_type(vrt::if_packet_info_t::PACKET_TYPE_CONTEXT), - _bige(link_type == vrt::if_packet_info_t::LINK_TYPE_VRLP), + _bige(big_endian), _ctrl_xport(ctrl_xport), _resp_xport(resp_xport), _sid(sid), @@ -301,12 +302,12 @@ private: radio_ctrl_core_3000::sptr radio_ctrl_core_3000::make( - vrt::if_packet_info_t::link_type_t link_type, + const bool big_endian, zero_copy_if::sptr ctrl_xport, zero_copy_if::sptr resp_xport, const boost::uint32_t sid, const std::string &name ) { - return sptr(new radio_ctrl_core_3000_impl(link_type, ctrl_xport, resp_xport, sid, name)); + return sptr(new radio_ctrl_core_3000_impl(big_endian, ctrl_xport, resp_xport, sid, name)); } diff --git a/host/lib/usrp/cores/radio_ctrl_core_3000.hpp b/host/lib/usrp/cores/radio_ctrl_core_3000.hpp index 6ef484296..8c0548d89 100644 --- a/host/lib/usrp/cores/radio_ctrl_core_3000.hpp +++ b/host/lib/usrp/cores/radio_ctrl_core_3000.hpp @@ -20,7 +20,6 @@ #include <uhd/types/time_spec.hpp> #include <uhd/transport/zero_copy.hpp> -#include <uhd/transport/vrt_if_packet.hpp> #include <boost/shared_ptr.hpp> #include <boost/utility.hpp> #include "wb_iface.hpp" @@ -36,7 +35,7 @@ public: //! Make a new control object static sptr make( - uhd::transport::vrt::if_packet_info_t::link_type_t link_type, + const bool big_endian, uhd::transport::zero_copy_if::sptr ctrl_xport, uhd::transport::zero_copy_if::sptr resp_xport, const boost::uint32_t sid, diff --git a/host/lib/usrp/cores/rx_dsp_core_3000.cpp b/host/lib/usrp/cores/rx_dsp_core_3000.cpp index 36d9af5bc..7b3324f74 100644 --- a/host/lib/usrp/cores/rx_dsp_core_3000.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_3000.cpp @@ -169,21 +169,26 @@ public: void setup(const uhd::stream_args_t &stream_args){ - //unsigned format_word = 0; if (stream_args.otw_format == "sc16"){ - //format_word = 0; _dsp_extra_scaling = 1.0; _host_extra_scaling = 1.0; } - /* else if (stream_args.otw_format == "sc8"){ - format_word = (1 << 0); double peak = stream_args.args.cast<double>("peak", 1.0); peak = std::max(peak, 1.0/256); _host_extra_scaling = peak*256; - _dsp_extra_scaling = peak*256; + _dsp_extra_scaling = peak; + } + else if (stream_args.otw_format == "sc12"){ + double peak = stream_args.args.cast<double>("peak", 1.0); + peak = std::max(peak, 1.0/16); + _host_extra_scaling = peak*16; + _dsp_extra_scaling = peak; + } + else if (stream_args.otw_format == "fc32"){ + _host_extra_scaling = 1.0; + _dsp_extra_scaling = 1.0; } - */ else throw uhd::value_error("USRP RX cannot handle requested wire format: " + stream_args.otw_format); _host_extra_scaling *= stream_args.args.cast<double>("fullscale", 1.0); diff --git a/host/lib/usrp/cores/tx_dsp_core_3000.cpp b/host/lib/usrp/cores/tx_dsp_core_3000.cpp index ff4392a13..feb749cd9 100644 --- a/host/lib/usrp/cores/tx_dsp_core_3000.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_3000.cpp @@ -146,22 +146,27 @@ public: void setup(const uhd::stream_args_t &stream_args){ - //unsigned format_word = 0; if (stream_args.otw_format == "sc16"){ - //format_word = 0; _dsp_extra_scaling = 1.0; _host_extra_scaling = 1.0; } - /* else if (stream_args.otw_format == "sc8"){ - format_word = (1 << 0); double peak = stream_args.args.cast<double>("peak", 1.0); peak = std::max(peak, 1.0/256); _host_extra_scaling = 1.0/peak/256; _dsp_extra_scaling = 1.0/peak; } + else if (stream_args.otw_format == "sc12"){ + double peak = stream_args.args.cast<double>("peak", 1.0); + peak = std::max(peak, 1.0/16); + _host_extra_scaling = 1.0/peak/16; + _dsp_extra_scaling = 1.0/peak; + } + else if (stream_args.otw_format == "fc32"){ + _host_extra_scaling = 1.0; + _dsp_extra_scaling = 1.0; + } else throw uhd::value_error("USRP TX cannot handle requested wire format: " + stream_args.otw_format); - */ _host_extra_scaling /= stream_args.args.cast<double>("fullscale", 1.0); |