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);  | 
