diff options
Diffstat (limited to 'host/lib')
358 files changed, 24323 insertions, 22487 deletions
diff --git a/host/lib/build_info.cpp b/host/lib/build_info.cpp index ee27f3f87..f9af663d1 100644 --- a/host/lib/build_info.cpp +++ b/host/lib/build_info.cpp @@ -4,99 +4,101 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <config.h> - #include <uhd/build_info.hpp> - +#include <config.h> +#include <boost/algorithm/string.hpp> #include <boost/format.hpp> #include <boost/version.hpp> -#include <boost/algorithm/string.hpp> #ifdef ENABLE_USB -#include <libusb.h> +# include <libusb.h> #endif namespace uhd { namespace build_info { - const std::string boost_version() { - return boost::algorithm::replace_all_copy( - std::string(BOOST_LIB_VERSION), "_", "." - ); - } +const std::string boost_version() +{ + return boost::algorithm::replace_all_copy(std::string(BOOST_LIB_VERSION), "_", "."); +} - const std::string build_date() { - return "@UHD_BUILD_DATE@"; - } +const std::string build_date() +{ + return "@UHD_BUILD_DATE@"; +} - const std::string c_compiler() { - return "@UHD_C_COMPILER@"; - } +const std::string c_compiler() +{ + return "@UHD_C_COMPILER@"; +} - const std::string cxx_compiler() { - return "@UHD_CXX_COMPILER@"; - } +const std::string cxx_compiler() +{ + return "@UHD_CXX_COMPILER@"; +} #ifdef _MSC_VER - static const std::string define_flag = "/D "; +static const std::string define_flag = "/D "; #else - static const std::string define_flag = "-D"; +static const std::string define_flag = "-D"; #endif - const std::string c_flags() { - return boost::algorithm::replace_all_copy( - (define_flag + std::string("@UHD_C_FLAGS@")), - std::string(";"), (" " + define_flag) - ); - } - - const std::string cxx_flags() { - return boost::algorithm::replace_all_copy( - (define_flag + std::string("@UHD_CXX_FLAGS@")), - std::string(";"), (" " + define_flag) - ); - } - - const std::string enabled_components() { - return boost::algorithm::replace_all_copy( - std::string("@_uhd_enabled_components@"), - std::string(";"), std::string(", ") - ); - } - - const std::string install_prefix() { - return "@CMAKE_INSTALL_PREFIX@"; - } - - const std::string libusb_version() { - #ifdef ENABLE_USB - /* - * Versions can only be queried from 1.0.13 onward. - * Depending on if the commit came from libusbx or - * libusb (now merged), the define might be different. - */ - #ifdef LIBUSB_API_VERSION /* 1.0.18 onward */ - int major_version = LIBUSB_API_VERSION >> 24; - int minor_version = (LIBUSB_API_VERSION & 0xFF0000) >> 16; - int micro_version = ((LIBUSB_API_VERSION & 0xFFFF) - 0x100) + 18; - - return str(boost::format("%d.%d.%d") - % major_version % minor_version % micro_version); - #elif defined(LIBUSBX_API_VERSION) /* 1.0.13 - 1.0.17 */ - switch(LIBUSBX_API_VERSION & 0xFF) { - case 0x00: - return "1.0.13"; - case 0x01: - return "1.0.15"; - case 0xFF: - return "1.0.14"; - default: - return "1.0.16 or 1.0.17"; - } - #else - return "< 1.0.13"; - #endif - #else - return "N/A"; - #endif +const std::string c_flags() +{ + return boost::algorithm::replace_all_copy( + (define_flag + std::string("@UHD_C_FLAGS@")), + std::string(";"), + (" " + define_flag)); +} + +const std::string cxx_flags() +{ + return boost::algorithm::replace_all_copy( + (define_flag + std::string("@UHD_CXX_FLAGS@")), + std::string(";"), + (" " + define_flag)); +} + +const std::string enabled_components() +{ + return boost::algorithm::replace_all_copy( + std::string("@_uhd_enabled_components@"), std::string(";"), std::string(", ")); +} + +const std::string install_prefix() +{ + return "@CMAKE_INSTALL_PREFIX@"; +} + +const std::string libusb_version() +{ +#ifdef ENABLE_USB +/* + * Versions can only be queried from 1.0.13 onward. + * Depending on if the commit came from libusbx or + * libusb (now merged), the define might be different. + */ +# ifdef LIBUSB_API_VERSION /* 1.0.18 onward */ + int major_version = LIBUSB_API_VERSION >> 24; + int minor_version = (LIBUSB_API_VERSION & 0xFF0000) >> 16; + int micro_version = ((LIBUSB_API_VERSION & 0xFFFF) - 0x100) + 18; + + return str(boost::format("%d.%d.%d") % major_version % minor_version % micro_version); +# elif defined(LIBUSBX_API_VERSION) /* 1.0.13 - 1.0.17 */ + switch (LIBUSBX_API_VERSION & 0xFF) { + case 0x00: + return "1.0.13"; + case 0x01: + return "1.0.15"; + case 0xFF: + return "1.0.14"; + default: + return "1.0.16 or 1.0.17"; } -}} +# else + return "< 1.0.13"; +# endif +#else + return "N/A"; +#endif +} +}} // namespace uhd::build_info diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp index 0de344b75..6ee9a651a 100644 --- a/host/lib/convert/convert_common.hpp +++ b/host/lib/convert/convert_common.hpp @@ -13,24 +13,31 @@ #include <stdint.h> #include <complex> -#define _DECLARE_CONVERTER(name, in_form, num_in, out_form, num_out, prio) \ - struct name : public uhd::convert::converter{ \ - static sptr make(void){return sptr(new name());} \ - double scale_factor; \ - void set_scalar(const double s){scale_factor = s;} \ +#define _DECLARE_CONVERTER(name, in_form, num_in, out_form, num_out, prio) \ + struct name : public uhd::convert::converter \ + { \ + static sptr make(void) \ + { \ + return sptr(new name()); \ + } \ + double scale_factor; \ + void set_scalar(const double s) \ + { \ + scale_factor = s; \ + } \ void operator()(const input_type&, const output_type&, const size_t); \ - }; \ - UHD_STATIC_BLOCK(__register_##name##_##prio){ \ - uhd::convert::id_type id; \ - id.input_format = #in_form; \ - id.num_inputs = num_in; \ - id.output_format = #out_form; \ - id.num_outputs = num_out; \ - uhd::convert::register_converter(id, &name::make, prio); \ - } \ - void name::operator()( \ - const input_type &inputs, const output_type &outputs, const size_t nsamps \ - ) + }; \ + UHD_STATIC_BLOCK(__register_##name##_##prio) \ + { \ + uhd::convert::id_type id; \ + id.input_format = #in_form; \ + id.num_inputs = num_in; \ + id.output_format = #out_form; \ + id.num_outputs = num_out; \ + uhd::convert::register_converter(id, &name::make, prio); \ + } \ + void name::operator()( \ + const input_type& inputs, const output_type& outputs, const size_t nsamps) /*! Convenience macro to declare a single-function converter * @@ -41,76 +48,83 @@ * which runs the conversion. Available parameters in this function block * are: * - `inputs`: Vector of pointers to the input data. Size of the vector == `num_in` - * - `outputs`: Vector of pointers to where the output data goes. Size of the vector == `num_out` + * - `outputs`: Vector of pointers to where the output data goes. Size of the vector == + * `num_out` * - `nsamps`: Number of items per input buffer to convert * - `scale_factor`: Scaling factor for float conversions */ -#define DECLARE_CONVERTER(in_form, num_in, out_form, num_out, prio) \ - _DECLARE_CONVERTER(__convert_##in_form##_##num_in##_##out_form##_##num_out##_##prio, in_form, num_in, out_form, num_out, prio) +#define DECLARE_CONVERTER(in_form, num_in, out_form, num_out, prio) \ + _DECLARE_CONVERTER(__convert_##in_form##_##num_in##_##out_form##_##num_out##_##prio, \ + in_form, \ + num_in, \ + out_form, \ + num_out, \ + prio) /*********************************************************************** * Setup priorities **********************************************************************/ static const int PRIORITY_GENERAL = 0; -static const int PRIORITY_EMPTY = -1; +static const int PRIORITY_EMPTY = -1; #ifdef __ARM_NEON__ static const int PRIORITY_SIMD = 2; -static const int PRIORITY_TABLE = 1; //tables require large cache, so they are slower on arm +static const int PRIORITY_TABLE = + 1; // tables require large cache, so they are slower on arm #else // We used to have ORC, too, so SIMD is 3 -static const int PRIORITY_SIMD = 3; +static const int PRIORITY_SIMD = 3; static const int PRIORITY_TABLE = 1; #endif /*********************************************************************** * Typedefs **********************************************************************/ -typedef std::complex<double> fc64_t; -typedef std::complex<float> fc32_t; +typedef std::complex<double> fc64_t; +typedef std::complex<float> fc32_t; typedef std::complex<int32_t> sc32_t; typedef std::complex<int16_t> sc16_t; -typedef std::complex<int8_t> sc8_t; -typedef double f64_t; -typedef float f32_t; -typedef int32_t s32_t; -typedef int16_t s16_t; -typedef int8_t s8_t; -typedef uint8_t u8_t; +typedef std::complex<int8_t> sc8_t; +typedef double f64_t; +typedef float f32_t; +typedef int32_t s32_t; +typedef int16_t s16_t; +typedef int8_t s8_t; +typedef uint8_t u8_t; -typedef uint32_t item32_t; +typedef uint32_t item32_t; typedef item32_t (*xtox_t)(item32_t); /*********************************************************************** * Convert xx to items32 sc16 buffer **********************************************************************/ -template <typename T> UHD_INLINE item32_t xx_to_item32_sc16_x1( - const std::complex<T> &num, const double scale_factor -){ - uint16_t real = int16_t(num.real()*float(scale_factor)); - uint16_t imag = int16_t(num.imag()*float(scale_factor)); +template <typename T> +UHD_INLINE item32_t xx_to_item32_sc16_x1( + const std::complex<T>& num, const double scale_factor) +{ + uint16_t real = int16_t(num.real() * float(scale_factor)); + uint16_t imag = int16_t(num.imag() * float(scale_factor)); return (item32_t(real) << 16) | (item32_t(imag) << 0); } -template <> UHD_INLINE item32_t xx_to_item32_sc16_x1( - const sc16_t &num, const double -){ +template <> +UHD_INLINE item32_t xx_to_item32_sc16_x1(const sc16_t& num, const double) +{ uint16_t real = int16_t(num.real()); uint16_t imag = int16_t(num.imag()); return (item32_t(real) << 16) | (item32_t(imag) << 0); } template <xtox_t to_wire, typename T> -UHD_INLINE void xx_to_item32_sc16( - const std::complex<T> *input, - item32_t *output, +UHD_INLINE void xx_to_item32_sc16(const std::complex<T>* input, + item32_t* output, const size_t nsamps, - const double scale_factor -){ - for (size_t i = 0; i < nsamps; i++){ + const double scale_factor) +{ + for (size_t i = 0; i < nsamps; i++) { const item32_t item = xx_to_item32_sc16_x1(input[i], scale_factor); - output[i] = to_wire(item); + output[i] = to_wire(item); } } @@ -137,33 +151,29 @@ UHD_FORCE_INLINE void xx_to_chdr_sc16(const std::complex<T>* input, /*********************************************************************** * Convert items32 sc16 buffer to xx **********************************************************************/ -template <typename T> UHD_INLINE std::complex<T> item32_sc16_x1_to_xx( - const item32_t item, const double scale_factor -){ - return std::complex<T>( - T(int16_t(item >> 16)*float(scale_factor)), - T(int16_t(item >> 0)*float(scale_factor)) - ); +template <typename T> +UHD_INLINE std::complex<T> item32_sc16_x1_to_xx( + const item32_t item, const double scale_factor) +{ + return std::complex<T>(T(int16_t(item >> 16) * float(scale_factor)), + T(int16_t(item >> 0) * float(scale_factor))); } -template <> UHD_INLINE sc16_t item32_sc16_x1_to_xx( - const item32_t item, const double -){ - return sc16_t( - int16_t(item >> 16), int16_t(item >> 0) - ); +template <> +UHD_INLINE sc16_t item32_sc16_x1_to_xx(const item32_t item, const double) +{ + return sc16_t(int16_t(item >> 16), int16_t(item >> 0)); } template <xtox_t to_host, typename T> -UHD_INLINE void item32_sc16_to_xx( - const item32_t *input, - std::complex<T> *output, +UHD_INLINE void item32_sc16_to_xx(const item32_t* input, + std::complex<T>* output, const size_t nsamps, - const double scale_factor -){ - for (size_t i = 0; i < nsamps; i++){ + const double scale_factor) +{ + for (size_t i = 0; i < nsamps; i++) { const item32_t item_i = to_host(input[i]); - output[i] = item32_sc16_x1_to_xx<T>(item_i, scale_factor); + output[i] = item32_sc16_x1_to_xx<T>(item_i, scale_factor); } } @@ -189,60 +199,56 @@ UHD_FORCE_INLINE void chdr_sc16_to_xx(const sc16_t* input, /*********************************************************************** * Convert xx to items32 sc8 buffer **********************************************************************/ -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 -){ - uint8_t real1 = int8_t(in0.real()*float(scale_factor)); - uint8_t imag1 = int8_t(in0.imag()*float(scale_factor)); - uint8_t real0 = int8_t(in1.real()*float(scale_factor)); - uint8_t imag0 = int8_t(in1.imag()*float(scale_factor)); - return - (item32_t(real0) << 8) | (item32_t(imag0) << 0) | - (item32_t(real1) << 24) | (item32_t(imag1) << 16) - ; +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) +{ + uint8_t real1 = int8_t(in0.real() * float(scale_factor)); + uint8_t imag1 = int8_t(in0.imag() * float(scale_factor)); + uint8_t real0 = int8_t(in1.real() * float(scale_factor)); + uint8_t imag0 = int8_t(in1.imag() * float(scale_factor)); + return (item32_t(real0) << 8) | (item32_t(imag0) << 0) | (item32_t(real1) << 24) + | (item32_t(imag1) << 16); } -template <> UHD_INLINE item32_t xx_to_item32_sc8_x1( - const sc16_t &in0, const sc16_t &in1, const double -){ +template <> +UHD_INLINE item32_t xx_to_item32_sc8_x1( + const sc16_t& in0, const sc16_t& in1, const double) +{ uint8_t real1 = int8_t(in0.real()); uint8_t imag1 = int8_t(in0.imag()); uint8_t real0 = int8_t(in1.real()); uint8_t imag0 = int8_t(in1.imag()); - return - (item32_t(real0) << 8) | (item32_t(imag0) << 0) | - (item32_t(real1) << 24) | (item32_t(imag1) << 16) - ; + return (item32_t(real0) << 8) | (item32_t(imag0) << 0) | (item32_t(real1) << 24) + | (item32_t(imag1) << 16); } -template <> UHD_INLINE item32_t xx_to_item32_sc8_x1( - const sc8_t &in0, const sc8_t &in1, const double -){ +template <> +UHD_INLINE item32_t xx_to_item32_sc8_x1(const sc8_t& in0, const sc8_t& in1, const double) +{ uint8_t real1 = int8_t(in0.real()); uint8_t imag1 = int8_t(in0.imag()); uint8_t real0 = int8_t(in1.real()); uint8_t imag0 = int8_t(in1.imag()); - return - (item32_t(real0) << 8) | (item32_t(imag0) << 0) | - (item32_t(real1) << 24) | (item32_t(imag1) << 16) - ; + return (item32_t(real0) << 8) | (item32_t(imag0) << 0) | (item32_t(real1) << 24) + | (item32_t(imag1) << 16); } template <xtox_t to_wire, typename T> -UHD_INLINE void xx_to_item32_sc8( - const std::complex<T> *input, - item32_t *output, +UHD_INLINE void xx_to_item32_sc8(const std::complex<T>* input, + item32_t* output, const size_t nsamps, - const double scale_factor -){ - const size_t num_pairs = nsamps/2; - for (size_t i = 0, j = 0; i < num_pairs; i++, j+=2){ - const item32_t item = xx_to_item32_sc8_x1(input[j], input[j+1], scale_factor); - output[i] = to_wire(item); + const double scale_factor) +{ + const size_t num_pairs = nsamps / 2; + for (size_t i = 0, j = 0; i < num_pairs; i++, j += 2) { + const item32_t item = xx_to_item32_sc8_x1(input[j], input[j + 1], scale_factor); + output[i] = to_wire(item); } - if (nsamps != num_pairs*2){ - const item32_t item = xx_to_item32_sc8_x1(input[nsamps-1], std::complex<T>(0), scale_factor); + if (nsamps != num_pairs * 2) { + const item32_t item = + xx_to_item32_sc8_x1(input[nsamps - 1], std::complex<T>(0), scale_factor); output[num_pairs] = to_wire(item); } } @@ -250,71 +256,59 @@ UHD_INLINE void xx_to_item32_sc8( /*********************************************************************** * Convert items32 sc8 buffer to xx **********************************************************************/ -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 -){ - out1 = std::complex<T>( - T(int8_t(item >> 8)*float(scale_factor)), - T(int8_t(item >> 0)*float(scale_factor)) - ); - out0 = std::complex<T>( - T(int8_t(item >> 24)*float(scale_factor)), - T(int8_t(item >> 16)*float(scale_factor)) - ); +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) +{ + out1 = std::complex<T>(T(int8_t(item >> 8) * float(scale_factor)), + T(int8_t(item >> 0) * float(scale_factor))); + out0 = std::complex<T>(T(int8_t(item >> 24) * float(scale_factor)), + T(int8_t(item >> 16) * float(scale_factor))); } -template <> UHD_INLINE void item32_sc8_x1_to_xx( - const item32_t item, sc16_t &out0, sc16_t &out1, const double -){ - out1 = sc16_t( - int16_t(int8_t(item >> 8)), - int16_t(int8_t(item >> 0)) - ); - out0 = sc16_t( - int16_t(int8_t(item >> 24)), - int16_t(int8_t(item >> 16)) - ); +template <> +UHD_INLINE void item32_sc8_x1_to_xx( + const item32_t item, sc16_t& out0, sc16_t& out1, const double) +{ + out1 = sc16_t(int16_t(int8_t(item >> 8)), int16_t(int8_t(item >> 0))); + out0 = sc16_t(int16_t(int8_t(item >> 24)), int16_t(int8_t(item >> 16))); } -template <> UHD_INLINE void item32_sc8_x1_to_xx( - const item32_t item, sc8_t &out0, sc8_t &out1, const double -){ - out1 = sc8_t( - int8_t(int8_t(item >> 8)), - int8_t(int8_t(item >> 0)) - ); - out0 = sc8_t( - int8_t(int8_t(item >> 24)), - int8_t(int8_t(item >> 16)) - ); +template <> +UHD_INLINE void item32_sc8_x1_to_xx( + const item32_t item, sc8_t& out0, sc8_t& out1, const double) +{ + out1 = sc8_t(int8_t(int8_t(item >> 8)), int8_t(int8_t(item >> 0))); + out0 = sc8_t(int8_t(int8_t(item >> 24)), int8_t(int8_t(item >> 16))); } template <xtox_t to_host, typename T> -UHD_INLINE void item32_sc8_to_xx( - const item32_t *input, - std::complex<T> *output, +UHD_INLINE void item32_sc8_to_xx(const item32_t* input, + std::complex<T>* output, const size_t nsamps, - const double scale_factor -){ - input = reinterpret_cast<const item32_t *>(size_t(input) & ~0x3); + const double scale_factor) +{ + input = reinterpret_cast<const item32_t*>(size_t(input) & ~0x3); std::complex<T> dummy; size_t num_samps = nsamps; - if ((size_t(input) & 0x3) != 0){ + if ((size_t(input) & 0x3) != 0) { const item32_t item0 = to_host(*input++); item32_sc8_x1_to_xx(item0, dummy, *output++, scale_factor); num_samps--; } - const size_t num_pairs = num_samps/2; - for (size_t i = 0, j = 0; i < num_pairs; i++, j+=2){ + const size_t num_pairs = num_samps / 2; + for (size_t i = 0, j = 0; i < num_pairs; i++, j += 2) { const item32_t item_i = to_host(input[i]); - item32_sc8_x1_to_xx(item_i, output[j], output[j+1], scale_factor); + item32_sc8_x1_to_xx(item_i, output[j], output[j + 1], scale_factor); } - if (num_samps != num_pairs*2){ + if (num_samps != num_pairs * 2) { const item32_t item_n = to_host(input[num_pairs]); - item32_sc8_x1_to_xx(item_n, output[num_samps-1], dummy, scale_factor); + item32_sc8_x1_to_xx(item_n, output[num_samps - 1], dummy, scale_factor); } } diff --git a/host/lib/convert/convert_fc32_item32.cpp b/host/lib/convert/convert_fc32_item32.cpp index b119fd877..713f565f5 100644 --- a/host/lib/convert/convert_fc32_item32.cpp +++ b/host/lib/convert/convert_fc32_item32.cpp @@ -18,9 +18,9 @@ typedef uint32_t (*to32_type)(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):_scalar(0.0) + convert_fc32_item32_1_to_star_1(void) : _scalar(0.0) { - //NOP + // NOP } void set_scalar(const double scalar) @@ -28,19 +28,20 @@ struct convert_fc32_item32_1_to_star_1 : public converter _scalar = scalar; } - void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps) + 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]); + 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_f32p = reinterpret_cast<const float *>(&i32); - const float *q_f32p = reinterpret_cast<const float *>(&q32); - output[o] = std::complex<type>(type((*i_f32p)*_scalar), type((*q_f32p)*_scalar)); + 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_f32p = reinterpret_cast<const float*>(&i32); + const float* q_f32p = reinterpret_cast<const float*>(&q32); + output[o] = + std::complex<type>(type((*i_f32p) * _scalar), type((*q_f32p) * _scalar)); } } @@ -50,9 +51,9 @@ struct convert_fc32_item32_1_to_star_1 : public converter template <typename type, to32_type towire> struct convert_star_1_to_fc32_item32_1 : public converter { - convert_star_1_to_fc32_item32_1(void):_scalar(0.0) + convert_star_1_to_fc32_item32_1(void) : _scalar(0.0) { - //NOP + // NOP } void set_scalar(const double scalar) @@ -60,45 +61,66 @@ struct convert_star_1_to_fc32_item32_1 : public converter _scalar = scalar; } - void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps) + 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]); + 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 *i32p = reinterpret_cast<const item32_t *>(&i_f32); - const item32_t *q32p = reinterpret_cast<const item32_t *>(&q_f32); - output[o++] = towire(*i32p); - output[o++] = towire(*q32p); + 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* i32p = reinterpret_cast<const item32_t*>(&i_f32); + const item32_t* q32p = reinterpret_cast<const item32_t*>(&q_f32); + output[o++] = towire(*i32p); + output[o++] = towire(*q32p); } } 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) +#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_impl.cpp b/host/lib/convert/convert_impl.cpp index 6385965f0..228f15552 100644 --- a/host/lib/convert/convert_impl.cpp +++ b/host/lib/convert/convert_impl.cpp @@ -6,91 +6,84 @@ // #include <uhd/convert.hpp> +#include <uhd/exception.hpp> +#include <uhd/types/dict.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/static.hpp> -#include <uhd/types/dict.hpp> -#include <uhd/exception.hpp> #include <stdint.h> #include <boost/format.hpp> #include <complex> using namespace uhd; -convert::converter::~converter(void){ +convert::converter::~converter(void) +{ /* NOP */ } -bool convert::operator==(const convert::id_type &lhs, const convert::id_type &rhs){ - return true - and (lhs.input_format == rhs.input_format) - and (lhs.num_inputs == rhs.num_inputs) - and (lhs.output_format == rhs.output_format) - and (lhs.num_outputs == rhs.num_outputs) - ; +bool convert::operator==(const convert::id_type& lhs, const convert::id_type& rhs) +{ + return true and (lhs.input_format == rhs.input_format) + and (lhs.num_inputs == rhs.num_inputs) + and (lhs.output_format == rhs.output_format) + and (lhs.num_outputs == rhs.num_outputs); } -std::string convert::id_type::to_pp_string(void) const{ - return str(boost::format( - "conversion ID\n" - " Input format: %s\n" - " Num inputs: %d\n" - " Output format: %s\n" - " Num outputs: %d\n" - ) - % this->input_format - % this->num_inputs - % this->output_format - % this->num_outputs - ); +std::string convert::id_type::to_pp_string(void) const +{ + return str(boost::format("conversion ID\n" + " Input format: %s\n" + " Num inputs: %d\n" + " Output format: %s\n" + " Num outputs: %d\n") + % this->input_format % this->num_inputs % this->output_format + % this->num_outputs); } -std::string convert::id_type::to_string(void) const{ - return str(boost::format("%s (%d) -> %s (%d)") - % this->input_format - % this->num_inputs - % this->output_format - % this->num_outputs - ); +std::string convert::id_type::to_string(void) const +{ + return str(boost::format("%s (%d) -> %s (%d)") % this->input_format % this->num_inputs + % this->output_format % this->num_outputs); } /*********************************************************************** * Setup the table registry **********************************************************************/ -typedef uhd::dict<convert::id_type, uhd::dict<convert::priority_type, convert::function_type> > fcn_table_type; +typedef uhd::dict<convert::id_type, + uhd::dict<convert::priority_type, convert::function_type>> + fcn_table_type; UHD_SINGLETON_FCN(fcn_table_type, get_table); /*********************************************************************** * The registry functions **********************************************************************/ void uhd::convert::register_converter( - const id_type &id, - const function_type &fcn, - const priority_type prio -){ + const id_type& id, const function_type& fcn, const priority_type prio) +{ get_table()[id][prio] = fcn; //----------------------------------------------------------------// - //UHD_LOG_TRACE("CONVERT", boost::format("register_converter: %s prio: %s") % id.to_string() % prio) + // UHD_LOG_TRACE("CONVERT", boost::format("register_converter: %s prio: %s") % + // id.to_string() % prio) //----------------------------------------------------------------// } /*********************************************************************** * The converter functions **********************************************************************/ -convert::function_type convert::get_converter( - const id_type &id, - const priority_type prio -){ - if (not get_table().has_key(id)) throw uhd::key_error( - "Cannot find a conversion routine for " + id.to_pp_string()); - - //find a matching priority +convert::function_type convert::get_converter(const id_type& id, const priority_type prio) +{ + if (not get_table().has_key(id)) + throw uhd::key_error("Cannot find a conversion routine for " + id.to_pp_string()); + + // find a matching priority priority_type best_prio = -1; - for(priority_type prio_i: get_table()[id].keys()){ + for (priority_type prio_i : get_table()[id].keys()) { if (prio_i == prio) { //----------------------------------------------------------------// - UHD_LOGGER_DEBUG("CONVERT") << "get_converter: For converter ID: " << id.to_pp_string() - << " Using prio: " << prio; + UHD_LOGGER_DEBUG("CONVERT") + << "get_converter: For converter ID: " << id.to_pp_string() + << " Using prio: " << prio; ; //----------------------------------------------------------------// return get_table()[id][prio]; @@ -98,16 +91,18 @@ convert::function_type convert::get_converter( best_prio = std::max(best_prio, prio_i); } - //wanted a specific prio, didnt find - if (prio != -1) throw uhd::key_error( - "Cannot find a conversion routine [with prio] for " + id.to_pp_string()); + // wanted a specific prio, didnt find + if (prio != -1) + throw uhd::key_error( + "Cannot find a conversion routine [with prio] for " + id.to_pp_string()); //----------------------------------------------------------------// - UHD_LOGGER_DEBUG("CONVERT") << "get_converter: For converter ID: " << id.to_pp_string() - << " Using prio: " << best_prio; + UHD_LOGGER_DEBUG("CONVERT") + << "get_converter: For converter ID: " << id.to_pp_string() + << " Using prio: " << best_prio; //----------------------------------------------------------------// - //otherwise, return best prio + // otherwise, return best prio return get_table()[id][best_prio]; } @@ -117,29 +112,31 @@ convert::function_type convert::get_converter( typedef uhd::dict<std::string, size_t> item_size_type; UHD_SINGLETON_FCN(item_size_type, get_item_size_table); -void convert::register_bytes_per_item( - const std::string &format, const size_t size -){ +void convert::register_bytes_per_item(const std::string& format, const size_t size) +{ get_item_size_table()[format] = size; } -size_t convert::get_bytes_per_item(const std::string &format){ - if (get_item_size_table().has_key(format)) return get_item_size_table()[format]; +size_t convert::get_bytes_per_item(const std::string& format) +{ + if (get_item_size_table().has_key(format)) + return get_item_size_table()[format]; - //OK. I am sorry about this. - //We didnt find a match, so lets find a match for the first term. - //This is partially a hack because of the way I append strings. - //But as long as life is kind, we can keep this. + // OK. I am sorry about this. + // We didnt find a match, so lets find a match for the first term. + // This is partially a hack because of the way I append strings. + // But as long as life is kind, we can keep this. const size_t pos = format.find("_"); - if (pos != std::string::npos){ + if (pos != std::string::npos) { return get_bytes_per_item(format.substr(0, pos)); } throw uhd::key_error("[convert] Cannot find an item size for: `" + format + "'"); } -UHD_STATIC_BLOCK(convert_register_item_sizes){ - //register standard complex types +UHD_STATIC_BLOCK(convert_register_item_sizes) +{ + // register standard complex types convert::register_bytes_per_item("fc64", sizeof(std::complex<double>)); convert::register_bytes_per_item("fc32", sizeof(std::complex<float>)); convert::register_bytes_per_item("sc64", sizeof(std::complex<int64_t>)); @@ -147,7 +144,7 @@ UHD_STATIC_BLOCK(convert_register_item_sizes){ convert::register_bytes_per_item("sc16", sizeof(std::complex<int16_t>)); convert::register_bytes_per_item("sc8", sizeof(std::complex<int8_t>)); - //register standard real types + // register standard real types convert::register_bytes_per_item("f64", sizeof(double)); convert::register_bytes_per_item("f32", sizeof(float)); convert::register_bytes_per_item("s64", sizeof(int64_t)); @@ -156,6 +153,6 @@ UHD_STATIC_BLOCK(convert_register_item_sizes){ convert::register_bytes_per_item("s8", sizeof(int8_t)); convert::register_bytes_per_item("u8", sizeof(uint8_t)); - //register VITA types + // register VITA types convert::register_bytes_per_item("item32", sizeof(int32_t)); } diff --git a/host/lib/convert/convert_item32.cpp b/host/lib/convert/convert_item32.cpp index 142a842bb..5d8361079 100644 --- a/host/lib/convert/convert_item32.cpp +++ b/host/lib/convert/convert_item32.cpp @@ -8,23 +8,25 @@ #include "convert_common.hpp" #include <uhd/utils/byteswap.hpp> -#define __DECLARE_ITEM32_CONVERTER(cpu_type, wire_type, xe, htoxx, xxtoh) \ - DECLARE_CONVERTER(cpu_type, 1, wire_type ## _item32_ ## xe, 1, PRIORITY_GENERAL){ \ - const cpu_type ## _t *input = reinterpret_cast<const cpu_type ## _t *>(inputs[0]); \ - item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); \ - xx_to_item32_ ## wire_type<htoxx>(input, output, nsamps, scale_factor); \ - } \ - DECLARE_CONVERTER(wire_type ## _item32_ ## xe, 1, cpu_type, 1, PRIORITY_GENERAL){ \ - const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); \ - cpu_type ## _t *output = reinterpret_cast<cpu_type ## _t *>(outputs[0]); \ - item32_ ## wire_type ## _to_xx<xxtoh>(input, output, nsamps, scale_factor); \ +#define __DECLARE_ITEM32_CONVERTER(cpu_type, wire_type, xe, htoxx, xxtoh) \ + DECLARE_CONVERTER(cpu_type, 1, wire_type##_item32_##xe, 1, PRIORITY_GENERAL) \ + { \ + const cpu_type##_t* input = reinterpret_cast<const cpu_type##_t*>(inputs[0]); \ + item32_t* output = reinterpret_cast<item32_t*>(outputs[0]); \ + xx_to_item32_##wire_type<htoxx>(input, output, nsamps, scale_factor); \ + } \ + DECLARE_CONVERTER(wire_type##_item32_##xe, 1, cpu_type, 1, PRIORITY_GENERAL) \ + { \ + const item32_t* input = reinterpret_cast<const item32_t*>(inputs[0]); \ + cpu_type##_t* output = reinterpret_cast<cpu_type##_t*>(outputs[0]); \ + item32_##wire_type##_to_xx<xxtoh>(input, output, nsamps, scale_factor); \ } -#define _DECLARE_ITEM32_CONVERTER(cpu_type, wire_type) \ +#define _DECLARE_ITEM32_CONVERTER(cpu_type, wire_type) \ __DECLARE_ITEM32_CONVERTER(cpu_type, wire_type, be, uhd::htonx, uhd::ntohx) \ __DECLARE_ITEM32_CONVERTER(cpu_type, wire_type, le, uhd::htowx, uhd::wtohx) -#define DECLARE_ITEM32_CONVERTER(cpu_type) \ +#define DECLARE_ITEM32_CONVERTER(cpu_type) \ _DECLARE_ITEM32_CONVERTER(cpu_type, sc8) \ _DECLARE_ITEM32_CONVERTER(cpu_type, sc16) diff --git a/host/lib/convert/convert_pack_sc12.cpp b/host/lib/convert/convert_pack_sc12.cpp index 97a4af206..ee28e00cd 100644 --- a/host/lib/convert/convert_pack_sc12.cpp +++ b/host/lib/convert/convert_pack_sc12.cpp @@ -12,9 +12,9 @@ using namespace uhd::convert; template <typename type, towire32_type towire> struct convert_star_1_to_sc12_item32_1 : public converter { - convert_star_1_to_sc12_item32_1(void):_scalar(0.0) + convert_star_1_to_sc12_item32_1(void) : _scalar(0.0) { - //NOP + // NOP } void set_scalar(const double scalar) @@ -22,74 +22,99 @@ struct convert_star_1_to_sc12_item32_1 : public converter _scalar = scalar; } - void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps) + 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]); + const std::complex<type>* input = + reinterpret_cast<const std::complex<type>*>(inputs[0]); /* - * Effectively outputs will point to a managed_buffer instance. These buffers are 32 bit aligned. - * For a detailed description see comments in 'convert_unpack_sc12.cpp'. + * Effectively outputs will point to a managed_buffer instance. These buffers are + * 32 bit aligned. For a detailed description see comments in + * 'convert_unpack_sc12.cpp'. */ const size_t head_samps = size_t(outputs[0]) & 0x3; int enable; size_t rewind = 0; - switch(head_samps) - { - case 0: break; - case 1: rewind = 9; break; - case 2: rewind = 6; break; - case 3: rewind = 3; break; + switch (head_samps) { + case 0: + break; + case 1: + rewind = 9; + break; + case 2: + rewind = 6; + break; + case 3: + rewind = 3; + break; } - item32_sc12_3x *output = reinterpret_cast<item32_sc12_3x *>(size_t(outputs[0]) - rewind); + item32_sc12_3x* output = + reinterpret_cast<item32_sc12_3x*>(size_t(outputs[0]) - rewind); - //helper variables + // helper variables size_t i = 0, o = 0; - //handle the head case - switch (head_samps) - { - case 0: - break; //no head - case 1: - enable = CONVERT12_LINE2; - convert_star_4_to_sc12_item32_3<type, towire>(0, 0, 0, input[0], enable, output[o++], _scalar); - break; - case 2: - enable = CONVERT12_LINE2 | CONVERT12_LINE1; - convert_star_4_to_sc12_item32_3<type, towire>(0, 0, input[0], input[1], enable, output[o++], _scalar); - break; - case 3: - enable = CONVERT12_LINE2 | CONVERT12_LINE1 | CONVERT12_LINE0; - convert_star_4_to_sc12_item32_3<type, towire>(0, input[0], input[1], input[2], enable, output[o++], _scalar); - break; + // handle the head case + switch (head_samps) { + case 0: + break; // no head + case 1: + enable = CONVERT12_LINE2; + convert_star_4_to_sc12_item32_3<type, towire>( + 0, 0, 0, input[0], enable, output[o++], _scalar); + break; + case 2: + enable = CONVERT12_LINE2 | CONVERT12_LINE1; + convert_star_4_to_sc12_item32_3<type, towire>( + 0, 0, input[0], input[1], enable, output[o++], _scalar); + break; + case 3: + enable = CONVERT12_LINE2 | CONVERT12_LINE1 | CONVERT12_LINE0; + convert_star_4_to_sc12_item32_3<type, towire>( + 0, input[0], input[1], input[2], enable, 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], CONVERT12_LINE_ALL, output[o], _scalar); - o++; i += 4; + // 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], + CONVERT12_LINE_ALL, + output[o], + _scalar); + o++; + i += 4; } - //handle the tail case + // handle the tail case const size_t tail_samps = nsamps - i; - switch (tail_samps) - { - case 0: - break; //no tail - case 1: - enable = CONVERT12_LINE0; - convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], 0, 0, 0, enable, output[o], _scalar); - break; - case 2: - enable = CONVERT12_LINE0 | CONVERT12_LINE1; - convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], input[i+1], 0, 0, enable, output[o], _scalar); - break; - case 3: - enable = CONVERT12_LINE0 | CONVERT12_LINE1 | CONVERT12_LINE2; - convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], input[i+1], input[i+2], 0, enable, output[o], _scalar); - break; + switch (tail_samps) { + case 0: + break; // no tail + case 1: + enable = CONVERT12_LINE0; + convert_star_4_to_sc12_item32_3<type, towire>( + input[i + 0], 0, 0, 0, enable, output[o], _scalar); + break; + case 2: + enable = CONVERT12_LINE0 | CONVERT12_LINE1; + convert_star_4_to_sc12_item32_3<type, towire>( + input[i + 0], input[i + 1], 0, 0, enable, output[o], _scalar); + break; + case 3: + enable = CONVERT12_LINE0 | CONVERT12_LINE1 | CONVERT12_LINE2; + convert_star_4_to_sc12_item32_3<type, towire>(input[i + 0], + input[i + 1], + input[i + 2], + 0, + enable, + output[o], + _scalar); + break; } } @@ -118,21 +143,25 @@ static converter::sptr make_convert_sc16_1_to_sc12_item32_be_1(void) UHD_STATIC_BLOCK(register_convert_pack_sc12) { - //uhd::convert::register_bytes_per_item("sc12", 3/*bytes*/); //registered in unpack + // uhd::convert::register_bytes_per_item("sc12", 3/*bytes*/); //registered in unpack uhd::convert::id_type id; - id.num_inputs = 1; + id.num_inputs = 1; id.num_outputs = 1; - id.input_format = "fc32"; + 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); + 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); + uhd::convert::register_converter( + id, &make_convert_fc32_1_to_sc12_item32_be_1, PRIORITY_GENERAL); - id.input_format = "sc16"; + id.input_format = "sc16"; id.output_format = "sc12_item32_le"; - uhd::convert::register_converter(id, &make_convert_sc16_1_to_sc12_item32_le_1, PRIORITY_GENERAL); + uhd::convert::register_converter( + id, &make_convert_sc16_1_to_sc12_item32_le_1, PRIORITY_GENERAL); id.output_format = "sc12_item32_be"; - uhd::convert::register_converter(id, &make_convert_sc16_1_to_sc12_item32_be_1, PRIORITY_GENERAL); + uhd::convert::register_converter( + id, &make_convert_sc16_1_to_sc12_item32_be_1, PRIORITY_GENERAL); } diff --git a/host/lib/convert/convert_pack_sc12.hpp b/host/lib/convert/convert_pack_sc12.hpp index 053236e6f..08ec98b10 100644 --- a/host/lib/convert/convert_pack_sc12.hpp +++ b/host/lib/convert/convert_pack_sc12.hpp @@ -5,9 +5,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <type_traits> -#include <uhd/utils/byteswap.hpp> #include "convert_common.hpp" +#include <uhd/utils/byteswap.hpp> +#include <type_traits> using namespace uhd::convert; @@ -26,9 +26,9 @@ struct item32_sc12_3x }; enum item32_sc12_3x_enable { - CONVERT12_LINE0 = 0x01, - CONVERT12_LINE1 = 0x02, - CONVERT12_LINE2 = 0x04, + CONVERT12_LINE0 = 0x01, + CONVERT12_LINE1 = 0x02, + CONVERT12_LINE2 = 0x04, CONVERT12_LINE_ALL = 0x07, }; @@ -48,10 +48,10 @@ enum item32_sc12_3x_enable { * 31 0 */ template <towire32_type towire> -void pack(item32_sc12_3x &output, int enable, const int32_t iq[8]) +void pack(item32_sc12_3x& output, int enable, const int32_t iq[8]) { if (enable & CONVERT12_LINE0) - output.line0 = towire(iq[0] << 20 | iq[1] << 8 | iq[2] >> 4); + output.line0 = towire(iq[0] << 20 | iq[1] << 8 | iq[2] >> 4); if (enable & CONVERT12_LINE1) output.line1 = towire(iq[2] << 28 | iq[3] << 16 | iq[4] << 4 | iq[5] >> 8); if (enable & CONVERT12_LINE2) @@ -59,46 +59,40 @@ void pack(item32_sc12_3x &output, int enable, const int32_t iq[8]) } 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, +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, const int enable, - item32_sc12_3x &output, + item32_sc12_3x& output, const double scalar, - typename std::enable_if<std::is_floating_point<type>::value>::type* = NULL -) + typename std::enable_if<std::is_floating_point<type>::value>::type* = NULL) { - int32_t iq[8] { - int32_t(in0.real()*scalar) & 0xfff, - int32_t(in0.imag()*scalar) & 0xfff, - int32_t(in1.real()*scalar) & 0xfff, - int32_t(in1.imag()*scalar) & 0xfff, + int32_t iq[8]{ + int32_t(in0.real() * scalar) & 0xfff, + int32_t(in0.imag() * scalar) & 0xfff, + int32_t(in1.real() * scalar) & 0xfff, + int32_t(in1.imag() * scalar) & 0xfff, - int32_t(in2.real()*scalar) & 0xfff, - int32_t(in2.imag()*scalar) & 0xfff, - int32_t(in3.real()*scalar) & 0xfff, - int32_t(in3.imag()*scalar) & 0xfff, + int32_t(in2.real() * scalar) & 0xfff, + int32_t(in2.imag() * scalar) & 0xfff, + int32_t(in3.real() * scalar) & 0xfff, + int32_t(in3.imag() * scalar) & 0xfff, }; pack<towire>(output, enable, iq); } 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, +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, const int enable, - item32_sc12_3x &output, + item32_sc12_3x& output, const double, - typename std::enable_if<std::is_same<type, short>::value>::type* = NULL -) + typename std::enable_if<std::is_same<type, short>::value>::type* = NULL) { - int32_t iq[8] { + int32_t iq[8]{ int32_t(in0.real() >> 4) & 0xfff, int32_t(in0.imag() >> 4) & 0xfff, int32_t(in1.real() >> 4) & 0xfff, diff --git a/host/lib/convert/convert_unpack_sc12.cpp b/host/lib/convert/convert_unpack_sc12.cpp index 9f0a14a77..9ec43a5c3 100644 --- a/host/lib/convert/convert_unpack_sc12.cpp +++ b/host/lib/convert/convert_unpack_sc12.cpp @@ -12,25 +12,27 @@ using namespace uhd::convert; template <typename type, tohost32_type tohost> struct convert_sc12_item32_1_to_star_1 : public converter { - convert_sc12_item32_1_to_star_1(void):_scalar(0.0) + convert_sc12_item32_1_to_star_1(void) : _scalar(0.0) { - //NOP + // NOP } void set_scalar(const double scalar) { const int unpack_growth = 16; - _scalar = scalar/unpack_growth; + _scalar = scalar / unpack_growth; } /* - * This converter takes in 24 bits complex samples, 12 bits I and 12 bits Q, and converts them to type 'std::complex<type>'. - * 'type' is usually 'float'. - * For the converter to work correctly the used managed_buffer which holds all samples of one packet has to be 32 bits aligned. - * We assume 32 bits to be one line. This said the converter must be aware where it is supposed to start within 3 lines. + * This converter takes in 24 bits complex samples, 12 bits I and 12 bits Q, and + * converts them to type 'std::complex<type>'. 'type' is usually 'float'. For the + * converter to work correctly the used managed_buffer which holds all samples of one + * packet has to be 32 bits aligned. We assume 32 bits to be one line. This said the + * converter must be aware where it is supposed to start within 3 lines. * */ - void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps) + void operator()( + const input_type& inputs, const output_type& outputs, const size_t nsamps) { /* * Looking at the line structure above we can identify 4 cases. @@ -39,67 +41,102 @@ struct convert_sc12_item32_1_to_star_1 : public converter * Then the number of bytes the converter has to rewind are calculated. */ const size_t head_samps = size_t(inputs[0]) & 0x3; - size_t rewind = 0; - switch(head_samps) - { - case 0: break; - case 1: rewind = 9; break; - case 2: rewind = 6; break; - case 3: rewind = 3; break; + size_t rewind = 0; + switch (head_samps) { + case 0: + break; + case 1: + rewind = 9; + break; + case 2: + rewind = 6; + break; + case 3: + rewind = 3; + break; } /* * The pointer *input now points to the head of a 3 line block. */ - const item32_sc12_3x *input = reinterpret_cast<const item32_sc12_3x *>(size_t(inputs[0]) - rewind); - std::complex<type> *output = reinterpret_cast<std::complex<type> *>(outputs[0]); + const item32_sc12_3x* input = + reinterpret_cast<const item32_sc12_3x*>(size_t(inputs[0]) - rewind); + std::complex<type>* output = reinterpret_cast<std::complex<type>*>(outputs[0]); - //helper variables + // helper variables std::complex<type> dummy0, dummy1, dummy2; size_t i = 0, o = 0; /* * handle the head case * head_samps holds the number of samples left in a block. - * The 3 line converter is called for the whole block and already processed samples are dumped. - * We don't run into the risk of a SIGSEGV because input will always point to valid memory within a managed_buffer. - * Furthermore the bytes in a buffer remain unchanged after they have been copied into it. + * The 3 line converter is called for the whole block and already processed + * samples are dumped. We don't run into the risk of a SIGSEGV because input will + * always point to valid memory within a managed_buffer. Furthermore the bytes in + * a buffer remain unchanged after they have been copied into it. */ - 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; + 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; + // 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 * The converter can be called with any number of samples to be converted. * This can end up in only a part of a block to be converted in one call. - * We never have to worry about SIGSEGVs here as long as we end in the middle of a managed_buffer. - * If we are at the end of managed_buffer there are 2 precautions to prevent SIGSEGVs. - * Firstly only a read operation is performed. - * Secondly managed_buffers allocate a fixed size memory which is always larger than the actually used size. - * e.g. The current sample maximum is 2000 samples in a packet over USB. - * With sc12 samples a packet consists of 6000kb but managed_buffers allocate 16kb each. - * Thus we don't run into problems here either. + * We never have to worry about SIGSEGVs here as long as we end in the middle of a + * managed_buffer. If we are at the end of managed_buffer there are 2 precautions + * to prevent SIGSEGVs. Firstly only a read operation is performed. Secondly + * managed_buffers allocate a fixed size memory which is always larger than the + * actually used size. e.g. The current sample maximum is 2000 samples in a packet + * over USB. With sc12 samples a packet consists of 6000kb but managed_buffers + * allocate 16kb each. Thus we don't run into problems here either. */ 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; + 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; } } @@ -128,20 +165,24 @@ static converter::sptr make_convert_sc12_item32_be_1_to_sc16_1(void) UHD_STATIC_BLOCK(register_convert_unpack_sc12) { - uhd::convert::register_bytes_per_item("sc12", 3/*bytes*/); + uhd::convert::register_bytes_per_item("sc12", 3 /*bytes*/); uhd::convert::id_type id; - id.num_inputs = 1; + 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_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); + uhd::convert::register_converter( + id, &make_convert_sc12_item32_be_1_to_fc32_1, PRIORITY_GENERAL); id.output_format = "sc16"; - id.input_format = "sc12_item32_le"; - uhd::convert::register_converter(id, &make_convert_sc12_item32_le_1_to_sc16_1, PRIORITY_GENERAL); + id.input_format = "sc12_item32_le"; + uhd::convert::register_converter( + id, &make_convert_sc12_item32_le_1_to_sc16_1, PRIORITY_GENERAL); id.input_format = "sc12_item32_be"; - uhd::convert::register_converter(id, &make_convert_sc12_item32_be_1_to_sc16_1, PRIORITY_GENERAL); + uhd::convert::register_converter( + id, &make_convert_sc12_item32_be_1_to_sc16_1, PRIORITY_GENERAL); } diff --git a/host/lib/convert/convert_unpack_sc12.hpp b/host/lib/convert/convert_unpack_sc12.hpp index e612b035d..26e5f5d79 100644 --- a/host/lib/convert/convert_unpack_sc12.hpp +++ b/host/lib/convert/convert_unpack_sc12.hpp @@ -5,9 +5,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <type_traits> -#include <uhd/utils/byteswap.hpp> #include "convert_common.hpp" +#include <uhd/utils/byteswap.hpp> +#include <type_traits> using namespace uhd::convert; @@ -37,38 +37,35 @@ struct item32_sc12_3x * The numbers mark the position of one complex sample. */ 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, +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, - typename std::enable_if<std::is_floating_point<type>::value>::type* = NULL -) + typename std::enable_if<std::is_floating_point<type>::value>::type* = NULL) { - //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); + // 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 uint64_t line01 = (uint64_t(line0) << 32) | line1; const uint64_t line12 = (uint64_t(line1) << 32) | line2; - //step 1: shift out and mask off the individual numbers - const type i0 = type(int16_t((line0 >> 16) & 0xfff0)*scalar); - const type q0 = type(int16_t((line0 >> 4) & 0xfff0)*scalar); + // step 1: shift out and mask off the individual numbers + const type i0 = type(int16_t((line0 >> 16) & 0xfff0) * scalar); + const type q0 = type(int16_t((line0 >> 4) & 0xfff0) * scalar); - const type i1 = type(int16_t((line01 >> 24) & 0xfff0)*scalar); - const type q1 = type(int16_t((line1 >> 12) & 0xfff0)*scalar); + const type i1 = type(int16_t((line01 >> 24) & 0xfff0) * scalar); + const type q1 = type(int16_t((line1 >> 12) & 0xfff0) * scalar); - const type i2 = type(int16_t((line1 >> 0) & 0xfff0)*scalar); - const type q2 = type(int16_t((line12 >> 20) & 0xfff0)*scalar); + const type i2 = type(int16_t((line1 >> 0) & 0xfff0) * scalar); + const type q2 = type(int16_t((line12 >> 20) & 0xfff0) * scalar); - const type i3 = type(int16_t((line2 >> 8) & 0xfff0)*scalar); - const type q3 = type(int16_t((line2 << 4) & 0xfff0)*scalar); + const type i3 = type(int16_t((line2 >> 8) & 0xfff0) * scalar); + const type q3 = type(int16_t((line2 << 4) & 0xfff0) * scalar); - //step 2: load the outputs + // step 2: load the outputs out0 = std::complex<type>(i0, q0); out1 = std::complex<type>(i1, q1); out2 = std::complex<type>(i2, q2); @@ -76,27 +73,24 @@ void convert_sc12_item32_3_to_star_4 } 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, +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, - typename std::enable_if<std::is_integral<type>::value>::type* = NULL -) + typename std::enable_if<std::is_integral<type>::value>::type* = NULL) { - //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); + // 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 uint64_t line01 = (uint64_t(line0) << 32) | line1; const uint64_t line12 = (uint64_t(line1) << 32) | line2; - //step 1: extract and load the outputs - out0 = std::complex<type>(line0 >> 16 & 0xfff0, line0 >> 4 & 0xfff0); - out1 = std::complex<type>(line01 >> 24 & 0xfff0, line1 >> 12 & 0xfff0); - out2 = std::complex<type>(line1 >> 0 & 0xfff0, line12 >> 20 & 0xfff0); - out3 = std::complex<type>(line2 >> 8 & 0xfff0, line2 << 4 & 0xfff0); + // step 1: extract and load the outputs + out0 = std::complex<type>(line0 >> 16 & 0xfff0, line0 >> 4 & 0xfff0); + out1 = std::complex<type>(line01 >> 24 & 0xfff0, line1 >> 12 & 0xfff0); + out2 = std::complex<type>(line1 >> 0 & 0xfff0, line12 >> 20 & 0xfff0); + out3 = std::complex<type>(line2 >> 8 & 0xfff0, line2 << 4 & 0xfff0); } diff --git a/host/lib/convert/convert_with_neon.cpp b/host/lib/convert/convert_with_neon.cpp index 8a3bd29d5..9aec68bab 100644 --- a/host/lib/convert/convert_with_neon.cpp +++ b/host/lib/convert/convert_with_neon.cpp @@ -10,119 +10,123 @@ #include <arm_neon.h> extern "C" { -void neon_item32_sc16_swap_16n(void *, void *, int iter); +void neon_item32_sc16_swap_16n(void*, void*, int iter); } static const int SIMD_WIDTH = 16; using namespace uhd::convert; -DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_SIMD){ - const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]); - item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); +DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_SIMD) +{ + const fc32_t* input = reinterpret_cast<const fc32_t*>(inputs[0]); + item32_t* output = reinterpret_cast<item32_t*>(outputs[0]); size_t i; float32x4_t Q0 = vdupq_n_f32(float(scale_factor)); - for (i=0; i < (nsamps & ~0x0f); i+=8) { - float32x4_t Q1 = vld1q_f32(reinterpret_cast<const float *>(&input[i])); - float32x4_t Q4 = vld1q_f32(reinterpret_cast<const float *>(&input[i+2])); - float32x4_t Q7 = vld1q_f32(reinterpret_cast<const float *>(&input[i+4])); - float32x4_t Q10 = vld1q_f32(reinterpret_cast<const float *>(&input[i+6])); + for (i = 0; i < (nsamps & ~0x0f); i += 8) { + float32x4_t Q1 = vld1q_f32(reinterpret_cast<const float*>(&input[i])); + float32x4_t Q4 = vld1q_f32(reinterpret_cast<const float*>(&input[i + 2])); + float32x4_t Q7 = vld1q_f32(reinterpret_cast<const float*>(&input[i + 4])); + float32x4_t Q10 = vld1q_f32(reinterpret_cast<const float*>(&input[i + 6])); float32x4_t Q2 = vmulq_f32(Q1, Q0); - int32x4_t Q3 = vcvtq_s32_f32(Q2); - int16x4_t D8 = vmovn_s32(Q3); - int16x4_t D9 = vrev32_s16(D8); - vst1_s16((reinterpret_cast<int16_t *>(&output[i])), D9); + int32x4_t Q3 = vcvtq_s32_f32(Q2); + int16x4_t D8 = vmovn_s32(Q3); + int16x4_t D9 = vrev32_s16(D8); + vst1_s16((reinterpret_cast<int16_t*>(&output[i])), D9); float32x4_t Q5 = vmulq_f32(Q4, Q0); - int32x4_t Q6 = vcvtq_s32_f32(Q5); - int16x4_t D10 = vmovn_s32(Q6); - int16x4_t D11 = vrev32_s16(D10); - vst1_s16((reinterpret_cast<int16_t *>(&output[i+2])), D11); + int32x4_t Q6 = vcvtq_s32_f32(Q5); + int16x4_t D10 = vmovn_s32(Q6); + int16x4_t D11 = vrev32_s16(D10); + vst1_s16((reinterpret_cast<int16_t*>(&output[i + 2])), D11); float32x4_t Q8 = vmulq_f32(Q7, Q0); - int32x4_t Q9 = vcvtq_s32_f32(Q8); - int16x4_t D12 = vmovn_s32(Q9); - int16x4_t D13 = vrev32_s16(D12); - vst1_s16((reinterpret_cast<int16_t *>(&output[i+4])), D13); + int32x4_t Q9 = vcvtq_s32_f32(Q8); + int16x4_t D12 = vmovn_s32(Q9); + int16x4_t D13 = vrev32_s16(D12); + vst1_s16((reinterpret_cast<int16_t*>(&output[i + 4])), D13); float32x4_t Q11 = vmulq_f32(Q10, Q0); - int32x4_t Q13 = vcvtq_s32_f32(Q11); - int16x4_t D14 = vmovn_s32(Q13); - int16x4_t D15 = vrev32_s16(D14); - vst1_s16((reinterpret_cast<int16_t *>(&output[i+6])), D15); + int32x4_t Q13 = vcvtq_s32_f32(Q11); + int16x4_t D14 = vmovn_s32(Q13); + int16x4_t D15 = vrev32_s16(D14); + vst1_s16((reinterpret_cast<int16_t*>(&output[i + 6])), D15); } - xx_to_item32_sc16<uhd::htowx>(input+i, output+i, nsamps-i, scale_factor); + xx_to_item32_sc16<uhd::htowx>(input + i, output + i, nsamps - i, scale_factor); } -DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_SIMD){ - const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); - fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]); +DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_SIMD) +{ + const item32_t* input = reinterpret_cast<const item32_t*>(inputs[0]); + fc32_t* output = reinterpret_cast<fc32_t*>(outputs[0]); size_t i; float32x4_t Q1 = vdupq_n_f32(float(scale_factor)); - for (i=0; i < (nsamps & ~0xf); i+=8) { - int16x4_t D0 = vld1_s16(reinterpret_cast<const int16_t *>(&input[i])); - int16x4_t D2 = vld1_s16(reinterpret_cast<const int16_t *>(&input[i+2])); - int16x4_t D4 = vld1_s16(reinterpret_cast<const int16_t *>(&input[i+4])); - int16x4_t D6 = vld1_s16(reinterpret_cast<const int16_t *>(&input[i+6])); - - int16x4_t D1 = vrev32_s16(D0); - int32x4_t Q2 = vmovl_s16(D1); + for (i = 0; i < (nsamps & ~0xf); i += 8) { + int16x4_t D0 = vld1_s16(reinterpret_cast<const int16_t*>(&input[i])); + int16x4_t D2 = vld1_s16(reinterpret_cast<const int16_t*>(&input[i + 2])); + int16x4_t D4 = vld1_s16(reinterpret_cast<const int16_t*>(&input[i + 4])); + int16x4_t D6 = vld1_s16(reinterpret_cast<const int16_t*>(&input[i + 6])); + + int16x4_t D1 = vrev32_s16(D0); + int32x4_t Q2 = vmovl_s16(D1); float32x4_t Q3 = vcvtq_f32_s32(Q2); float32x4_t Q4 = vmulq_f32(Q3, Q1); - vst1q_f32((reinterpret_cast<float *>(&output[i])), Q4); + vst1q_f32((reinterpret_cast<float*>(&output[i])), Q4); - int16x4_t D3 = vrev32_s16(D2); - int32x4_t Q5 = vmovl_s16(D3); + int16x4_t D3 = vrev32_s16(D2); + int32x4_t Q5 = vmovl_s16(D3); float32x4_t Q6 = vcvtq_f32_s32(Q5); float32x4_t Q7 = vmulq_f32(Q6, Q1); - vst1q_f32((reinterpret_cast<float *>(&output[i+2])), Q7); + vst1q_f32((reinterpret_cast<float*>(&output[i + 2])), Q7); - int16x4_t D5 = vrev32_s16(D4); - int32x4_t Q8 = vmovl_s16(D5); - float32x4_t Q9 = vcvtq_f32_s32(Q8); + int16x4_t D5 = vrev32_s16(D4); + int32x4_t Q8 = vmovl_s16(D5); + float32x4_t Q9 = vcvtq_f32_s32(Q8); float32x4_t Q10 = vmulq_f32(Q9, Q1); - vst1q_f32((reinterpret_cast<float *>(&output[i+4])), Q10); + vst1q_f32((reinterpret_cast<float*>(&output[i + 4])), Q10); - int16x4_t D7 = vrev32_s16(D6); - int32x4_t Q11 = vmovl_s16(D7); + int16x4_t D7 = vrev32_s16(D6); + int32x4_t Q11 = vmovl_s16(D7); float32x4_t Q12 = vcvtq_f32_s32(Q11); float32x4_t Q13 = vmulq_f32(Q12, Q1); - vst1q_f32((reinterpret_cast<float *>(&output[i+6])), Q13); + vst1q_f32((reinterpret_cast<float*>(&output[i + 6])), Q13); } - item32_sc16_to_xx<uhd::htowx>(input+i, output+i, nsamps-i, scale_factor); + item32_sc16_to_xx<uhd::htowx>(input + i, output + i, nsamps - i, scale_factor); } -DECLARE_CONVERTER(sc16, 1, sc16_item32_le, 1, PRIORITY_SIMD){ - const sc16_t *input = reinterpret_cast<const sc16_t *>(inputs[0]); - item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); +DECLARE_CONVERTER(sc16, 1, sc16_item32_le, 1, PRIORITY_SIMD) +{ + const sc16_t* input = reinterpret_cast<const sc16_t*>(inputs[0]); + item32_t* output = reinterpret_cast<item32_t*>(outputs[0]); size_t i = nsamps / SIMD_WIDTH; if (i) - neon_item32_sc16_swap_16n((void *) input, (void *) output, i); + neon_item32_sc16_swap_16n((void*)input, (void*)output, i); i *= SIMD_WIDTH; - xx_to_item32_sc16<uhd::htowx>(input+i, output+i, nsamps-i, scale_factor); + xx_to_item32_sc16<uhd::htowx>(input + i, output + i, nsamps - i, scale_factor); } -DECLARE_CONVERTER(sc16_item32_le, 1, sc16, 1, PRIORITY_SIMD){ - const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); - sc16_t *output = reinterpret_cast<sc16_t *>(outputs[0]); +DECLARE_CONVERTER(sc16_item32_le, 1, sc16, 1, PRIORITY_SIMD) +{ + const item32_t* input = reinterpret_cast<const item32_t*>(inputs[0]); + sc16_t* output = reinterpret_cast<sc16_t*>(outputs[0]); size_t i = nsamps / SIMD_WIDTH; if (i) - neon_item32_sc16_swap_16n((void *) input, (void *) output, i); + neon_item32_sc16_swap_16n((void*)input, (void*)output, i); i *= SIMD_WIDTH; - item32_sc16_to_xx<uhd::wtohx>(input+i, output+i, nsamps-i, scale_factor); + item32_sc16_to_xx<uhd::wtohx>(input + i, output + i, nsamps - i, scale_factor); } diff --git a/host/lib/convert/convert_with_tables.cpp b/host/lib/convert/convert_with_tables.cpp index 5c9248052..86637171a 100644 --- a/host/lib/convert/convert_with_tables.cpp +++ b/host/lib/convert/convert_with_tables.cpp @@ -20,7 +20,8 @@ typedef uint16_t (*tohost16_type)(uint16_t); * Implementation for sc16 to sc8 lookup table * - Lookup the real and imaginary parts individually **********************************************************************/ -template <bool swap> class convert_sc16_1_to_sc8_item32_1 : public converter +template <bool swap> +class convert_sc16_1_to_sc8_item32_1 : public converter { public: convert_sc16_1_to_sc8_item32_1(void) : _table(sc16_table_len) {} diff --git a/host/lib/convert/ssse3_pack_sc12.cpp b/host/lib/convert/ssse3_pack_sc12.cpp index e71c2288b..4ba14db3b 100644 --- a/host/lib/convert/ssse3_pack_sc12.cpp +++ b/host/lib/convert/ssse3_pack_sc12.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <tmmintrin.h> #include "convert_pack_sc12.hpp" +#include <tmmintrin.h> /* * Shuffle Orderings - Single 128-bit SSE register @@ -44,24 +44,21 @@ * ----------------------- * 31 0 */ -#define SC12_SHIFT_MASK 0xfff0fff0, 0xfff0fff0, 0x0fff0fff, 0x0fff0fff -#define SC12_PACK_SHUFFLE1 13,12,9,8,5,4,1,0,15,14,11,10,7,6,3,2 -#define SC12_PACK_SHUFFLE2 9,8,0,11,10,2,13,12,4,15,14,6,0,0,0,0 -#define SC12_PACK_SHUFFLE3 8,1,8,8,3,8,8,5,8,8,7,8,8,8,8,8 +#define SC12_SHIFT_MASK 0xfff0fff0, 0xfff0fff0, 0x0fff0fff, 0x0fff0fff +#define SC12_PACK_SHUFFLE1 13, 12, 9, 8, 5, 4, 1, 0, 15, 14, 11, 10, 7, 6, 3, 2 +#define SC12_PACK_SHUFFLE2 9, 8, 0, 11, 10, 2, 13, 12, 4, 15, 14, 6, 0, 0, 0, 0 +#define SC12_PACK_SHUFFLE3 8, 1, 8, 8, 3, 8, 8, 5, 8, 8, 7, 8, 8, 8, 8, 8 template <typename type> -inline void convert_star_4_to_sc12_item32_3 -( - const std::complex<type> *in, - item32_sc12_3x &output, +inline void convert_star_4_to_sc12_item32_3(const std::complex<type>* in, + item32_sc12_3x& output, const double scalar, - typename std::enable_if<std::is_same<type, float>::value>::type* = NULL -) + typename std::enable_if<std::is_same<type, float>::value>::type* = NULL) { __m128 m0, m1, m2; m0 = _mm_set1_ps(scalar); - m1 = _mm_loadu_ps((const float *) &in[0]); - m2 = _mm_loadu_ps((const float *) &in[2]); + m1 = _mm_loadu_ps((const float*)&in[0]); + m2 = _mm_loadu_ps((const float*)&in[2]); m1 = _mm_mul_ps(m1, m0); m2 = _mm_mul_ps(m2, m0); m0 = _mm_shuffle_ps(m1, m2, _MM_SHUFFLE(2, 0, 2, 0)); @@ -84,17 +81,14 @@ inline void convert_star_4_to_sc12_item32_3 m6 = _mm_or_si128(m6, m7); m6 = _mm_shuffle_epi32(m6, _MM_SHUFFLE(0, 1, 2, 3)); - _mm_storeu_si128((__m128i*) &output, m6); + _mm_storeu_si128((__m128i*)&output, m6); } template <typename type> -static void convert_star_4_to_sc12_item32_3 -( - const std::complex<type> *in, - item32_sc12_3x &output, +static void convert_star_4_to_sc12_item32_3(const std::complex<type>* in, + item32_sc12_3x& output, const double, - typename std::enable_if<std::is_same<type, short>::value>::type* = NULL -) + typename std::enable_if<std::is_same<type, short>::value>::type* = NULL) { __m128i m0, m1, m2, m3, m4, m5; m0 = _mm_set_epi32(SC12_SHIFT_MASK); @@ -102,7 +96,7 @@ static void convert_star_4_to_sc12_item32_3 m2 = _mm_set_epi8(SC12_PACK_SHUFFLE2); m3 = _mm_set_epi8(SC12_PACK_SHUFFLE3); - m4 = _mm_loadu_si128((__m128i*) in); + m4 = _mm_loadu_si128((__m128i*)in); m4 = _mm_shuffle_epi8(m4, m1); m5 = _mm_srli_epi16(m4, 4); m4 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(0, 0, 3, 2)); @@ -115,57 +109,66 @@ static void convert_star_4_to_sc12_item32_3 m3 = _mm_or_si128(m4, m5); m3 = _mm_shuffle_epi32(m3, _MM_SHUFFLE(0, 1, 2, 3)); - _mm_storeu_si128((__m128i*) &output, m3); + _mm_storeu_si128((__m128i*)&output, m3); } template <typename type, towire32_type towire> struct convert_star_1_to_sc12_item32_2 : public converter { - convert_star_1_to_sc12_item32_2(void):_scalar(0.0) - { - } + convert_star_1_to_sc12_item32_2(void) : _scalar(0.0) {} void set_scalar(const double scalar) { _scalar = scalar; } - void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps) + 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]); + const std::complex<type>* input = + reinterpret_cast<const std::complex<type>*>(inputs[0]); const size_t head_samps = size_t(outputs[0]) & 0x3; int enable; size_t rewind = 0; - switch(head_samps) - { - case 0: break; - case 1: rewind = 9; break; - case 2: rewind = 6; break; - case 3: rewind = 3; break; + switch (head_samps) { + case 0: + break; + case 1: + rewind = 9; + break; + case 2: + rewind = 6; + break; + case 3: + rewind = 3; + break; } - item32_sc12_3x *output = reinterpret_cast<item32_sc12_3x *>(size_t(outputs[0]) - rewind); + item32_sc12_3x* output = + reinterpret_cast<item32_sc12_3x*>(size_t(outputs[0]) - rewind); - //helper variables + // helper variables size_t i = 0, o = 0; - //handle the head case - switch (head_samps) - { - case 0: - break; //no head - case 1: - enable = CONVERT12_LINE2; - convert_star_4_to_sc12_item32_3<type, towire>(0, 0, 0, input[0], enable, output[o++], _scalar); - break; - case 2: - enable = CONVERT12_LINE2 | CONVERT12_LINE1; - convert_star_4_to_sc12_item32_3<type, towire>(0, 0, input[0], input[1], enable, output[o++], _scalar); - break; - case 3: - enable = CONVERT12_LINE2 | CONVERT12_LINE1 | CONVERT12_LINE0; - convert_star_4_to_sc12_item32_3<type, towire>(0, input[0], input[1], input[2], enable, output[o++], _scalar); - break; + // handle the head case + switch (head_samps) { + case 0: + break; // no head + case 1: + enable = CONVERT12_LINE2; + convert_star_4_to_sc12_item32_3<type, towire>( + 0, 0, 0, input[0], enable, output[o++], _scalar); + break; + case 2: + enable = CONVERT12_LINE2 | CONVERT12_LINE1; + convert_star_4_to_sc12_item32_3<type, towire>( + 0, 0, input[0], input[1], enable, output[o++], _scalar); + break; + case 3: + enable = CONVERT12_LINE2 | CONVERT12_LINE1 | CONVERT12_LINE0; + convert_star_4_to_sc12_item32_3<type, towire>( + 0, input[0], input[1], input[2], enable, output[o++], _scalar); + break; } i += head_samps; @@ -174,34 +177,47 @@ struct convert_star_1_to_sc12_item32_2 : public converter // subsequent samples to be converted (writes will simply happen // twice). So set the conversion loop to force a tail case on the // final 4 or fewer samples. - while (i+4 < nsamps) - { + while (i + 4 < nsamps) { convert_star_4_to_sc12_item32_3<type>(&input[i], output[o], _scalar); - o++; i += 4; + o++; + i += 4; } - //handle the tail case + // handle the tail case const size_t tail_samps = nsamps - i; - switch (tail_samps) - { - case 0: - break; //no tail - case 1: - enable = CONVERT12_LINE0; - convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], 0, 0, 0, enable, output[o], _scalar); - break; - case 2: - enable = CONVERT12_LINE0 | CONVERT12_LINE1; - convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], input[i+1], 0, 0, enable, output[o], _scalar); - break; - case 3: - enable = CONVERT12_LINE0 | CONVERT12_LINE1 | CONVERT12_LINE2; - convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], input[i+1], input[i+2], 0, enable, output[o], _scalar); - break; - case 4: - enable = CONVERT12_LINE_ALL; - convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], input[i+1], input[i+2], input[i+3], enable, output[o], _scalar); - break; + switch (tail_samps) { + case 0: + break; // no tail + case 1: + enable = CONVERT12_LINE0; + convert_star_4_to_sc12_item32_3<type, towire>( + input[i + 0], 0, 0, 0, enable, output[o], _scalar); + break; + case 2: + enable = CONVERT12_LINE0 | CONVERT12_LINE1; + convert_star_4_to_sc12_item32_3<type, towire>( + input[i + 0], input[i + 1], 0, 0, enable, output[o], _scalar); + break; + case 3: + enable = CONVERT12_LINE0 | CONVERT12_LINE1 | CONVERT12_LINE2; + convert_star_4_to_sc12_item32_3<type, towire>(input[i + 0], + input[i + 1], + input[i + 2], + 0, + enable, + output[o], + _scalar); + break; + case 4: + enable = CONVERT12_LINE_ALL; + convert_star_4_to_sc12_item32_3<type, towire>(input[i + 0], + input[i + 1], + input[i + 2], + input[i + 3], + enable, + output[o], + _scalar); + break; } } @@ -221,14 +237,16 @@ static converter::sptr make_convert_sc16_1_to_sc12_item32_le_1(void) UHD_STATIC_BLOCK(register_sse_pack_sc12) { uhd::convert::id_type id; - id.num_inputs = 1; + id.num_inputs = 1; id.num_outputs = 1; - id.input_format = "fc32"; + 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_SIMD); + uhd::convert::register_converter( + id, &make_convert_fc32_1_to_sc12_item32_le_1, PRIORITY_SIMD); - id.input_format = "sc16"; + id.input_format = "sc16"; id.output_format = "sc12_item32_le"; - uhd::convert::register_converter(id, &make_convert_sc16_1_to_sc12_item32_le_1, PRIORITY_SIMD); + uhd::convert::register_converter( + id, &make_convert_sc16_1_to_sc12_item32_le_1, PRIORITY_SIMD); } diff --git a/host/lib/convert/ssse3_unpack_sc12.cpp b/host/lib/convert/ssse3_unpack_sc12.cpp index a6e147142..5494e0fd7 100644 --- a/host/lib/convert/ssse3_unpack_sc12.cpp +++ b/host/lib/convert/ssse3_unpack_sc12.cpp @@ -59,23 +59,20 @@ using namespace uhd::convert; * | 127 0 | * */ -#define SC12_SHIFT_MASK 0x0fff0fff, 0x0fff0fff, 0xfff0fff0, 0xfff0fff0 -#define SC12_PACK_SHUFFLE1 5,4,8,7,11,10,14,13,6,5,9,8,12,11,15,14 -#define SC12_PACK_SHUFFLE2 15,14,7,6,13,12,5,4,11,10,3,2,9,8,1,0 +#define SC12_SHIFT_MASK 0x0fff0fff, 0x0fff0fff, 0xfff0fff0, 0xfff0fff0 +#define SC12_PACK_SHUFFLE1 5, 4, 8, 7, 11, 10, 14, 13, 6, 5, 9, 8, 12, 11, 15, 14 +#define SC12_PACK_SHUFFLE2 15, 14, 7, 6, 13, 12, 5, 4, 11, 10, 3, 2, 9, 8, 1, 0 template <typename type, tohost32_type tohost> -inline void convert_sc12_item32_3_to_star_4 -( - const item32_sc12_3x &input, - std::complex<type> *out, +inline void convert_sc12_item32_3_to_star_4(const item32_sc12_3x& input, + std::complex<type>* out, double scalar, - typename std::enable_if<std::is_same<type, float>::value>::type* = NULL -) + typename std::enable_if<std::is_same<type, float>::value>::type* = NULL) { __m128i m0, m1, m2, m3, m4; m0 = _mm_set_epi32(SC12_SHIFT_MASK); m1 = _mm_set_epi8(SC12_PACK_SHUFFLE1); - m2 = _mm_loadu_si128((__m128i*) &input); + m2 = _mm_loadu_si128((__m128i*)&input); m2 = _mm_shuffle_epi32(m2, _MM_SHUFFLE(0, 1, 2, 3)); m3 = _mm_shuffle_epi8(m2, m1); m3 = _mm_and_si128(m3, m0); @@ -88,7 +85,7 @@ inline void convert_sc12_item32_3_to_star_4 m4 = _mm_unpackhi_epi32(m1, m2); __m128 m5, m6, m7; - m5 = _mm_set_ps1(scalar/(1 << 16)); + m5 = _mm_set_ps1(scalar / (1 << 16)); m6 = _mm_cvtepi32_ps(m3); m7 = _mm_cvtepi32_ps(m4); m6 = _mm_mul_ps(m6, m5); @@ -99,20 +96,17 @@ inline void convert_sc12_item32_3_to_star_4 } template <typename type, tohost32_type tohost> -inline void convert_sc12_item32_3_to_star_4 -( - const item32_sc12_3x &input, - std::complex<type> *out, +inline void convert_sc12_item32_3_to_star_4(const item32_sc12_3x& input, + std::complex<type>* out, double, - typename std::enable_if<std::is_same<type, short>::value>::type* = NULL -) + typename std::enable_if<std::is_same<type, short>::value>::type* = NULL) { __m128i m0, m1, m2, m3; m0 = _mm_set_epi32(SC12_SHIFT_MASK); m1 = _mm_set_epi8(SC12_PACK_SHUFFLE1); m2 = _mm_set_epi8(SC12_PACK_SHUFFLE2); - m3 = _mm_loadu_si128((__m128i*) &input); + m3 = _mm_loadu_si128((__m128i*)&input); m3 = _mm_shuffle_epi32(m3, _MM_SHUFFLE(0, 1, 2, 3)); m3 = _mm_shuffle_epi8(m3, m1); m3 = _mm_and_si128(m3, m0); @@ -122,62 +116,92 @@ inline void convert_sc12_item32_3_to_star_4 m0 = _mm_unpackhi_epi64(m1, m0); m1 = _mm_shuffle_epi8(m0, m2); - _mm_storeu_si128((__m128i*) out, m1); + _mm_storeu_si128((__m128i*)out, m1); } template <typename type, tohost32_type tohost> struct convert_sc12_item32_1_to_star_2 : public converter { - convert_sc12_item32_1_to_star_2(void):_scalar(0.0) + convert_sc12_item32_1_to_star_2(void) : _scalar(0.0) { - //NOP + // NOP } void set_scalar(const double scalar) { const int unpack_growth = 16; - _scalar = scalar/unpack_growth; + _scalar = scalar / unpack_growth; } - void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps) + void operator()( + const input_type& inputs, const output_type& outputs, const size_t nsamps) { const size_t head_samps = size_t(inputs[0]) & 0x3; - size_t rewind = 0; - switch(head_samps) - { - case 0: break; - case 1: rewind = 9; break; - case 2: rewind = 6; break; - case 3: rewind = 3; break; + size_t rewind = 0; + switch (head_samps) { + case 0: + break; + case 1: + rewind = 9; + break; + case 2: + rewind = 6; + break; + case 3: + rewind = 3; + break; } - const item32_sc12_3x *input = reinterpret_cast<const item32_sc12_3x *>(size_t(inputs[0]) - rewind); - std::complex<type> *output = reinterpret_cast<std::complex<type> *>(outputs[0]); + const item32_sc12_3x* input = + reinterpret_cast<const item32_sc12_3x*>(size_t(inputs[0]) - rewind); + std::complex<type>* output = reinterpret_cast<std::complex<type>*>(outputs[0]); std::complex<type> dummy; size_t i = 0, o = 0; - switch (head_samps) - { - case 0: break; //no head - case 1: convert_sc12_item32_3_to_star_4<type, tohost>(input[i++], dummy, dummy, dummy, output[0], _scalar); break; - case 2: convert_sc12_item32_3_to_star_4<type, tohost>(input[i++], dummy, dummy, output[0], output[1], _scalar); break; - case 3: convert_sc12_item32_3_to_star_4<type, tohost>(input[i++], dummy, output[0], output[1], output[2], _scalar); break; + switch (head_samps) { + case 0: + break; // no head + case 1: + convert_sc12_item32_3_to_star_4<type, tohost>( + input[i++], dummy, dummy, dummy, output[0], _scalar); + break; + case 2: + convert_sc12_item32_3_to_star_4<type, tohost>( + input[i++], dummy, dummy, output[0], output[1], _scalar); + break; + case 3: + convert_sc12_item32_3_to_star_4<type, tohost>( + input[i++], dummy, 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], _scalar); - i += 1; o += 4; + // convert the body + while (o + 3 < nsamps) { + convert_sc12_item32_3_to_star_4<type, tohost>(input[i], &output[o], _scalar); + i += 1; + o += 4; } 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], dummy, dummy, dummy, _scalar); break; - case 2: convert_sc12_item32_3_to_star_4<type, tohost>(input[i], output[o+0], output[o+1], dummy, dummy, _scalar); break; - case 3: convert_sc12_item32_3_to_star_4<type, tohost>(input[i], output[o+0], output[o+1], output[o+2], dummy, _scalar); break; + switch (tail_samps) { + case 0: + break; // no tail + case 1: + convert_sc12_item32_3_to_star_4<type, tohost>( + input[i], output[o + 0], dummy, dummy, dummy, _scalar); + break; + case 2: + convert_sc12_item32_3_to_star_4<type, tohost>( + input[i], output[o + 0], output[o + 1], dummy, dummy, _scalar); + break; + case 3: + convert_sc12_item32_3_to_star_4<type, tohost>(input[i], + output[o + 0], + output[o + 1], + output[o + 2], + dummy, + _scalar); + break; } } @@ -197,13 +221,15 @@ static converter::sptr make_convert_sc12_item32_le_1_to_sc16_1(void) UHD_STATIC_BLOCK(register_sse_unpack_sc12) { uhd::convert::id_type id; - id.num_inputs = 1; - id.num_outputs = 1; + 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_SIMD); + id.input_format = "sc12_item32_le"; + uhd::convert::register_converter( + id, &make_convert_sc12_item32_le_1_to_fc32_1, PRIORITY_SIMD); id.output_format = "sc16"; - id.input_format = "sc12_item32_le"; - uhd::convert::register_converter(id, &make_convert_sc12_item32_le_1_to_sc16_1, PRIORITY_SIMD); + id.input_format = "sc12_item32_le"; + uhd::convert::register_converter( + id, &make_convert_sc12_item32_le_1_to_sc16_1, PRIORITY_SIMD); } diff --git a/host/lib/device.cpp b/host/lib/device.cpp index 752e70288..9fdbc03ed 100644 --- a/host/lib/device.cpp +++ b/host/lib/device.cpp @@ -6,18 +6,15 @@ // #include <uhd/device.hpp> -#include <uhd/types/dict.hpp> #include <uhd/exception.hpp> +#include <uhd/types/dict.hpp> +#include <uhd/utils/algorithm.hpp> #include <uhd/utils/log.hpp> - #include <uhd/utils/static.hpp> -#include <uhd/utils/algorithm.hpp> #include <uhdlib/utils/prefs.hpp> - #include <boost/format.hpp> #include <boost/functional/hash.hpp> #include <boost/thread/mutex.hpp> - #include <future> #include <memory> #include <tuple> @@ -35,30 +32,23 @@ static boost::mutex _device_mutex; * \param dev_addr the device address * \return the hash number */ -static size_t hash_device_addr( - const device_addr_t &dev_addr -){ - //combine the hashes of sorted keys/value pairs +static size_t hash_device_addr(const device_addr_t& dev_addr) +{ + // combine the hashes of sorted keys/value pairs size_t hash = 0; // The device addr can contain all sorts of stuff, which sometimes gets in // the way of hashing reliably. TODO: Make this a whitelist const std::vector<std::string> hash_key_blacklist = { - "claimed", - "skip_dram", - "skip_ddc", - "skip_duc" - }; + "claimed", "skip_dram", "skip_ddc", "skip_duc"}; - if(dev_addr.has_key("resource")) { + if (dev_addr.has_key("resource")) { boost::hash_combine(hash, "resource"); boost::hash_combine(hash, dev_addr["resource"]); - } - else { - for (const std::string &key: uhd::sorted(dev_addr.keys())) { - if (std::find(hash_key_blacklist.begin(), - hash_key_blacklist.end(), - key) == hash_key_blacklist.end()) { + } else { + for (const std::string& key : uhd::sorted(dev_addr.keys())) { + if (std::find(hash_key_blacklist.begin(), hash_key_blacklist.end(), key) + == hash_key_blacklist.end()) { boost::hash_combine(hash, key); boost::hash_combine(hash, dev_addr[key]); } @@ -76,45 +66,38 @@ typedef std::tuple<device::find_t, device::make_t, device::device_filter_t> dev_ UHD_SINGLETON_FCN(std::vector<dev_fcn_reg_t>, get_dev_fcn_regs) void device::register_device( - const find_t &find, - const make_t &make, - const device_filter_t filter -){ + const find_t& find, const make_t& make, const device_filter_t filter) +{ // UHD_LOGGER_TRACE("UHD") << "registering device"; get_dev_fcn_regs().push_back(dev_fcn_reg_t(find, make, filter)); } -device::~device(void){ +device::~device(void) +{ /* NOP */ } /*********************************************************************** * Discover **********************************************************************/ -device_addrs_t device::find(const device_addr_t &hint, device_filter_t filter){ +device_addrs_t device::find(const device_addr_t& hint, device_filter_t filter) +{ boost::mutex::scoped_lock lock(_device_mutex); device_addrs_t device_addrs; std::vector<std::future<device_addrs_t>> find_tasks; for (const auto& fcn : get_dev_fcn_regs()) { if (filter == ANY or std::get<2>(fcn) == filter) { - find_tasks.emplace_back(std::async(std::launch::async, - [fcn, hint](){ - return std::get<0>(fcn)(hint); - } - )); + find_tasks.emplace_back(std::async( + std::launch::async, [fcn, hint]() { return std::get<0>(fcn)(hint); })); } } - for(auto &find_task : find_tasks) { + for (auto& find_task : find_tasks) { try { device_addrs_t discovered_addrs = find_task.get(); device_addrs.insert( - device_addrs.begin(), - discovered_addrs.begin(), - discovered_addrs.end() - ); - } - catch (const std::exception &e) { + device_addrs.begin(), discovered_addrs.begin(), discovered_addrs.end()); + } catch (const std::exception& e) { UHD_LOGGER_ERROR("UHD") << "Device discovery error: " << e.what(); } } @@ -125,77 +108,78 @@ device_addrs_t device::find(const device_addr_t &hint, device_filter_t filter){ /*********************************************************************** * Make **********************************************************************/ -device::sptr device::make(const device_addr_t &hint, device_filter_t filter, size_t which){ +device::sptr device::make(const device_addr_t& hint, device_filter_t filter, size_t which) +{ boost::mutex::scoped_lock lock(_device_mutex); typedef std::tuple<device_addr_t, make_t> dev_addr_make_t; std::vector<dev_addr_make_t> dev_addr_makers; device_addr_t hint_with_prefs = prefs::get_usrp_args(hint); - UHD_LOGGER_DEBUG("UHD") << "Looking for device with hint: " << hint_with_prefs.to_string(); + UHD_LOGGER_DEBUG("UHD") << "Looking for device with hint: " + << hint_with_prefs.to_string(); - for(const dev_fcn_reg_t &fcn: get_dev_fcn_regs()){ - try{ - if(filter == ANY or std::get<2>(fcn) == filter){ + for (const dev_fcn_reg_t& fcn : get_dev_fcn_regs()) { + try { + if (filter == ANY or std::get<2>(fcn) == filter) { for (device_addr_t dev_addr : std::get<0>(fcn)(hint_with_prefs)) { - //append the discovered address and its factory function - dev_addr_makers.push_back(dev_addr_make_t(dev_addr, std::get<1>(fcn))); + // append the discovered address and its factory function + dev_addr_makers.push_back( + dev_addr_make_t(dev_addr, std::get<1>(fcn))); } } - } - catch(const std::exception &e){ - UHD_LOGGER_ERROR("UHD") << "Device discovery error: " << e.what() ; + } catch (const std::exception& e) { + UHD_LOGGER_ERROR("UHD") << "Device discovery error: " << e.what(); } } - //check that we found any devices - if (dev_addr_makers.size() == 0){ - throw uhd::key_error(str( - boost::format("No devices found for ----->\n%s") % hint.to_pp_string() - )); + // check that we found any devices + if (dev_addr_makers.size() == 0) { + throw uhd::key_error( + str(boost::format("No devices found for ----->\n%s") % hint.to_pp_string())); } - //check that the which index is valid - if (dev_addr_makers.size() <= which){ - throw uhd::index_error(str( - boost::format("No device at index %d for ----->\n%s") % which % hint.to_pp_string() - )); + // check that the which index is valid + if (dev_addr_makers.size() <= which) { + throw uhd::index_error(str(boost::format("No device at index %d for ----->\n%s") + % which % hint.to_pp_string())); } - //create a unique hash for the device address - device_addr_t dev_addr; make_t maker; + // create a unique hash for the device address + device_addr_t dev_addr; + make_t maker; std::tie(dev_addr, maker) = dev_addr_makers.at(which); - size_t dev_hash = hash_device_addr(dev_addr); - UHD_LOGGER_TRACE("UHD") << boost::format("Device hash: %u") % dev_hash ; - - //copy keys that were in hint but not in dev_addr - //this way, we can pass additional transport arguments - for(const std::string &key: hint.keys()){ - if (not dev_addr.has_key(key)) dev_addr[key] = hint[key]; + size_t dev_hash = hash_device_addr(dev_addr); + UHD_LOGGER_TRACE("UHD") << boost::format("Device hash: %u") % dev_hash; + + // copy keys that were in hint but not in dev_addr + // this way, we can pass additional transport arguments + for (const std::string& key : hint.keys()) { + if (not dev_addr.has_key(key)) + dev_addr[key] = hint[key]; } - //map device address hash to created devices - static uhd::dict<size_t, std::weak_ptr<device> > hash_to_device; + // map device address hash to created devices + static uhd::dict<size_t, std::weak_ptr<device>> hash_to_device; - //try to find an existing device - if (hash_to_device.has_key(dev_hash) and not hash_to_device[dev_hash].expired()){ + // try to find an existing device + if (hash_to_device.has_key(dev_hash) and not hash_to_device[dev_hash].expired()) { return hash_to_device[dev_hash].lock(); - } - else { + } else { // Add keys from the config files (note: the user-defined keys will // always be applied, see also get_usrp_args() // Then, create and register a new device. - device::sptr dev = maker(prefs::get_usrp_args(dev_addr)); + device::sptr dev = maker(prefs::get_usrp_args(dev_addr)); hash_to_device[dev_hash] = dev; return dev; } } -uhd::property_tree::sptr -device::get_tree(void) const +uhd::property_tree::sptr device::get_tree(void) const { return _tree; } -device::device_filter_t device::get_device_type() const { +device::device_filter_t device::get_device_type() const +{ return _type; } diff --git a/host/lib/error_c.cpp b/host/lib/error_c.cpp index 0012ffb2c..0914ca4e7 100644 --- a/host/lib/error_c.cpp +++ b/host/lib/error_c.cpp @@ -8,28 +8,28 @@ #include <uhd/error.h> #include <uhd/exception.hpp> #include <uhd/utils/static.hpp> - #include <boost/thread/mutex.hpp> - #include <cstring> -#define MAP_TO_ERROR(exception_type, error_type) \ - if (dynamic_cast<const uhd::exception_type*>(e)) return error_type; +#define MAP_TO_ERROR(exception_type, error_type) \ + if (dynamic_cast<const uhd::exception_type*>(e)) \ + return error_type; -uhd_error error_from_uhd_exception(const uhd::exception* e){ - MAP_TO_ERROR(index_error, UHD_ERROR_INDEX) - MAP_TO_ERROR(key_error, UHD_ERROR_KEY) +uhd_error error_from_uhd_exception(const uhd::exception* e) +{ + MAP_TO_ERROR(index_error, UHD_ERROR_INDEX) + MAP_TO_ERROR(key_error, UHD_ERROR_KEY) MAP_TO_ERROR(not_implemented_error, UHD_ERROR_NOT_IMPLEMENTED) - MAP_TO_ERROR(usb_error, UHD_ERROR_USB) - MAP_TO_ERROR(io_error, UHD_ERROR_IO) - MAP_TO_ERROR(os_error, UHD_ERROR_OS) - MAP_TO_ERROR(assertion_error, UHD_ERROR_ASSERTION) - MAP_TO_ERROR(lookup_error, UHD_ERROR_LOOKUP) - MAP_TO_ERROR(type_error, UHD_ERROR_TYPE) - MAP_TO_ERROR(value_error, UHD_ERROR_VALUE) - MAP_TO_ERROR(runtime_error, UHD_ERROR_RUNTIME) - MAP_TO_ERROR(environment_error, UHD_ERROR_ENVIRONMENT) - MAP_TO_ERROR(system_error, UHD_ERROR_SYSTEM) + MAP_TO_ERROR(usb_error, UHD_ERROR_USB) + MAP_TO_ERROR(io_error, UHD_ERROR_IO) + MAP_TO_ERROR(os_error, UHD_ERROR_OS) + MAP_TO_ERROR(assertion_error, UHD_ERROR_ASSERTION) + MAP_TO_ERROR(lookup_error, UHD_ERROR_LOOKUP) + MAP_TO_ERROR(type_error, UHD_ERROR_TYPE) + MAP_TO_ERROR(value_error, UHD_ERROR_VALUE) + MAP_TO_ERROR(runtime_error, UHD_ERROR_RUNTIME) + MAP_TO_ERROR(environment_error, UHD_ERROR_ENVIRONMENT) + MAP_TO_ERROR(system_error, UHD_ERROR_SYSTEM) return UHD_ERROR_EXCEPT; } @@ -42,28 +42,25 @@ UHD_SINGLETON_FCN(std::string, _c_global_error_string) static boost::mutex _error_c_mutex; -std::string get_c_global_error_string(){ +std::string get_c_global_error_string() +{ boost::mutex::scoped_lock lock(_error_c_mutex); return _c_global_error_string(); } -void set_c_global_error_string( - const std::string &msg -){ +void set_c_global_error_string(const std::string& msg) +{ boost::mutex::scoped_lock lock(_error_c_mutex); _c_global_error_string() = msg; } -uhd_error uhd_get_last_error( - char* error_out, - size_t strbuffer_len -){ - try{ +uhd_error uhd_get_last_error(char* error_out, size_t strbuffer_len) +{ + try { auto error_str = get_c_global_error_string(); memset(error_out, '\0', strbuffer_len); strncpy(error_out, error_str.c_str(), strbuffer_len); - } - catch(...){ + } catch (...) { return UHD_ERROR_UNKNOWN; } return UHD_ERROR_NONE; diff --git a/host/lib/experts/expert_container.cpp b/host/lib/experts/expert_container.cpp index 895ab1d41..6f7dc2c78 100644 --- a/host/lib/experts/expert_container.cpp +++ b/host/lib/experts/expert_container.cpp @@ -19,51 +19,53 @@ #include <memory> #ifdef UHD_EXPERT_LOGGING -#define EX_LOG(depth, str) _log(depth, str) +# define EX_LOG(depth, str) _log(depth, str) #else -#define EX_LOG(depth, str) +# define EX_LOG(depth, str) #endif namespace uhd { namespace experts { -typedef boost::adjacency_list< - boost::vecS, //Container used to represent the edge-list for each of the vertices. - boost::vecS, //container used to represent the vertex-list of the graph. - boost::directedS, //Directionality of graph - dag_vertex_t*, //Storage for each vertex - boost::no_property, //Storage for each edge - boost::no_property, //Storage for graph object - boost::listS //Container used to represent the edge-list for the graph. -> expert_graph_t; +typedef boost::adjacency_list<boost::vecS, // Container used to represent the edge-list + // for each of the vertices. + boost::vecS, // container used to represent the vertex-list of the graph. + boost::directedS, // Directionality of graph + dag_vertex_t*, // Storage for each vertex + boost::no_property, // Storage for each edge + boost::no_property, // Storage for graph object + boost::listS // Container used to represent the edge-list for the graph. + > + expert_graph_t; typedef std::map<std::string, expert_graph_t::vertex_descriptor> vertex_map_t; -typedef std::list<expert_graph_t::vertex_descriptor> node_queue_t; +typedef std::list<expert_graph_t::vertex_descriptor> node_queue_t; -typedef boost::graph_traits<expert_graph_t>::edge_iterator edge_iter; -typedef boost::graph_traits<expert_graph_t>::vertex_iterator vertex_iter; +typedef boost::graph_traits<expert_graph_t>::edge_iterator edge_iter; +typedef boost::graph_traits<expert_graph_t>::vertex_iterator vertex_iter; class expert_container_impl : public expert_container { -private: //Visitor class for cycle detection algorithm +private: // Visitor class for cycle detection algorithm struct cycle_det_visitor : public boost::dfs_visitor<> { - cycle_det_visitor(std::vector<std::string>& back_edges): - _back_edges(back_edges) {} + cycle_det_visitor(std::vector<std::string>& back_edges) : _back_edges(back_edges) + { + } template <class Edge, class Graph> - void back_edge(Edge u, const Graph& g) { - _back_edges.push_back( - g[boost::source(u,g)]->get_name() + "->" + g[boost::target(u,g)]->get_name()); + void back_edge(Edge u, const Graph& g) + { + _back_edges.push_back(g[boost::source(u, g)]->get_name() + "->" + + g[boost::target(u, g)]->get_name()); } - private: std::vector<std::string>& _back_edges; + + private: + std::vector<std::string>& _back_edges; }; public: - expert_container_impl(const std::string& name): - _name(name) - { - } + expert_container_impl(const std::string& name) : _name(name) {} ~expert_container_impl() { @@ -79,7 +81,7 @@ public: { boost::lock_guard<boost::recursive_mutex> resolve_lock(_resolve_mutex); boost::lock_guard<boost::mutex> lock(_mutex); - EX_LOG(0, str(boost::format("resolve_all(%s)") % (force?"force":""))); + EX_LOG(0, str(boost::format("resolve_all(%s)") % (force ? "force" : ""))); // Do a full resolve of the graph _resolve_helper("", "", force); } @@ -109,7 +111,7 @@ public: try { expert_graph_t::vertex_descriptor vertex = _lookup_vertex(name); return _get_vertex(vertex); - } catch(std::exception&) { + } catch (std::exception&) { throw uhd::lookup_error("failed to find node " + name + " in expert graph"); } } @@ -134,27 +136,26 @@ public: // Iterate through the vertices and print them out for (std::pair<vertex_iter, vertex_iter> vi = boost::vertices(_expert_dag); vi.first != vi.second; - ++vi.first - ) { + ++vi.first) { const dag_vertex_t& vertex = _get_vertex(*vi.first); if (vertex.get_class() != CLASS_WORKER) { - dot_str += str(boost::format(" %d [label=\"%s\",shape=%s,xlabel=\"%s\"];\n") % - uint32_t(*vi.first) % vertex.get_name() % - DATA_SHAPE % vertex.get_dtype()); + dot_str += + str(boost::format(" %d [label=\"%s\",shape=%s,xlabel=\"%s\"];\n") + % uint32_t(*vi.first) % vertex.get_name() % DATA_SHAPE + % vertex.get_dtype()); } else { - dot_str += str(boost::format(" %d [label=\"%s\",shape=%s];\n") % - uint32_t(*vi.first) % vertex.get_name() % WORKER_SHAPE); + dot_str += str(boost::format(" %d [label=\"%s\",shape=%s];\n") + % uint32_t(*vi.first) % vertex.get_name() % WORKER_SHAPE); } } // Iterate through the edges and print them out for (std::pair<edge_iter, edge_iter> ei = boost::edges(_expert_dag); ei.first != ei.second; - ++ei.first - ) { - dot_str += str(boost::format(" %d -> %d;\n") % - uint32_t(boost::source(*(ei.first), _expert_dag)) % - uint32_t(boost::target(*(ei.first), _expert_dag))); + ++ei.first) { + dot_str += str(boost::format(" %d -> %d;\n") + % uint32_t(boost::source(*(ei.first), _expert_dag)) + % uint32_t(boost::target(*(ei.first), _expert_dag))); } dot_str += "}\n"; return dot_str; @@ -165,7 +166,7 @@ public: #ifdef UHD_EXPERT_LOGGING EX_LOG(0, "debug_audit()"); - //Test 1: Check for cycles in graph + // Test 1: Check for cycles in graph std::vector<std::string> back_edges; cycle_det_visitor cdet_vis(back_edges); boost::depth_first_search(_expert_dag, boost::visitor(cdet_vis)); @@ -173,20 +174,19 @@ public: EX_LOG(1, "cycle check ... PASSED"); } else { EX_LOG(1, "cycle check ... ERROR!!!"); - for(const std::string& e: back_edges) { + for (const std::string& e : back_edges) { EX_LOG(2, "back edge: " + e); } } back_edges.clear(); - //Test 2: Check data node input and output edges + // Test 2: Check data node input and output edges std::vector<std::string> data_node_issues; - for(const vertex_map_t::value_type& v: _datanode_map) { + for (const vertex_map_t::value_type& v : _datanode_map) { size_t in_count = 0, out_count = 0; for (std::pair<edge_iter, edge_iter> ei = boost::edges(_expert_dag); ei.first != ei.second; - ++ei.first - ) { + ++ei.first) { if (boost::target(*(ei.first), _expert_dag) == v.second) in_count++; if (boost::source(*(ei.first), _expert_dag) == v.second) @@ -197,26 +197,34 @@ public: data_node_issues.push_back(v.first + ": multiple writers (workers)"); } else if (in_count > 0) { if (_expert_dag[v.second]->get_class() == CLASS_PROPERTY) { - data_node_issues.push_back(v.first + ": multiple writers (worker and property tree)"); + data_node_issues.push_back( + v.first + ": multiple writers (worker and property tree)"); } } else { if (_expert_dag[v.second]->get_class() != CLASS_PROPERTY) { - data_node_issues.push_back(v.first + ": unreachable (will always hold initial value)"); - } else if (_expert_dag[v.second]->get_class() == CLASS_PROPERTY and not _expert_dag[v.second]->has_write_callback()) { + data_node_issues.push_back( + v.first + ": unreachable (will always hold initial value)"); + } else if (_expert_dag[v.second]->get_class() == CLASS_PROPERTY + and not _expert_dag[v.second]->has_write_callback()) { if (out_count > 0) { - data_node_issues.push_back(v.first + ": needs explicit resolve after write"); + data_node_issues.push_back( + v.first + ": needs explicit resolve after write"); } else { - data_node_issues.push_back(v.first + ": unused (no readers or writers)"); + data_node_issues.push_back( + v.first + ": unused (no readers or writers)"); prop_unused = true; } } } if (out_count < 1) { if (_expert_dag[v.second]->get_class() != CLASS_PROPERTY) { - data_node_issues.push_back(v.first + ": unused (is not read by any worker)"); - } else if (_expert_dag[v.second]->get_class() == CLASS_PROPERTY and not _expert_dag[v.second]->has_read_callback()) { + data_node_issues.push_back( + v.first + ": unused (is not read by any worker)"); + } else if (_expert_dag[v.second]->get_class() == CLASS_PROPERTY + and not _expert_dag[v.second]->has_read_callback()) { if (not prop_unused) { - data_node_issues.push_back(v.first + ": needs explicit resolve to read"); + data_node_issues.push_back( + v.first + ": needs explicit resolve to read"); } } } @@ -226,20 +234,19 @@ public: EX_LOG(1, "data node check ... PASSED"); } else { EX_LOG(1, "data node check ... WARNING!"); - for(const std::string& i: data_node_issues) { + for (const std::string& i : data_node_issues) { EX_LOG(2, i); } } data_node_issues.clear(); - //Test 3: Check worker node input and output edges + // Test 3: Check worker node input and output edges std::vector<std::string> worker_issues; - for(const vertex_map_t::value_type& v: _worker_map) { + for (const vertex_map_t::value_type& v : _worker_map) { size_t in_count = 0, out_count = 0; for (std::pair<edge_iter, edge_iter> ei = boost::edges(_expert_dag); ei.first != ei.second; - ++ei.first - ) { + ++ei.first) { if (boost::target(*(ei.first), _expert_dag) == v.second) in_count++; if (boost::source(*(ei.first), _expert_dag) == v.second) @@ -256,7 +263,7 @@ public: EX_LOG(1, "worker check ... PASSED"); } else { EX_LOG(1, "worker check ... WARNING!"); - for(const std::string& i: worker_issues) { + for (const std::string& i : worker_issues) { EX_LOG(2, i); } } @@ -264,7 +271,8 @@ public: #endif } - inline boost::recursive_mutex& resolve_mutex() { + inline boost::recursive_mutex& resolve_mutex() + { return _resolve_mutex; } @@ -273,40 +281,50 @@ protected: { boost::lock_guard<boost::mutex> lock(_mutex); - //Sanity check node pointer + // Sanity check node pointer if (data_node == NULL) { - throw uhd::runtime_error("NULL data node passed into expert container for registration."); + throw uhd::runtime_error( + "NULL data node passed into expert container for registration."); } - //Sanity check the data node and ensure that it is not already in this graph + // Sanity check the data node and ensure that it is not already in this graph EX_LOG(0, str(boost::format("add_data_node(%s)") % data_node->get_name())); if (data_node->get_class() == CLASS_WORKER) { - throw uhd::runtime_error("Supplied node " + data_node->get_name() + " is not a data/property node."); + throw uhd::runtime_error("Supplied node " + data_node->get_name() + + " is not a data/property node."); // Throw leaves data_node undeleted } if (_datanode_map.find(data_node->get_name()) != _datanode_map.end()) { - throw uhd::runtime_error("Data node with name " + data_node->get_name() + " already exists"); + throw uhd::runtime_error( + "Data node with name " + data_node->get_name() + " already exists"); // Throw leaves data node undeleted } try { - //Add a vertex in this graph for the data node - expert_graph_t::vertex_descriptor gr_node = boost::add_vertex(data_node, _expert_dag); + // Add a vertex in this graph for the data node + expert_graph_t::vertex_descriptor gr_node = + boost::add_vertex(data_node, _expert_dag); EX_LOG(1, str(boost::format("added vertex %s") % data_node->get_name())); - _datanode_map.insert(vertex_map_t::value_type(data_node->get_name(), gr_node)); + _datanode_map.insert( + vertex_map_t::value_type(data_node->get_name(), gr_node)); - //Add resolve callbacks - if (resolve_mode == AUTO_RESOLVE_ON_WRITE or resolve_mode == AUTO_RESOLVE_ON_READ_WRITE) { + // Add resolve callbacks + if (resolve_mode == AUTO_RESOLVE_ON_WRITE + or resolve_mode == AUTO_RESOLVE_ON_READ_WRITE) { EX_LOG(2, str(boost::format("added write callback"))); - data_node->set_write_callback(std::bind(&expert_container_impl::resolve_from, this, std::placeholders::_1)); + data_node->set_write_callback(std::bind( + &expert_container_impl::resolve_from, this, std::placeholders::_1)); } - if (resolve_mode == AUTO_RESOLVE_ON_READ or resolve_mode == AUTO_RESOLVE_ON_READ_WRITE) { + if (resolve_mode == AUTO_RESOLVE_ON_READ + or resolve_mode == AUTO_RESOLVE_ON_READ_WRITE) { EX_LOG(2, str(boost::format("added read callback"))); - data_node->set_read_callback(std::bind(&expert_container_impl::resolve_to, this, std::placeholders::_1)); + data_node->set_read_callback(std::bind( + &expert_container_impl::resolve_to, this, std::placeholders::_1)); } } catch (...) { clear(); - throw uhd::assertion_error("Unknown unrecoverable error adding data node. Cleared expert container."); + throw uhd::assertion_error("Unknown unrecoverable error adding data node. " + "Cleared expert container."); } } @@ -314,54 +332,69 @@ protected: { boost::lock_guard<boost::mutex> lock(_mutex); - //Sanity check node pointer + // Sanity check node pointer if (worker == NULL) { - throw uhd::runtime_error("NULL worker passed into expert container for registration."); + throw uhd::runtime_error( + "NULL worker passed into expert container for registration."); } - //Sanity check the data node and ensure that it is not already in this graph + // Sanity check the data node and ensure that it is not already in this graph EX_LOG(0, str(boost::format("add_worker(%s)") % worker->get_name())); if (worker->get_class() != CLASS_WORKER) { - throw uhd::runtime_error("Supplied node " + worker->get_name() + " is not a worker node."); + throw uhd::runtime_error( + "Supplied node " + worker->get_name() + " is not a worker node."); } if (_worker_map.find(worker->get_name()) != _worker_map.end()) { - throw uhd::runtime_error("Resolver with name " + worker->get_name() + " already exists."); + throw uhd::runtime_error( + "Resolver with name " + worker->get_name() + " already exists."); } try { - //Add a vertex in this graph for the worker node - expert_graph_t::vertex_descriptor gr_node = boost::add_vertex(worker, _expert_dag); + // Add a vertex in this graph for the worker node + expert_graph_t::vertex_descriptor gr_node = + boost::add_vertex(worker, _expert_dag); EX_LOG(1, str(boost::format("added vertex %s") % worker->get_name())); _worker_map.insert(vertex_map_t::value_type(worker->get_name(), gr_node)); - //For each input, add an edge from the input to this node - for(const std::string& node_name: worker->get_inputs()) { + // For each input, add an edge from the input to this node + for (const std::string& node_name : worker->get_inputs()) { vertex_map_t::const_iterator node = _datanode_map.find(node_name); if (node != _datanode_map.end()) { boost::add_edge((*node).second, gr_node, _expert_dag); - EX_LOG(1, str(boost::format("added edge %s->%s") % _expert_dag[(*node).second]->get_name() % _expert_dag[gr_node]->get_name())); + EX_LOG(1, + str(boost::format("added edge %s->%s") + % _expert_dag[(*node).second]->get_name() + % _expert_dag[gr_node]->get_name())); } else { - throw uhd::runtime_error("Data node with name " + node_name + " was not found"); + throw uhd::runtime_error( + "Data node with name " + node_name + " was not found"); } } - //For each output, add an edge from this node to the output - for(const std::string& node_name: worker->get_outputs()) { + // For each output, add an edge from this node to the output + for (const std::string& node_name : worker->get_outputs()) { vertex_map_t::const_iterator node = _datanode_map.find(node_name); if (node != _datanode_map.end()) { boost::add_edge(gr_node, (*node).second, _expert_dag); - EX_LOG(1, str(boost::format("added edge %s->%s") % _expert_dag[gr_node]->get_name() % _expert_dag[(*node).second]->get_name())); + EX_LOG(1, + str(boost::format("added edge %s->%s") + % _expert_dag[gr_node]->get_name() + % _expert_dag[(*node).second]->get_name())); } else { - throw uhd::runtime_error("Data node with name " + node_name + " was not found"); + throw uhd::runtime_error( + "Data node with name " + node_name + " was not found"); } } } catch (uhd::runtime_error& ex) { clear(); - //Promote runtime_error to assertion_error - throw uhd::assertion_error(std::string(ex.what()) + " (Cleared expert container because error is unrecoverable)."); + // Promote runtime_error to assertion_error + throw uhd::assertion_error( + std::string(ex.what()) + + " (Cleared expert container because error is unrecoverable)."); } catch (...) { clear(); - throw uhd::assertion_error("Unknown unrecoverable error adding worker. Cleared expert container."); + throw uhd::assertion_error( + "Unknown unrecoverable error adding worker. Cleared expert container."); } } @@ -374,20 +407,19 @@ protected: typedef boost::graph_traits<expert_graph_t>::vertex_iterator vertex_iter; for (std::pair<vertex_iter, vertex_iter> vi = boost::vertices(_expert_dag); vi.first != vi.second; - ++vi.first - ) { + ++vi.first) { try { delete _expert_dag[*vi.first]; _expert_dag[*vi.first] = NULL; } catch (...) { - //If a dag_vertex is a worker, it has a virtual dtor which - //can possibly throw an exception. We will not let that - //terminate clear() and leave things in a bad state. + // If a dag_vertex is a worker, it has a virtual dtor which + // can possibly throw an exception. We will not let that + // terminate clear() and leave things in a bad state. } } - //The following calls will not throw because they all contain - //intrinsic types. + // The following calls will not throw because they all contain + // intrinsic types. // Release all vertices and edges in the DAG _expert_dag.clear(); @@ -400,8 +432,8 @@ protected: private: void _resolve_helper(std::string start, std::string stop, bool force) { - //Sort the graph topologically. This ensures that for all dependencies, the dependant - //is always after all of its dependencies. + // Sort the graph topologically. This ensures that for all dependencies, the + // dependant is always after all of its dependencies. node_queue_t sorted_nodes; try { boost::topological_sort(_expert_dag, std::front_inserter(sorted_nodes)); @@ -411,33 +443,38 @@ private: boost::depth_first_search(_expert_dag, boost::visitor(cdet_vis)); if (not back_edges.empty()) { std::string edges; - for(const std::string& e: back_edges) { + for (const std::string& e : back_edges) { edges += "* " + e + ""; } - throw uhd::runtime_error("Cannot resolve expert because it has at least one cycle!\n" - "The following back-edges were found:" + edges); + throw uhd::runtime_error( + "Cannot resolve expert because it has at least one cycle!\n" + "The following back-edges were found:" + + edges); } } - if (sorted_nodes.empty()) return; + if (sorted_nodes.empty()) + return; - //Determine the start and stop node. If one is not explicitly specified then - //resolve everything + // Determine the start and stop node. If one is not explicitly specified then + // resolve everything expert_graph_t::vertex_descriptor start_vertex = sorted_nodes.front(); - expert_graph_t::vertex_descriptor stop_vertex = sorted_nodes.back(); - if (not start.empty()) start_vertex = _lookup_vertex(start); - if (not stop.empty()) stop_vertex = _lookup_vertex(stop); + expert_graph_t::vertex_descriptor stop_vertex = sorted_nodes.back(); + if (not start.empty()) + start_vertex = _lookup_vertex(start); + if (not stop.empty()) + stop_vertex = _lookup_vertex(stop); - //First Pass: Resolve all nodes if they are dirty, in a topological order + // First Pass: Resolve all nodes if they are dirty, in a topological order std::list<dag_vertex_t*> resolved_workers; bool start_node_encountered = false; for (node_queue_t::iterator node_iter = sorted_nodes.begin(); node_iter != sorted_nodes.end(); - ++node_iter - ) { - //Determine if we are at or beyond the starting node - if (*node_iter == start_vertex) start_node_encountered = true; + ++node_iter) { + // Determine if we are at or beyond the starting node + if (*node_iter == start_vertex) + start_node_encountered = true; - //Only resolve if the starting node has passed + // Only resolve if the starting node has passed if (start_node_encountered) { dag_vertex_t& node = _get_vertex(*node_iter); std::string node_val; @@ -446,25 +483,28 @@ private: if (node.get_class() == CLASS_WORKER) { resolved_workers.push_back(&node); } - EX_LOG(1, str(boost::format("resolved node %s (%s) [%s]") % - node.get_name() % (node.is_dirty()?"dirty":"clean") % node.to_string())); + EX_LOG(1, + str(boost::format("resolved node %s (%s) [%s]") % node.get_name() + % (node.is_dirty() ? "dirty" : "clean") % node.to_string())); } else { - EX_LOG(1, str(boost::format("skipped node %s (%s) [%s]") % - node.get_name() % (node.is_dirty()?"dirty":"clean") % node.to_string())); + EX_LOG(1, + str(boost::format("skipped node %s (%s) [%s]") % node.get_name() + % (node.is_dirty() ? "dirty" : "clean") % node.to_string())); } } - //Determine if we are beyond the stop node - if (*node_iter == stop_vertex) break; + // Determine if we are beyond the stop node + if (*node_iter == stop_vertex) + break; } - //Second Pass: Mark all the workers clean. The policy is that a worker will mark all of - //its dependencies clean so after this step all data nodes that are not consumed by a worker - //will remain dirty (as they should because no one has consumed their value) + // Second Pass: Mark all the workers clean. The policy is that a worker will mark + // all of its dependencies clean so after this step all data nodes that are not + // consumed by a worker will remain dirty (as they should because no one has + // consumed their value) for (std::list<dag_vertex_t*>::iterator worker = resolved_workers.begin(); worker != resolved_workers.end(); - ++worker - ) { + ++worker) { (*worker)->mark_clean(); } } @@ -472,12 +512,12 @@ private: expert_graph_t::vertex_descriptor _lookup_vertex(const std::string& name) const { expert_graph_t::vertex_descriptor vertex; - //Look for node in the data-node map + // Look for node in the data-node map vertex_map_t::const_iterator vertex_iter = _datanode_map.find(name); if (vertex_iter != _datanode_map.end()) { vertex = (*vertex_iter).second; } else { - //If not found, look in the worker-node map + // If not found, look in the worker-node map vertex_iter = _worker_map.find(name); if (vertex_iter != _worker_map.end()) { vertex = (*vertex_iter).second; @@ -488,8 +528,9 @@ private: return vertex; } - dag_vertex_t& _get_vertex(expert_graph_t::vertex_descriptor desc) const { - //Requirement: Node must exist in expert graph + dag_vertex_t& _get_vertex(expert_graph_t::vertex_descriptor desc) const + { + // Requirement: Node must exist in expert graph dag_vertex_t* vertex_ptr = _expert_dag[desc]; if (vertex_ptr) { return *vertex_ptr; @@ -501,17 +542,19 @@ private: void _log(size_t depth, const std::string& str) const { std::string indents; - for (size_t i = 0; i < depth; i++) indents += "- "; - UHD_LOG_DEBUG("EXPERT","[expert::" + _name + "] " << indents << str) + for (size_t i = 0; i < depth; i++) + indents += "- "; + UHD_LOG_DEBUG("EXPERT", "[expert::" + _name + "] " << indents << str) } private: - const std::string _name; - expert_graph_t _expert_dag; //The primary graph data structure as an adjacency list - vertex_map_t _worker_map; //A map from vertex name to vertex descriptor for workers - vertex_map_t _datanode_map; //A map from vertex name to vertex descriptor for data nodes - boost::mutex _mutex; - boost::recursive_mutex _resolve_mutex; + const std::string _name; + expert_graph_t _expert_dag; // The primary graph data structure as an adjacency list + vertex_map_t _worker_map; // A map from vertex name to vertex descriptor for workers + vertex_map_t + _datanode_map; // A map from vertex name to vertex descriptor for data nodes + boost::mutex _mutex; + boost::recursive_mutex _resolve_mutex; }; expert_container::sptr expert_container::make(const std::string& name) @@ -519,4 +562,4 @@ expert_container::sptr expert_container::make(const std::string& name) return std::make_shared<expert_container_impl>(name); } -}} +}} // namespace uhd::experts diff --git a/host/lib/experts/expert_factory.cpp b/host/lib/experts/expert_factory.cpp index abc718d28..2d86f90a1 100644 --- a/host/lib/experts/expert_factory.cpp +++ b/host/lib/experts/expert_factory.cpp @@ -14,4 +14,4 @@ expert_container::sptr expert_factory::create_container(const std::string& name) return expert_container::make(name); } -}} +}} // namespace uhd::experts diff --git a/host/lib/image_loader.cpp b/host/lib/image_loader.cpp index 7e91dfaec..38fed1c87 100644 --- a/host/lib/image_loader.cpp +++ b/host/lib/image_loader.cpp @@ -5,18 +5,15 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <iostream> -#include <map> -#include <utility> - -#include <boost/filesystem.hpp> -#include <boost/format.hpp> - #include <uhd/exception.hpp> #include <uhd/image_loader.hpp> #include <uhd/utils/log.hpp> - #include <uhd/utils/static.hpp> +#include <boost/filesystem.hpp> +#include <boost/format.hpp> +#include <iostream> +#include <map> +#include <utility> namespace fs = boost::filesystem; @@ -28,15 +25,17 @@ typedef std::pair<std::string, uhd::image_loader::loader_fcn_t> loader_fcn_pair_ typedef std::pair<std::string, std::string> string_pair_t; UHD_SINGLETON_FCN(loader_fcn_map_t, get_image_loaders); -UHD_SINGLETON_FCN(string_map_t, get_recovery_strings); +UHD_SINGLETON_FCN(string_map_t, get_recovery_strings); /* * Registration */ -void uhd::image_loader::register_image_loader(const std::string &device_type, - const loader_fcn_t &loader_fcn, - const std::string &recovery_instructions){ - // UHD_LOGGER_TRACE("UHD") << "Registering image loader and recovery instructions for " +void uhd::image_loader::register_image_loader(const std::string& device_type, + const loader_fcn_t& loader_fcn, + const std::string& recovery_instructions) +{ + // UHD_LOGGER_TRACE("UHD") << "Registering image loader and recovery instructions for + // " // << device_type; get_image_loaders().insert(loader_fcn_pair_t(device_type, loader_fcn)); @@ -46,20 +45,23 @@ void uhd::image_loader::register_image_loader(const std::string &device_type, /* * Actual loading */ -bool uhd::image_loader::load(const uhd::image_loader::image_loader_args_t &image_loader_args){ - +bool uhd::image_loader::load( + const uhd::image_loader::image_loader_args_t& image_loader_args) +{ // If "type=foo" given in args, see if we have an image loader for that - if(image_loader_args.args.has_key("type")){ + if (image_loader_args.args.has_key("type")) { std::string type = image_loader_args.args.get("type"); - if(get_image_loaders().find(type) == get_image_loaders().end()){ - throw uhd::runtime_error(str(boost::format("There is no image loader registered for given type \"%s\".") - % type)); - } - else return get_image_loaders().at(type)(image_loader_args); - } - else{ - for(const loader_fcn_pair_t &loader_fcn_pair: get_image_loaders()){ - if(loader_fcn_pair.second(image_loader_args)) return true; + if (get_image_loaders().find(type) == get_image_loaders().end()) { + throw uhd::runtime_error( + str(boost::format( + "There is no image loader registered for given type \"%s\".") + % type)); + } else + return get_image_loaders().at(type)(image_loader_args); + } else { + for (const loader_fcn_pair_t& loader_fcn_pair : get_image_loaders()) { + if (loader_fcn_pair.second(image_loader_args)) + return true; } return false; } @@ -68,9 +70,11 @@ bool uhd::image_loader::load(const uhd::image_loader::image_loader_args_t &image /* * Get recovery instructions for particular device */ -std::string uhd::image_loader::get_recovery_instructions(const std::string &device_type){ - if(get_recovery_strings().count(device_type) == 0){ - return "A firmware or FPGA loading process was interrupted by the user. This can leave your device in a non-working state."; - } - else return get_recovery_strings().at(device_type); +std::string uhd::image_loader::get_recovery_instructions(const std::string& device_type) +{ + if (get_recovery_strings().count(device_type) == 0) { + return "A firmware or FPGA loading process was interrupted by the user. This can " + "leave your device in a non-working state."; + } else + return get_recovery_strings().at(device_type); } diff --git a/host/lib/include/uhdlib/experts/expert_container.hpp b/host/lib/include/uhdlib/experts/expert_container.hpp index da52f6f4a..0beae5504 100644 --- a/host/lib/include/uhdlib/experts/expert_container.hpp +++ b/host/lib/include/uhdlib/experts/expert_container.hpp @@ -8,185 +8,189 @@ #ifndef INCLUDED_UHD_EXPERTS_EXPERT_CONTAINER_HPP #define INCLUDED_UHD_EXPERTS_EXPERT_CONTAINER_HPP -#include <uhdlib/experts/expert_nodes.hpp> #include <uhd/config.hpp> #include <uhd/utils/noncopyable.hpp> -#include <memory> +#include <uhdlib/experts/expert_nodes.hpp> #include <boost/thread/recursive_mutex.hpp> +#include <memory> namespace uhd { namespace experts { - enum auto_resolve_mode_t { - AUTO_RESOLVE_OFF, - AUTO_RESOLVE_ON_READ, - AUTO_RESOLVE_ON_WRITE, - AUTO_RESOLVE_ON_READ_WRITE - }; - - class UHD_API expert_container : private uhd::noncopyable, public node_retriever_t { - public: //Methods - typedef std::shared_ptr<expert_container> sptr; - - virtual ~expert_container() {}; - - /*! - * Return the name of this container - */ - virtual const std::string& get_name() const = 0; - - /*! - * Resolves all the nodes in this expert graph. - * - * Dependency analysis is performed on the graph and nodes - * are resolved in a topologically sorted order to ensure - * that no nodes receive stale data. - * Nodes and their dependencies are resolved only if they are - * dirty i.e. their contained values have changed since the - * last resolve. - * This call requires an acyclic expert graph. - * - * \param force If true then ignore dirty state and resolve all nodes - * \throws uhd::runtime_error if graph cannot be resolved - */ - virtual void resolve_all(bool force = false) = 0; - - /*! - * Resolves all the nodes that depend on the specified node. - * - * Dependency analysis is performed on the graph and nodes - * are resolved in a topologically sorted order to ensure - * that no nodes receive stale data. - * Nodes and their dependencies are resolved only if they are - * dirty i.e. their contained values have changed since the - * last resolve. - * This call requires an acyclic expert graph. - * - * \param node_name Name of the node to start resolving from - * \throws uhd::lookup_error if node_name not in container - * \throws uhd::runtime_error if graph cannot be resolved - * - */ - virtual void resolve_from(const std::string& node_name) = 0; - - /*! - * Resolves all the specified node and all of its dependencies. - * - * Dependency analysis is performed on the graph and nodes - * are resolved in a topologically sorted order to ensure - * that no nodes receive stale data. - * Nodes and their dependencies are resolved only if they are - * dirty i.e. their contained values have changed since the - * last resolve. - * This call requires an acyclic expert graph. - * - * \param node_name Name of the node to resolve - * \throws uhd::lookup_error if node_name not in container - * \throws uhd::runtime_error if graph cannot be resolved - * - */ - virtual void resolve_to(const std::string& node_name) = 0; - - /*! - * Return a node retriever object for this container - */ - virtual const node_retriever_t& node_retriever() const = 0; - - /*! - * Returns a DOT (graph description language) representation - * of the expert graph. The output has labels for the node - * name, node type (data or worker) and the underlying - * data type for each node. - * - */ - virtual std::string to_dot() const = 0; - - /*! - * Runs several sanity checks on the underlying graph to - * flag dependency issues. Outputs of the checks are - * logged to the console so UHD_EXPERTS_VERBOSE_LOGGING - * must be enabled to see the results - * - */ - virtual void debug_audit() const = 0; - - private: - /*! - * Lookup a node with the specified name in the contained graph - * - * If the node is found, a reference to the node is returned. - * If the node is not found, uhd::lookup_error is thrown - * lookup can return a data or a worker node - * \implements uhd::experts::node_retriever_t - * - * \param name Name of the node to find - * - */ - virtual const dag_vertex_t& lookup(const std::string& name) const = 0; - virtual dag_vertex_t& retrieve(const std::string& name) const = 0; - - /*! - * expert_factory is a friend of expert_container and - * handles all operations that change the structure of - * the underlying dependency graph. - * The expert_container instance owns all data and worker - * nodes and is responsible for release storage on destruction. - * However, the expert_factory allocates storage for the - * node and passes them into the expert_container using the - * following "protected" API calls. - * - */ - friend class expert_factory; - - /*! - * Creates an empty instance of expert_container with the - * specified name. - * - * \param name Name of the container - */ - static sptr make(const std::string& name); - - /*! - * Returns a reference to the resolver mutex. - * - * The resolver mutex guarantees that external operations - * to data-nodes are serialized with resolves of this - * container. - * - */ - virtual boost::recursive_mutex& resolve_mutex() = 0; - - /*! - * Add a data node to the expert graph - * - * \param data_node Pointer to a fully constructed data node object - * \resolve_mode Auto resolve options: Choose from "disabled" and resolve on "read", "write" or "both" - * \throws uhd::runtime_error if node already exists or is of a wrong type (recoverable) - * \throws uhd::assertion_error for other failures (unrecoverable. will clear the graph) - * - */ - virtual void add_data_node(dag_vertex_t* data_node, auto_resolve_mode_t resolve_mode = AUTO_RESOLVE_OFF) = 0; - - /*! - * Add a worker node to the expert graph - * - * \param worker Pointer to a fully constructed worker object - * \throws uhd::runtime_error if worker already exists or is of a wrong type (recoverable) - * \throws uhd::assertion_error for other failures (unrecoverable. will clear the graph) - * - */ - virtual void add_worker(worker_node_t* worker) = 0; - - /*! - * Release all storage for this object. This will delete all contained - * data and worker nodes and remove all dependency relationship and - * resolve callbacks. - * - * The object will be restored to its newly constructed state. Will not - * throw. - */ - virtual void clear() = 0; - }; - -}} +enum auto_resolve_mode_t { + AUTO_RESOLVE_OFF, + AUTO_RESOLVE_ON_READ, + AUTO_RESOLVE_ON_WRITE, + AUTO_RESOLVE_ON_READ_WRITE +}; + +class UHD_API expert_container : private uhd::noncopyable, public node_retriever_t +{ +public: // Methods + typedef std::shared_ptr<expert_container> sptr; + + virtual ~expert_container(){}; + + /*! + * Return the name of this container + */ + virtual const std::string& get_name() const = 0; + + /*! + * Resolves all the nodes in this expert graph. + * + * Dependency analysis is performed on the graph and nodes + * are resolved in a topologically sorted order to ensure + * that no nodes receive stale data. + * Nodes and their dependencies are resolved only if they are + * dirty i.e. their contained values have changed since the + * last resolve. + * This call requires an acyclic expert graph. + * + * \param force If true then ignore dirty state and resolve all nodes + * \throws uhd::runtime_error if graph cannot be resolved + */ + virtual void resolve_all(bool force = false) = 0; + + /*! + * Resolves all the nodes that depend on the specified node. + * + * Dependency analysis is performed on the graph and nodes + * are resolved in a topologically sorted order to ensure + * that no nodes receive stale data. + * Nodes and their dependencies are resolved only if they are + * dirty i.e. their contained values have changed since the + * last resolve. + * This call requires an acyclic expert graph. + * + * \param node_name Name of the node to start resolving from + * \throws uhd::lookup_error if node_name not in container + * \throws uhd::runtime_error if graph cannot be resolved + * + */ + virtual void resolve_from(const std::string& node_name) = 0; + + /*! + * Resolves all the specified node and all of its dependencies. + * + * Dependency analysis is performed on the graph and nodes + * are resolved in a topologically sorted order to ensure + * that no nodes receive stale data. + * Nodes and their dependencies are resolved only if they are + * dirty i.e. their contained values have changed since the + * last resolve. + * This call requires an acyclic expert graph. + * + * \param node_name Name of the node to resolve + * \throws uhd::lookup_error if node_name not in container + * \throws uhd::runtime_error if graph cannot be resolved + * + */ + virtual void resolve_to(const std::string& node_name) = 0; + + /*! + * Return a node retriever object for this container + */ + virtual const node_retriever_t& node_retriever() const = 0; + + /*! + * Returns a DOT (graph description language) representation + * of the expert graph. The output has labels for the node + * name, node type (data or worker) and the underlying + * data type for each node. + * + */ + virtual std::string to_dot() const = 0; + + /*! + * Runs several sanity checks on the underlying graph to + * flag dependency issues. Outputs of the checks are + * logged to the console so UHD_EXPERTS_VERBOSE_LOGGING + * must be enabled to see the results + * + */ + virtual void debug_audit() const = 0; + +private: + /*! + * Lookup a node with the specified name in the contained graph + * + * If the node is found, a reference to the node is returned. + * If the node is not found, uhd::lookup_error is thrown + * lookup can return a data or a worker node + * \implements uhd::experts::node_retriever_t + * + * \param name Name of the node to find + * + */ + virtual const dag_vertex_t& lookup(const std::string& name) const = 0; + virtual dag_vertex_t& retrieve(const std::string& name) const = 0; + + /*! + * expert_factory is a friend of expert_container and + * handles all operations that change the structure of + * the underlying dependency graph. + * The expert_container instance owns all data and worker + * nodes and is responsible for release storage on destruction. + * However, the expert_factory allocates storage for the + * node and passes them into the expert_container using the + * following "protected" API calls. + * + */ + friend class expert_factory; + + /*! + * Creates an empty instance of expert_container with the + * specified name. + * + * \param name Name of the container + */ + static sptr make(const std::string& name); + + /*! + * Returns a reference to the resolver mutex. + * + * The resolver mutex guarantees that external operations + * to data-nodes are serialized with resolves of this + * container. + * + */ + virtual boost::recursive_mutex& resolve_mutex() = 0; + + /*! + * Add a data node to the expert graph + * + * \param data_node Pointer to a fully constructed data node object + * \resolve_mode Auto resolve options: Choose from "disabled" and resolve on "read", + * "write" or "both" \throws uhd::runtime_error if node already exists or is of a + * wrong type (recoverable) \throws uhd::assertion_error for other failures + * (unrecoverable. will clear the graph) + * + */ + virtual void add_data_node( + dag_vertex_t* data_node, auto_resolve_mode_t resolve_mode = AUTO_RESOLVE_OFF) = 0; + + /*! + * Add a worker node to the expert graph + * + * \param worker Pointer to a fully constructed worker object + * \throws uhd::runtime_error if worker already exists or is of a wrong type + * (recoverable) \throws uhd::assertion_error for other failures (unrecoverable. will + * clear the graph) + * + */ + virtual void add_worker(worker_node_t* worker) = 0; + + /*! + * Release all storage for this object. This will delete all contained + * data and worker nodes and remove all dependency relationship and + * resolve callbacks. + * + * The object will be restored to its newly constructed state. Will not + * throw. + */ + virtual void clear() = 0; +}; + +}} // namespace uhd::experts #endif /* INCLUDED_UHD_EXPERTS_EXPERT_CONTAINER_HPP */ diff --git a/host/lib/include/uhdlib/experts/expert_factory.hpp b/host/lib/include/uhdlib/experts/expert_factory.hpp index 9e07aa47f..47308d046 100644 --- a/host/lib/include/uhdlib/experts/expert_factory.hpp +++ b/host/lib/include/uhdlib/experts/expert_factory.hpp @@ -18,311 +18,333 @@ namespace uhd { namespace experts { +/*! + * expert_factory is a friend of expert_container and + * handles all operations to create and change the structure of + * the an expert container. + * The expert_factory allocates storage for the nodes in the + * expert_container and passes allocated objects to the container + * using private APIs. The expert_container instance owns all + * data and workernodes and is responsible for releasing their + * storage on destruction. + * + */ +class UHD_API expert_factory : public uhd::noncopyable +{ +public: /*! - * expert_factory is a friend of expert_container and - * handles all operations to create and change the structure of - * the an expert container. - * The expert_factory allocates storage for the nodes in the - * expert_container and passes allocated objects to the container - * using private APIs. The expert_container instance owns all - * data and workernodes and is responsible for releasing their - * storage on destruction. + * Creates an empty instance of expert_container with the + * specified name. * + * \param name Name of the container */ - class UHD_API expert_factory : public uhd::noncopyable { - public: + static expert_container::sptr create_container(const std::string& name); - /*! - * Creates an empty instance of expert_container with the - * specified name. - * - * \param name Name of the container - */ - static expert_container::sptr create_container( - const std::string& name - ); - - /*! - * Add a data node to the expert graph. - * - * \param container A shared pointer to the container to add the node to - * \param name The name of the data node - * \param init_val The initial value of the data node - * \param mode The auto resolve mode - * - * Requirements for data_t - * - Must have a default constructor - * - Must have a copy constructor - * - Must have an assignment operator (=) - * - Must have an equality operator (==) - */ - template<typename data_t> - inline static void add_data_node( - expert_container::sptr container, - const std::string& name, - const data_t& init_val, - const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF - ) { - container->add_data_node(new data_node_t<data_t>(name, init_val), mode); - } + /*! + * Add a data node to the expert graph. + * + * \param container A shared pointer to the container to add the node to + * \param name The name of the data node + * \param init_val The initial value of the data node + * \param mode The auto resolve mode + * + * Requirements for data_t + * - Must have a default constructor + * - Must have a copy constructor + * - Must have an assignment operator (=) + * - Must have an equality operator (==) + */ + template <typename data_t> + inline static void add_data_node(expert_container::sptr container, + const std::string& name, + const data_t& init_val, + const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF) + { + container->add_data_node(new data_node_t<data_t>(name, init_val), mode); + } - /*! - * Add a expert property to a property tree AND an expert graph - * - * \param container A shared pointer to the expert container to add the node to - * \param subtree A shared pointer to subtree to add the property to - * \param path The path of the property in the subtree - * \param name The name of the data node in the expert graph - * \param init_val The initial value of the data node - * \param mode The auto resolve mode - * - * Requirements for data_t - * - Must have a default constructor - * - Must have a copy constructor - * - Must have an assignment operator (=) - * - Must have an equality operator (==) - */ - template<typename data_t> - inline static property<data_t>& add_prop_node( - expert_container::sptr container, - property_tree::sptr subtree, - const fs_path &path, - const std::string& name, - const data_t& init_val, - const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF - ) { - property<data_t>& prop = subtree->create<data_t>(path, property_tree::MANUAL_COERCE); - data_node_t<data_t>* node_ptr = - new data_node_t<data_t>(name, init_val, &container->resolve_mutex()); - prop.set(init_val); - prop.add_desired_subscriber(std::bind(&data_node_t<data_t>::commit, node_ptr, std::placeholders::_1)); - prop.set_publisher(std::bind(&data_node_t<data_t>::retrieve, node_ptr)); - container->add_data_node(node_ptr, mode); - return prop; - } + /*! + * Add a expert property to a property tree AND an expert graph + * + * \param container A shared pointer to the expert container to add the node to + * \param subtree A shared pointer to subtree to add the property to + * \param path The path of the property in the subtree + * \param name The name of the data node in the expert graph + * \param init_val The initial value of the data node + * \param mode The auto resolve mode + * + * Requirements for data_t + * - Must have a default constructor + * - Must have a copy constructor + * - Must have an assignment operator (=) + * - Must have an equality operator (==) + */ + template <typename data_t> + inline static property<data_t>& add_prop_node(expert_container::sptr container, + property_tree::sptr subtree, + const fs_path& path, + const std::string& name, + const data_t& init_val, + const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF) + { + property<data_t>& prop = + subtree->create<data_t>(path, property_tree::MANUAL_COERCE); + data_node_t<data_t>* node_ptr = + new data_node_t<data_t>(name, init_val, &container->resolve_mutex()); + prop.set(init_val); + prop.add_desired_subscriber( + std::bind(&data_node_t<data_t>::commit, node_ptr, std::placeholders::_1)); + prop.set_publisher(std::bind(&data_node_t<data_t>::retrieve, node_ptr)); + container->add_data_node(node_ptr, mode); + return prop; + } - /*! - * Add a expert property to a property tree AND an expert graph. - * The property is registered with the path as the identifier for - * both the property subtree and the expert container - * - * \param container A shared pointer to the expert container to add the node to - * \param subtree A shared pointer to subtree to add the property to - * \param path The path of the property in the subtree - * \param init_val The initial value of the data node - * \param mode The auto resolve mode - * - */ - template<typename data_t> - inline static property<data_t>& add_prop_node( - expert_container::sptr container, - property_tree::sptr subtree, - const fs_path &path, - const data_t& init_val, - const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF - ) { - return add_prop_node(container, subtree, path, path, init_val, mode); - } + /*! + * Add a expert property to a property tree AND an expert graph. + * The property is registered with the path as the identifier for + * both the property subtree and the expert container + * + * \param container A shared pointer to the expert container to add the node to + * \param subtree A shared pointer to subtree to add the property to + * \param path The path of the property in the subtree + * \param init_val The initial value of the data node + * \param mode The auto resolve mode + * + */ + template <typename data_t> + inline static property<data_t>& add_prop_node(expert_container::sptr container, + property_tree::sptr subtree, + const fs_path& path, + const data_t& init_val, + const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF) + { + return add_prop_node(container, subtree, path, path, init_val, mode); + } - /*! - * Add a dual expert property to a property tree AND an expert graph. - * A dual property is a desired and coerced value pair - * - * \param container A shared pointer to the expert container to add the node to - * \param subtree A shared pointer to subtree to add the property to - * \param path The path of the property in the subtree - * \param desired_name The name of the desired data node in the expert graph - * \param desired_name The name of the coerced data node in the expert graph - * \param init_val The initial value of both the data nodes - * \param mode The auto resolve mode - * - * Requirements for data_t - * - Must have a default constructor - * - Must have a copy constructor - * - Must have an assignment operator (=) - * - Must have an equality operator (==) - */ - template<typename data_t> - inline static property<data_t>& add_dual_prop_node( - expert_container::sptr container, - property_tree::sptr subtree, - const fs_path &path, - const std::string& desired_name, - const std::string& coerced_name, - const data_t& init_val, - const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF - ) { - bool auto_resolve_desired = (mode==AUTO_RESOLVE_ON_WRITE or mode==AUTO_RESOLVE_ON_READ_WRITE); - bool auto_resolve_coerced = (mode==AUTO_RESOLVE_ON_READ or mode==AUTO_RESOLVE_ON_READ_WRITE); + /*! + * Add a dual expert property to a property tree AND an expert graph. + * A dual property is a desired and coerced value pair + * + * \param container A shared pointer to the expert container to add the node to + * \param subtree A shared pointer to subtree to add the property to + * \param path The path of the property in the subtree + * \param desired_name The name of the desired data node in the expert graph + * \param desired_name The name of the coerced data node in the expert graph + * \param init_val The initial value of both the data nodes + * \param mode The auto resolve mode + * + * Requirements for data_t + * - Must have a default constructor + * - Must have a copy constructor + * - Must have an assignment operator (=) + * - Must have an equality operator (==) + */ + template <typename data_t> + inline static property<data_t>& add_dual_prop_node(expert_container::sptr container, + property_tree::sptr subtree, + const fs_path& path, + const std::string& desired_name, + const std::string& coerced_name, + const data_t& init_val, + const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF) + { + bool auto_resolve_desired = + (mode == AUTO_RESOLVE_ON_WRITE or mode == AUTO_RESOLVE_ON_READ_WRITE); + bool auto_resolve_coerced = + (mode == AUTO_RESOLVE_ON_READ or mode == AUTO_RESOLVE_ON_READ_WRITE); - property<data_t>& prop = subtree->create<data_t>(path, property_tree::MANUAL_COERCE); - data_node_t<data_t>* desired_node_ptr = - new data_node_t<data_t>(desired_name, init_val, &container->resolve_mutex()); - data_node_t<data_t>* coerced_node_ptr = - new data_node_t<data_t>(coerced_name, init_val, &container->resolve_mutex()); - prop.set(init_val); - prop.set_coerced(init_val); - prop.add_desired_subscriber(std::bind(&data_node_t<data_t>::commit, desired_node_ptr, std::placeholders::_1)); - prop.set_publisher(std::bind(&data_node_t<data_t>::retrieve, coerced_node_ptr)); + property<data_t>& prop = + subtree->create<data_t>(path, property_tree::MANUAL_COERCE); + data_node_t<data_t>* desired_node_ptr = + new data_node_t<data_t>(desired_name, init_val, &container->resolve_mutex()); + data_node_t<data_t>* coerced_node_ptr = + new data_node_t<data_t>(coerced_name, init_val, &container->resolve_mutex()); + prop.set(init_val); + prop.set_coerced(init_val); + prop.add_desired_subscriber(std::bind( + &data_node_t<data_t>::commit, desired_node_ptr, std::placeholders::_1)); + prop.set_publisher(std::bind(&data_node_t<data_t>::retrieve, coerced_node_ptr)); - container->add_data_node(desired_node_ptr, - auto_resolve_desired ? AUTO_RESOLVE_ON_WRITE : AUTO_RESOLVE_OFF); - container->add_data_node(coerced_node_ptr, - auto_resolve_coerced ? AUTO_RESOLVE_ON_READ : AUTO_RESOLVE_OFF); - return prop; - } + container->add_data_node(desired_node_ptr, + auto_resolve_desired ? AUTO_RESOLVE_ON_WRITE : AUTO_RESOLVE_OFF); + container->add_data_node(coerced_node_ptr, + auto_resolve_coerced ? AUTO_RESOLVE_ON_READ : AUTO_RESOLVE_OFF); + return prop; + } - /*! - * Add a dual expert property to a property tree AND an expert graph. - * A dual property is a desired and coerced value pair - * The property is registered with path/desired as the desired node - * name and path/coerced as the coerced node name - * - * \param container A shared pointer to the expert container to add the node to - * \param subtree A shared pointer to subtree to add the property to - * \param path The path of the property in the subtree - * \param init_val The initial value of both the data nodes - * \param mode The auto resolve mode - * - */ - template<typename data_t> - inline static property<data_t>& add_dual_prop_node( - expert_container::sptr container, - property_tree::sptr subtree, - const fs_path &path, - const data_t& init_val, - const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF - ) { - return add_dual_prop_node(container, subtree, path, path + "/desired", path + "/coerced", init_val, mode); - } + /*! + * Add a dual expert property to a property tree AND an expert graph. + * A dual property is a desired and coerced value pair + * The property is registered with path/desired as the desired node + * name and path/coerced as the coerced node name + * + * \param container A shared pointer to the expert container to add the node to + * \param subtree A shared pointer to subtree to add the property to + * \param path The path of the property in the subtree + * \param init_val The initial value of both the data nodes + * \param mode The auto resolve mode + * + */ + template <typename data_t> + inline static property<data_t>& add_dual_prop_node(expert_container::sptr container, + property_tree::sptr subtree, + const fs_path& path, + const data_t& init_val, + const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF) + { + return add_dual_prop_node(container, + subtree, + path, + path + "/desired", + path + "/coerced", + init_val, + mode); + } - /*! - * Add a worker node to the expert graph. - * The expert_container owns and manages storage for the worker - * - * \tparam worker_t Data type of the worker class - * - * \param container A shared pointer to the container to add the node to - * - */ - template<typename worker_t> - inline static void add_worker_node( - expert_container::sptr container - ) { - container->add_worker(new worker_t()); - } + /*! + * Add a worker node to the expert graph. + * The expert_container owns and manages storage for the worker + * + * \tparam worker_t Data type of the worker class + * + * \param container A shared pointer to the container to add the node to + * + */ + template <typename worker_t> + inline static void add_worker_node(expert_container::sptr container) + { + container->add_worker(new worker_t()); + } - /*! - * Add a worker node to the expert graph. - * The expert_container owns and manages storage for the worker - * - * \tparam worker_t Data type of the worker class - * \tparam arg1_t Data type of the first argument to the constructor - * \tparam ... - * \tparam argN_t Data type of the Nth argument to the constructor - * - * \param container A shared pointer to the container to add the node to - * \param arg1 First arg to ctor - * \param ... - * \param argN Nth arg to ctor - * - */ - template<typename worker_t, typename arg1_t> - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1 - ) { - container->add_worker(new worker_t(arg1)); - } + /*! + * Add a worker node to the expert graph. + * The expert_container owns and manages storage for the worker + * + * \tparam worker_t Data type of the worker class + * \tparam arg1_t Data type of the first argument to the constructor + * \tparam ... + * \tparam argN_t Data type of the Nth argument to the constructor + * + * \param container A shared pointer to the container to add the node to + * \param arg1 First arg to ctor + * \param ... + * \param argN Nth arg to ctor + * + */ + template <typename worker_t, typename arg1_t> + inline static void add_worker_node( + expert_container::sptr container, arg1_t const& arg1) + { + container->add_worker(new worker_t(arg1)); + } - template<typename worker_t, typename arg1_t, typename arg2_t> - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2 - ) { - container->add_worker(new worker_t(arg1, arg2)); - } + template <typename worker_t, typename arg1_t, typename arg2_t> + inline static void add_worker_node( + expert_container::sptr container, arg1_t const& arg1, arg2_t const& arg2) + { + container->add_worker(new worker_t(arg1, arg2)); + } - template<typename worker_t, typename arg1_t, typename arg2_t, typename arg3_t> - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2, - arg3_t const & arg3 - ) { - container->add_worker(new worker_t(arg1, arg2, arg3)); - } + template <typename worker_t, typename arg1_t, typename arg2_t, typename arg3_t> + inline static void add_worker_node(expert_container::sptr container, + arg1_t const& arg1, + arg2_t const& arg2, + arg3_t const& arg3) + { + container->add_worker(new worker_t(arg1, arg2, arg3)); + } - template<typename worker_t, typename arg1_t, typename arg2_t, typename arg3_t, typename arg4_t> - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2, - arg3_t const & arg3, - arg4_t const & arg4 - ) { - container->add_worker(new worker_t(arg1, arg2, arg3, arg4)); - } + template <typename worker_t, + typename arg1_t, + typename arg2_t, + typename arg3_t, + typename arg4_t> + inline static void add_worker_node(expert_container::sptr container, + arg1_t const& arg1, + arg2_t const& arg2, + arg3_t const& arg3, + arg4_t const& arg4) + { + container->add_worker(new worker_t(arg1, arg2, arg3, arg4)); + } - template<typename worker_t, typename arg1_t, typename arg2_t, typename arg3_t, typename arg4_t, - typename arg5_t> - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2, - arg3_t const & arg3, - arg4_t const & arg4, - arg5_t const & arg5 - ) { - container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5)); - } + template <typename worker_t, + typename arg1_t, + typename arg2_t, + typename arg3_t, + typename arg4_t, + typename arg5_t> + inline static void add_worker_node(expert_container::sptr container, + arg1_t const& arg1, + arg2_t const& arg2, + arg3_t const& arg3, + arg4_t const& arg4, + arg5_t const& arg5) + { + container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5)); + } - template<typename worker_t, typename arg1_t, typename arg2_t, typename arg3_t, typename arg4_t, - typename arg5_t, typename arg6_t> - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2, - arg3_t const & arg3, - arg4_t const & arg4, - arg5_t const & arg5, - arg6_t const & arg6 - ) { - container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5, arg6)); - } + template <typename worker_t, + typename arg1_t, + typename arg2_t, + typename arg3_t, + typename arg4_t, + typename arg5_t, + typename arg6_t> + inline static void add_worker_node(expert_container::sptr container, + arg1_t const& arg1, + arg2_t const& arg2, + arg3_t const& arg3, + arg4_t const& arg4, + arg5_t const& arg5, + arg6_t const& arg6) + { + container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5, arg6)); + } - template<typename worker_t, typename arg1_t, typename arg2_t, typename arg3_t, typename arg4_t, - typename arg5_t, typename arg6_t, typename arg7_t> - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2, - arg3_t const & arg3, - arg4_t const & arg4, - arg5_t const & arg5, - arg6_t const & arg6, - arg7_t const & arg7 - ) { - container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5, arg6, arg7)); - } + template <typename worker_t, + typename arg1_t, + typename arg2_t, + typename arg3_t, + typename arg4_t, + typename arg5_t, + typename arg6_t, + typename arg7_t> + inline static void add_worker_node(expert_container::sptr container, + arg1_t const& arg1, + arg2_t const& arg2, + arg3_t const& arg3, + arg4_t const& arg4, + arg5_t const& arg5, + arg6_t const& arg6, + arg7_t const& arg7) + { + container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5, arg6, arg7)); + } - template<typename worker_t, typename arg1_t, typename arg2_t, typename arg3_t, typename arg4_t, - typename arg5_t, typename arg6_t, typename arg7_t, typename arg8_t> - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2, - arg3_t const & arg3, - arg4_t const & arg4, - arg5_t const & arg5, - arg6_t const & arg6, - arg7_t const & arg7, - arg7_t const & arg8 - ) { - container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); - } - }; -}} + template <typename worker_t, + typename arg1_t, + typename arg2_t, + typename arg3_t, + typename arg4_t, + typename arg5_t, + typename arg6_t, + typename arg7_t, + typename arg8_t> + inline static void add_worker_node(expert_container::sptr container, + arg1_t const& arg1, + arg2_t const& arg2, + arg3_t const& arg3, + arg4_t const& arg4, + arg5_t const& arg5, + arg6_t const& arg6, + arg7_t const& arg7, + arg7_t const& arg8) + { + container->add_worker( + new worker_t(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); + } +}; +}} // namespace uhd::experts #endif /* INCLUDED_UHD_EXPERTS_EXPERT_FACTORY_HPP */ diff --git a/host/lib/include/uhdlib/experts/expert_nodes.hpp b/host/lib/include/uhdlib/experts/expert_nodes.hpp index 665c0e579..b9a0f57bd 100644 --- a/host/lib/include/uhdlib/experts/expert_nodes.hpp +++ b/host/lib/include/uhdlib/experts/expert_nodes.hpp @@ -10,464 +10,544 @@ #include <uhd/config.hpp> #include <uhd/exception.hpp> +#include <uhd/types/time_spec.hpp> #include <uhd/utils/dirty_tracked.hpp> #include <uhd/utils/noncopyable.hpp> -#include <uhd/types/time_spec.hpp> -#include <functional> -#include <boost/thread/recursive_mutex.hpp> -#include <boost/thread.hpp> +#include <stdint.h> #include <boost/core/demangle.hpp> -#include <memory> +#include <boost/thread.hpp> +#include <boost/thread/recursive_mutex.hpp> +#include <functional> #include <list> -#include <stdint.h> +#include <memory> namespace uhd { namespace experts { - enum node_class_t { CLASS_WORKER, CLASS_DATA, CLASS_PROPERTY }; - enum node_access_t { ACCESS_READER, ACCESS_WRITER }; - enum node_author_t { AUTHOR_NONE, AUTHOR_USER, AUTHOR_EXPERT }; - - /*!--------------------------------------------------------- - * class dag_vertex_t - * - * This serves as the base class for all nodes in the expert - * graph. Data nodes and workers are derived from this class. - * --------------------------------------------------------- - */ - class dag_vertex_t : private uhd::noncopyable { - public: - typedef std::function<void(std::string)> callback_func_t; - - virtual ~dag_vertex_t() {} - - // Getters for basic info about the node - inline node_class_t get_class() const { - return _class; - } - - inline const std::string& get_name() const { - return _name; - } - - virtual const std::string& get_dtype() const = 0; - - virtual std::string to_string() const = 0; - - // Graph resolution specific - virtual bool is_dirty() const = 0; - virtual void mark_clean() = 0; - virtual void resolve() = 0; - - // External callbacks - virtual void set_write_callback(const callback_func_t& func) = 0; - virtual bool has_write_callback() const = 0; - virtual void clear_write_callback() = 0; - virtual void set_read_callback(const callback_func_t& func) = 0; - virtual bool has_read_callback() const = 0; - virtual void clear_read_callback() = 0; - - protected: - dag_vertex_t(const node_class_t c, const std::string& n): - _class(c), _name(n) {} - - private: - const node_class_t _class; - const std::string _name; - }; - - class data_node_printer { - public: - //Generic implementation - template<typename data_t> - static std::string print(const data_t& val) { - std::ostringstream os; - os << val; - return os.str(); - } - - static std::string print(const uint8_t& val) { - std::ostringstream os; - os << int(val); - return os.str(); - } - - static std::string print(const time_spec_t time) { - std::ostringstream os; - os << time.get_real_secs(); - return os.str(); - } - }; - - /*!--------------------------------------------------------- - * class data_node_t - * - * The data node class hold a passive piece of data in the - * expert graph. A data node is clean if its underlying data - * is clean. Access to the underlying data is provided using - * two methods: - * 1. Special accessor classes (for R/W enforcement) - * 2. External clients (via commit and retrieve). This access - * is protected by the callback mutex. - * - * Requirements for data_t - * - Must have a default constructor - * - Must have a copy constructor - * - Must have an assignment operator (=) - * - Must have an equality operator (==) - * --------------------------------------------------------- - */ - template<typename data_t> - class data_node_t : public dag_vertex_t { - public: - // A data_node_t instance can have a type of CLASS_DATA or CLASS_PROPERTY - // In general a data node is a property if it can be accessed and modified - // from the outside world (of experts) using read and write callbacks. We - // assume that if a callback mutex is passed into the data node that it will - // be accessed from the outside and tag the data node as a PROPERTY. - data_node_t(const std::string& name, boost::recursive_mutex* mutex = NULL) : - dag_vertex_t(mutex?CLASS_PROPERTY:CLASS_DATA, name), _callback_mutex(mutex), _data(), _author(AUTHOR_NONE) {} - - data_node_t(const std::string& name, const data_t& value, boost::recursive_mutex* mutex = NULL) : - dag_vertex_t(mutex?CLASS_PROPERTY:CLASS_DATA, name), _callback_mutex(mutex), _data(value), _author(AUTHOR_NONE) {} - - // Basic info - virtual const std::string& get_dtype() const { - static const std::string dtype( - boost::core::demangle(typeid(data_t).name())); - return dtype; - } - - virtual std::string to_string() const { - return data_node_printer::print(get()); - } - - inline node_author_t get_author() const { - return _author; - } - - // Graph resolution specific - virtual bool is_dirty() const { - return _data.is_dirty(); - } - - virtual void mark_clean() { - _data.mark_clean(); - } - - void resolve() { - //NOP - } - - // Data node specific setters and getters (for the framework) - void set(const data_t& value) { - _data = value; - _author = AUTHOR_EXPERT; - } - - const data_t& get() const { - return _data; - } - - // Data node specific setters and getters (for external entities) - void commit(const data_t& value) { - if (_callback_mutex == NULL) throw uhd::assertion_error("node " + get_name() + " is missing the callback mutex"); - boost::lock_guard<boost::recursive_mutex> lock(*_callback_mutex); - set(value); - _author = AUTHOR_USER; - if (is_dirty() and has_write_callback()) { - _wr_callback(std::string(get_name())); //Put the name on the stack before calling - } - } - - const data_t retrieve() const { - if (_callback_mutex == NULL) throw uhd::assertion_error("node " + get_name() + " is missing the callback mutex"); - boost::lock_guard<boost::recursive_mutex> lock(*_callback_mutex); - if (has_read_callback()) { - _rd_callback(std::string(get_name())); - } - return get(); - } - - private: - // External callbacks - virtual void set_write_callback(const callback_func_t& func) { - _wr_callback = func; - } - - virtual bool has_write_callback() const { - return bool(_wr_callback); - } - - virtual void clear_write_callback() { - _wr_callback = nullptr; - } - - virtual void set_read_callback(const callback_func_t& func) { - _rd_callback = func; - } - - virtual bool has_read_callback() const { - return bool(_rd_callback); - } - - virtual void clear_read_callback() { - _rd_callback = nullptr; - } - - boost::recursive_mutex* _callback_mutex; - callback_func_t _rd_callback; - callback_func_t _wr_callback; - dirty_tracked<data_t> _data; - node_author_t _author; - }; - - /*!--------------------------------------------------------- - * class node_retriever_t - * - * Node storage is managed by a framework class so we need - * and interface to find and retrieve data nodes to associate - * with accessors. - * --------------------------------------------------------- - */ - class node_retriever_t { - public: - virtual ~node_retriever_t() {} - virtual const dag_vertex_t& lookup(const std::string& name) const = 0; - private: - friend class data_accessor_t; - virtual dag_vertex_t& retrieve(const std::string& name) const = 0; - }; - - /*!--------------------------------------------------------- - * class data_accessor_t - * - * Accessors provide protected access to data nodes and help - * establish dependency relationships. - * --------------------------------------------------------- - */ - class data_accessor_t { - public: - virtual ~data_accessor_t() {} - - virtual bool is_reader() const = 0; - virtual bool is_writer() const = 0; - virtual dag_vertex_t& node() const = 0; - protected: - data_accessor_t(const node_retriever_t& r, const std::string& n): - _vertex(r.retrieve(n)) {} - dag_vertex_t& _vertex; - }; - - template<typename data_t> - class data_accessor_base : public data_accessor_t { - public: - virtual ~data_accessor_base() {} - - virtual bool is_reader() const { - return _access == ACCESS_READER; - } - - virtual bool is_writer() const { - return _access == ACCESS_WRITER; - } - - inline bool is_dirty() const { - return _datanode->is_dirty(); - } - - inline node_class_t get_class() const { - return _datanode->get_class(); - } - - inline node_author_t get_author() const { - return _datanode->get_author(); - } - - protected: - data_accessor_base( - const node_retriever_t& r, const std::string& n, const node_access_t a) : - data_accessor_t(r, n), _datanode(NULL), _access(a) - { - _datanode = dynamic_cast< data_node_t<data_t>* >(&node()); - if (_datanode == NULL) { - throw uhd::type_error("Expected data type for node " + n + - " was " + boost::core::demangle(typeid(data_t).name()) + - " but got " + node().get_dtype()); - } - } - - data_node_t<data_t>* _datanode; - const node_access_t _access; - - private: - virtual dag_vertex_t& node() const { - return _vertex; - } - }; - - /*!--------------------------------------------------------- - * class data_reader_t - * - * Accessor to read the value of a data node and to establish - * a data node => worker node dependency - * --------------------------------------------------------- - */ - template<typename data_t> - class data_reader_t : public data_accessor_base<data_t> { - public: - data_reader_t(const node_retriever_t& retriever, const std::string& node) : - data_accessor_base<data_t>( - retriever, node, ACCESS_READER) {} - - inline const data_t& get() const { - return data_accessor_base<data_t>::_datanode->get(); - } - - inline operator const data_t&() const { - return get(); - } - - inline bool operator==(const data_t& rhs) { - return get() == rhs; - } - - inline bool operator!=(const data_t& rhs) { - return !(get() == rhs); - } - }; - - /*!--------------------------------------------------------- - * class data_reader_t - * - * Accessor to read and write the value of a data node and - * to establish a worker node => data node dependency - * --------------------------------------------------------- - */ - template<typename data_t> - class data_writer_t : public data_accessor_base<data_t> { - public: - data_writer_t(const node_retriever_t& retriever, const std::string& node) : - data_accessor_base<data_t>( - retriever, node, ACCESS_WRITER) {} - - inline const data_t& get() const { - return data_accessor_base<data_t>::_datanode->get(); - } - - inline operator const data_t&() const { - return get(); - } - - inline bool operator==(const data_t& rhs) { - return get() == rhs; - } - - inline bool operator!=(const data_t& rhs) { - return !(get() == rhs); - } - - inline void set(const data_t& value) { - data_accessor_base<data_t>::_datanode->set(value); - } - - inline data_writer_t<data_t>& operator=(const data_t& value) { - set(value); - return *this; - } - - inline data_writer_t<data_t>& operator=(const data_writer_t<data_t>& value) { - set(value.get()); - return *this; - } +enum node_class_t { CLASS_WORKER, CLASS_DATA, CLASS_PROPERTY }; +enum node_access_t { ACCESS_READER, ACCESS_WRITER }; +enum node_author_t { AUTHOR_NONE, AUTHOR_USER, AUTHOR_EXPERT }; + +/*!--------------------------------------------------------- + * class dag_vertex_t + * + * This serves as the base class for all nodes in the expert + * graph. Data nodes and workers are derived from this class. + * --------------------------------------------------------- + */ +class dag_vertex_t : private uhd::noncopyable +{ +public: + typedef std::function<void(std::string)> callback_func_t; + + virtual ~dag_vertex_t() {} + + // Getters for basic info about the node + inline node_class_t get_class() const + { + return _class; + } + + inline const std::string& get_name() const + { + return _name; + } + + virtual const std::string& get_dtype() const = 0; + + virtual std::string to_string() const = 0; + + // Graph resolution specific + virtual bool is_dirty() const = 0; + virtual void mark_clean() = 0; + virtual void resolve() = 0; + + // External callbacks + virtual void set_write_callback(const callback_func_t& func) = 0; + virtual bool has_write_callback() const = 0; + virtual void clear_write_callback() = 0; + virtual void set_read_callback(const callback_func_t& func) = 0; + virtual bool has_read_callback() const = 0; + virtual void clear_read_callback() = 0; + +protected: + dag_vertex_t(const node_class_t c, const std::string& n) : _class(c), _name(n) {} + +private: + const node_class_t _class; + const std::string _name; }; - /*!--------------------------------------------------------- - * class worker_node_t - * - * A node class to implement a function that consumes - * zero or more input data nodes and emits zero or more output - * data nodes. The worker can also operate on other non-expert - * interfaces because worker_node_t is abstract and the client - * is required to implement the "resolve" method in a subclass. - * --------------------------------------------------------- - */ - class worker_node_t : public dag_vertex_t { - public: - worker_node_t(const std::string& name) : - dag_vertex_t(CLASS_WORKER, name) {} - - // Worker node specific - std::list<std::string> get_inputs() const { - std::list<std::string> retval; - for(data_accessor_t* acc: _inputs) { - retval.push_back(acc->node().get_name()); - } - return retval; - } - - std::list<std::string> get_outputs() const { - std::list<std::string> retval; - for(data_accessor_t* acc: _outputs) { - retval.push_back(acc->node().get_name()); - } - return retval; - } - - protected: - // This function is used to bind data accessors - // to this worker. Accessors can be read/write - // and the binding will ensure proper dependency - // handling. - void bind_accessor(data_accessor_t& accessor) { - if (accessor.is_reader()) { - _inputs.push_back(&accessor); - } else if (accessor.is_writer()) { - _outputs.push_back(&accessor); - } else { - throw uhd::assertion_error("Invalid accessor type"); - } - } +class data_node_printer +{ +public: + // Generic implementation + template <typename data_t> + static std::string print(const data_t& val) + { + std::ostringstream os; + os << val; + return os.str(); + } + + static std::string print(const uint8_t& val) + { + std::ostringstream os; + os << int(val); + return os.str(); + } + + static std::string print(const time_spec_t time) + { + std::ostringstream os; + os << time.get_real_secs(); + return os.str(); + } +}; - private: - // Graph resolution specific - virtual bool is_dirty() const { - bool inputs_dirty = false; - for(data_accessor_t* acc: _inputs) { - inputs_dirty |= acc->node().is_dirty(); - } - return inputs_dirty; - } +/*!--------------------------------------------------------- + * class data_node_t + * + * The data node class hold a passive piece of data in the + * expert graph. A data node is clean if its underlying data + * is clean. Access to the underlying data is provided using + * two methods: + * 1. Special accessor classes (for R/W enforcement) + * 2. External clients (via commit and retrieve). This access + * is protected by the callback mutex. + * + * Requirements for data_t + * - Must have a default constructor + * - Must have a copy constructor + * - Must have an assignment operator (=) + * - Must have an equality operator (==) + * --------------------------------------------------------- + */ +template <typename data_t> +class data_node_t : public dag_vertex_t +{ +public: + // A data_node_t instance can have a type of CLASS_DATA or CLASS_PROPERTY + // In general a data node is a property if it can be accessed and modified + // from the outside world (of experts) using read and write callbacks. We + // assume that if a callback mutex is passed into the data node that it will + // be accessed from the outside and tag the data node as a PROPERTY. + data_node_t(const std::string& name, boost::recursive_mutex* mutex = NULL) + : dag_vertex_t(mutex ? CLASS_PROPERTY : CLASS_DATA, name) + , _callback_mutex(mutex) + , _data() + , _author(AUTHOR_NONE) + { + } + + data_node_t(const std::string& name, + const data_t& value, + boost::recursive_mutex* mutex = NULL) + : dag_vertex_t(mutex ? CLASS_PROPERTY : CLASS_DATA, name) + , _callback_mutex(mutex) + , _data(value) + , _author(AUTHOR_NONE) + { + } + + // Basic info + virtual const std::string& get_dtype() const + { + static const std::string dtype(boost::core::demangle(typeid(data_t).name())); + return dtype; + } + + virtual std::string to_string() const + { + return data_node_printer::print(get()); + } + + inline node_author_t get_author() const + { + return _author; + } + + // Graph resolution specific + virtual bool is_dirty() const + { + return _data.is_dirty(); + } + + virtual void mark_clean() + { + _data.mark_clean(); + } + + void resolve() + { + // NOP + } + + // Data node specific setters and getters (for the framework) + void set(const data_t& value) + { + _data = value; + _author = AUTHOR_EXPERT; + } + + const data_t& get() const + { + return _data; + } + + // Data node specific setters and getters (for external entities) + void commit(const data_t& value) + { + if (_callback_mutex == NULL) + throw uhd::assertion_error( + "node " + get_name() + " is missing the callback mutex"); + boost::lock_guard<boost::recursive_mutex> lock(*_callback_mutex); + set(value); + _author = AUTHOR_USER; + if (is_dirty() and has_write_callback()) { + _wr_callback( + std::string(get_name())); // Put the name on the stack before calling + } + } + + const data_t retrieve() const + { + if (_callback_mutex == NULL) + throw uhd::assertion_error( + "node " + get_name() + " is missing the callback mutex"); + boost::lock_guard<boost::recursive_mutex> lock(*_callback_mutex); + if (has_read_callback()) { + _rd_callback(std::string(get_name())); + } + return get(); + } + +private: + // External callbacks + virtual void set_write_callback(const callback_func_t& func) + { + _wr_callback = func; + } + + virtual bool has_write_callback() const + { + return bool(_wr_callback); + } + + virtual void clear_write_callback() + { + _wr_callback = nullptr; + } + + virtual void set_read_callback(const callback_func_t& func) + { + _rd_callback = func; + } + + virtual bool has_read_callback() const + { + return bool(_rd_callback); + } + + virtual void clear_read_callback() + { + _rd_callback = nullptr; + } + + boost::recursive_mutex* _callback_mutex; + callback_func_t _rd_callback; + callback_func_t _wr_callback; + dirty_tracked<data_t> _data; + node_author_t _author; +}; - virtual void mark_clean() { - for(data_accessor_t* acc: _inputs) { - acc->node().mark_clean(); - } - } +/*!--------------------------------------------------------- + * class node_retriever_t + * + * Node storage is managed by a framework class so we need + * and interface to find and retrieve data nodes to associate + * with accessors. + * --------------------------------------------------------- + */ +class node_retriever_t +{ +public: + virtual ~node_retriever_t() {} + virtual const dag_vertex_t& lookup(const std::string& name) const = 0; + +private: + friend class data_accessor_t; + virtual dag_vertex_t& retrieve(const std::string& name) const = 0; +}; - virtual void resolve() = 0; +/*!--------------------------------------------------------- + * class data_accessor_t + * + * Accessors provide protected access to data nodes and help + * establish dependency relationships. + * --------------------------------------------------------- + */ +class data_accessor_t +{ +public: + virtual ~data_accessor_t() {} + + virtual bool is_reader() const = 0; + virtual bool is_writer() const = 0; + virtual dag_vertex_t& node() const = 0; + +protected: + data_accessor_t(const node_retriever_t& r, const std::string& n) + : _vertex(r.retrieve(n)) + { + } + dag_vertex_t& _vertex; +}; - // Basic type info - virtual const std::string& get_dtype() const { - static const std::string dtype = "<worker>"; - return dtype; - } +template <typename data_t> +class data_accessor_base : public data_accessor_t +{ +public: + virtual ~data_accessor_base() {} + + virtual bool is_reader() const + { + return _access == ACCESS_READER; + } + + virtual bool is_writer() const + { + return _access == ACCESS_WRITER; + } + + inline bool is_dirty() const + { + return _datanode->is_dirty(); + } + + inline node_class_t get_class() const + { + return _datanode->get_class(); + } + + inline node_author_t get_author() const + { + return _datanode->get_author(); + } + +protected: + data_accessor_base( + const node_retriever_t& r, const std::string& n, const node_access_t a) + : data_accessor_t(r, n), _datanode(NULL), _access(a) + { + _datanode = dynamic_cast<data_node_t<data_t>*>(&node()); + if (_datanode == NULL) { + throw uhd::type_error("Expected data type for node " + n + " was " + + boost::core::demangle(typeid(data_t).name()) + + " but got " + node().get_dtype()); + } + } + + data_node_t<data_t>* _datanode; + const node_access_t _access; + +private: + virtual dag_vertex_t& node() const + { + return _vertex; + } +}; - virtual std::string to_string() const { - return "<worker>"; - } +/*!--------------------------------------------------------- + * class data_reader_t + * + * Accessor to read the value of a data node and to establish + * a data node => worker node dependency + * --------------------------------------------------------- + */ +template <typename data_t> +class data_reader_t : public data_accessor_base<data_t> +{ +public: + data_reader_t(const node_retriever_t& retriever, const std::string& node) + : data_accessor_base<data_t>(retriever, node, ACCESS_READER) + { + } + + inline const data_t& get() const + { + return data_accessor_base<data_t>::_datanode->get(); + } + + inline operator const data_t&() const + { + return get(); + } + + inline bool operator==(const data_t& rhs) + { + return get() == rhs; + } + + inline bool operator!=(const data_t& rhs) + { + return !(get() == rhs); + } +}; - // Workers don't have callbacks so implement stubs - virtual void set_write_callback(const callback_func_t&) {} - virtual bool has_write_callback() const { return false; } - virtual void clear_write_callback() {} - virtual void set_read_callback(const callback_func_t&) {} - virtual bool has_read_callback() const { return false; } - virtual void clear_read_callback() {} +/*!--------------------------------------------------------- + * class data_reader_t + * + * Accessor to read and write the value of a data node and + * to establish a worker node => data node dependency + * --------------------------------------------------------- + */ +template <typename data_t> +class data_writer_t : public data_accessor_base<data_t> +{ +public: + data_writer_t(const node_retriever_t& retriever, const std::string& node) + : data_accessor_base<data_t>(retriever, node, ACCESS_WRITER) + { + } + + inline const data_t& get() const + { + return data_accessor_base<data_t>::_datanode->get(); + } + + inline operator const data_t&() const + { + return get(); + } + + inline bool operator==(const data_t& rhs) + { + return get() == rhs; + } + + inline bool operator!=(const data_t& rhs) + { + return !(get() == rhs); + } + + inline void set(const data_t& value) + { + data_accessor_base<data_t>::_datanode->set(value); + } + + inline data_writer_t<data_t>& operator=(const data_t& value) + { + set(value); + return *this; + } + + inline data_writer_t<data_t>& operator=(const data_writer_t<data_t>& value) + { + set(value.get()); + return *this; + } +}; - std::list<data_accessor_t*> _inputs; - std::list<data_accessor_t*> _outputs; - }; +/*!--------------------------------------------------------- + * class worker_node_t + * + * A node class to implement a function that consumes + * zero or more input data nodes and emits zero or more output + * data nodes. The worker can also operate on other non-expert + * interfaces because worker_node_t is abstract and the client + * is required to implement the "resolve" method in a subclass. + * --------------------------------------------------------- + */ +class worker_node_t : public dag_vertex_t +{ +public: + worker_node_t(const std::string& name) : dag_vertex_t(CLASS_WORKER, name) {} + + // Worker node specific + std::list<std::string> get_inputs() const + { + std::list<std::string> retval; + for (data_accessor_t* acc : _inputs) { + retval.push_back(acc->node().get_name()); + } + return retval; + } + + std::list<std::string> get_outputs() const + { + std::list<std::string> retval; + for (data_accessor_t* acc : _outputs) { + retval.push_back(acc->node().get_name()); + } + return retval; + } + +protected: + // This function is used to bind data accessors + // to this worker. Accessors can be read/write + // and the binding will ensure proper dependency + // handling. + void bind_accessor(data_accessor_t& accessor) + { + if (accessor.is_reader()) { + _inputs.push_back(&accessor); + } else if (accessor.is_writer()) { + _outputs.push_back(&accessor); + } else { + throw uhd::assertion_error("Invalid accessor type"); + } + } + +private: + // Graph resolution specific + virtual bool is_dirty() const + { + bool inputs_dirty = false; + for (data_accessor_t* acc : _inputs) { + inputs_dirty |= acc->node().is_dirty(); + } + return inputs_dirty; + } + + virtual void mark_clean() + { + for (data_accessor_t* acc : _inputs) { + acc->node().mark_clean(); + } + } + + virtual void resolve() = 0; + + // Basic type info + virtual const std::string& get_dtype() const + { + static const std::string dtype = "<worker>"; + return dtype; + } + + virtual std::string to_string() const + { + return "<worker>"; + } + + // Workers don't have callbacks so implement stubs + virtual void set_write_callback(const callback_func_t&) {} + virtual bool has_write_callback() const + { + return false; + } + virtual void clear_write_callback() {} + virtual void set_read_callback(const callback_func_t&) {} + virtual bool has_read_callback() const + { + return false; + } + virtual void clear_read_callback() {} + + std::list<data_accessor_t*> _inputs; + std::list<data_accessor_t*> _outputs; +}; -}} +}} // namespace uhd::experts #endif /* INCLUDED_UHD_EXPERTS_EXPERT_NODE_HPP */ diff --git a/host/lib/include/uhdlib/rfnoc/async_msg.hpp b/host/lib/include/uhdlib/rfnoc/async_msg.hpp index 8abdb27b8..988801dc3 100644 --- a/host/lib/include/uhdlib/rfnoc/async_msg.hpp +++ b/host/lib/include/uhdlib/rfnoc/async_msg.hpp @@ -8,78 +8,80 @@ #define INCLUDED_UHD_RFNOC_ASYNC_MSG_HPP #include <uhd/config.hpp> -#include <uhd/types/time_spec.hpp> #include <uhd/types/sid.hpp> +#include <uhd/types/time_spec.hpp> #include <vector> namespace uhd { namespace rfnoc { - /*! - * Async message. - */ - struct async_msg_t - { - //! Has time? - bool has_time_spec; - - //! When the async event occurred. - time_spec_t time_spec; +/*! + * Async message. + */ +struct async_msg_t +{ + //! Has time? + bool has_time_spec; - /*! - * The type of event for a receive async message call. - */ - enum event_code_t { - //! Nothing happened. - EVENT_CODE_NONE = 0x00, - //! A burst was successfully transmitted. - EVENT_CODE_BURST_ACK = 0x1, - //! An internal send buffer has emptied. - EVENT_CODE_UNDERFLOW = 0x2, - //! Same. We use the terms 'underrun' and 'underflow' interchangeably. - EVENT_CODE_UNDERRUN = EVENT_CODE_UNDERFLOW, - //! Packet loss or reordering between source and destination, - // at start of burst (i.e. the first packet after an EOB packet - // had the wrong sequence number). - EVENT_CODE_SEQ_ERROR = 0x4, - //! Like EVENT_CODE_SEQ_ERROR, but within a burst (i.e., any packet - // other than the first packet had an error) - EVENT_CODE_SEQ_ERROR_IN_BURST = 0x20, - //! Data packet had time that was late. - EVENT_CODE_LATE_DATA_ERROR = 0x8, - //! Command packet had time that was late. - EVENT_CODE_LATE_CMD_ERROR = 0x8, - //! Packet is carrying arbitrary payload - EVENT_CODE_USER_PAYLOAD = 0x40, + //! When the async event occurred. + time_spec_t time_spec; - // TODO: For now, we combine legacy TX and RX messages. - EVENT_CODE_OVERFLOW = 0x8, - EVENT_CODE_OVERRUN = EVENT_CODE_OVERFLOW, - //! Multi-channel alignment failed. - EVENT_CODE_ALIGNMENT = 0xc, - //! The packet could not be parsed. - EVENT_CODE_BAD_PACKET = 0xf - } event_code; + /*! + * The type of event for a receive async message call. + */ + enum event_code_t { + //! Nothing happened. + EVENT_CODE_NONE = 0x00, + //! A burst was successfully transmitted. + EVENT_CODE_BURST_ACK = 0x1, + //! An internal send buffer has emptied. + EVENT_CODE_UNDERFLOW = 0x2, + //! Same. We use the terms 'underrun' and 'underflow' interchangeably. + EVENT_CODE_UNDERRUN = EVENT_CODE_UNDERFLOW, + //! Packet loss or reordering between source and destination, + // at start of burst (i.e. the first packet after an EOB packet + // had the wrong sequence number). + EVENT_CODE_SEQ_ERROR = 0x4, + //! Like EVENT_CODE_SEQ_ERROR, but within a burst (i.e., any packet + // other than the first packet had an error) + EVENT_CODE_SEQ_ERROR_IN_BURST = 0x20, + //! Data packet had time that was late. + EVENT_CODE_LATE_DATA_ERROR = 0x8, + //! Command packet had time that was late. + EVENT_CODE_LATE_CMD_ERROR = 0x8, + //! Packet is carrying arbitrary payload + EVENT_CODE_USER_PAYLOAD = 0x40, - /*! - * A special payload populated by custom FPGA fabric. - */ - std::vector<uint32_t> payload; + // TODO: For now, we combine legacy TX and RX messages. + EVENT_CODE_OVERFLOW = 0x8, + EVENT_CODE_OVERRUN = EVENT_CODE_OVERFLOW, + //! Multi-channel alignment failed. + EVENT_CODE_ALIGNMENT = 0xc, + //! The packet could not be parsed. + EVENT_CODE_BAD_PACKET = 0xf + } event_code; - //! The SID on the async message packet - uint32_t sid; + /*! + * A special payload populated by custom FPGA fabric. + */ + std::vector<uint32_t> payload; - async_msg_t(const size_t payload_size=4) : - has_time_spec(false), - time_spec(0.0), - event_code(EVENT_CODE_NONE), - payload(payload_size, 0), - sid(0) - {} - //! Return the the id of src block that throw eror - uint32_t get_error_src() const { return sid_t(sid).get_src_endpoint(); } - }; + //! The SID on the async message packet + uint32_t sid; + async_msg_t(const size_t payload_size = 4) + : has_time_spec(false) + , time_spec(0.0) + , event_code(EVENT_CODE_NONE) + , payload(payload_size, 0) + , sid(0) + { } -} -#endif /* INCLUDED_UHD_RFNOC_ASYNC_MSG_HPP */ + //! Return the the id of src block that throw eror + uint32_t get_error_src() const + { + return sid_t(sid).get_src_endpoint(); + } +}; +}} // namespace uhd::rfnoc +#endif /* INCLUDED_UHD_RFNOC_ASYNC_MSG_HPP */ diff --git a/host/lib/include/uhdlib/rfnoc/block_container.hpp b/host/lib/include/uhdlib/rfnoc/block_container.hpp index 3c75892a4..800902d06 100644 --- a/host/lib/include/uhdlib/rfnoc/block_container.hpp +++ b/host/lib/include/uhdlib/rfnoc/block_container.hpp @@ -7,10 +7,10 @@ #ifndef INCLUDED_LIBUHD_BLOCK_CONTAINER_HPP #define INCLUDED_LIBUHD_BLOCK_CONTAINER_HPP -#include <uhd/rfnoc/noc_block_base.hpp> #include <uhd/rfnoc/block_id.hpp> -#include <boost/units/detail/utility.hpp> +#include <uhd/rfnoc/noc_block_base.hpp> #include <unordered_set> +#include <boost/units/detail/utility.hpp> #include <mutex> #include <vector> @@ -64,4 +64,3 @@ private: }}} /* namespace uhd::rfnoc::detail */ #endif /* INCLUDED_LIBUHD_BLOCK_CONTAINER_HPP */ - diff --git a/host/lib/include/uhdlib/rfnoc/chdr_ctrl_xport.hpp b/host/lib/include/uhdlib/rfnoc/chdr_ctrl_xport.hpp index d4564e935..d32ab7222 100644 --- a/host/lib/include/uhdlib/rfnoc/chdr_ctrl_xport.hpp +++ b/host/lib/include/uhdlib/rfnoc/chdr_ctrl_xport.hpp @@ -136,8 +136,8 @@ public: private: chdr_ctrl_xport(const chdr_ctrl_xport&) = delete; - void _release_cb(uhd::transport::frame_buff::uptr buff, - uhd::transport::recv_link_if* recv_link); + void _release_cb( + uhd::transport::frame_buff::uptr buff, uhd::transport::recv_link_if* recv_link); bool _ctrl_recv_cb(uhd::transport::frame_buff::uptr& buff); diff --git a/host/lib/include/uhdlib/rfnoc/chdr_packet.hpp b/host/lib/include/uhdlib/rfnoc/chdr_packet.hpp index cc729de6c..355c15da2 100644 --- a/host/lib/include/uhdlib/rfnoc/chdr_packet.hpp +++ b/host/lib/include/uhdlib/rfnoc/chdr_packet.hpp @@ -120,8 +120,8 @@ public: * \param num_mdata The number of metadata words for calculation * \return The offset of the payload in a packet with the given params */ - virtual size_t calculate_payload_offset(const packet_type_t pkt_type, - const uint8_t num_mdata = 0) const = 0; + virtual size_t calculate_payload_offset( + const packet_type_t pkt_type, const uint8_t num_mdata = 0) const = 0; //! Shortcut to return the const metadata pointer cast as a specific type template <typename data_t> diff --git a/host/lib/include/uhdlib/rfnoc/chdr_types.hpp b/host/lib/include/uhdlib/rfnoc/chdr_types.hpp index 393996c6b..25a7c8905 100644 --- a/host/lib/include/uhdlib/rfnoc/chdr_types.hpp +++ b/host/lib/include/uhdlib/rfnoc/chdr_types.hpp @@ -209,8 +209,10 @@ private: } template <typename field_t> - static inline uint64_t set_field( - const uint64_t old_val, const field_t field, const size_t offset, const size_t width) + static inline uint64_t set_field(const uint64_t old_val, + const field_t field, + const size_t offset, + const size_t width) { return (old_val & ~(mask(width) << offset)) | ((static_cast<uint64_t>(field) & mask(width)) << offset); diff --git a/host/lib/include/uhdlib/rfnoc/clock_iface.hpp b/host/lib/include/uhdlib/rfnoc/clock_iface.hpp index 06e54e67c..1a9f18bd5 100644 --- a/host/lib/include/uhdlib/rfnoc/clock_iface.hpp +++ b/host/lib/include/uhdlib/rfnoc/clock_iface.hpp @@ -11,8 +11,8 @@ #include <uhd/exception.hpp> #include <uhd/utils/log.hpp> #include <atomic> -#include <string> #include <memory> +#include <string> namespace uhd { namespace rfnoc { diff --git a/host/lib/include/uhdlib/rfnoc/ctrlport_endpoint.hpp b/host/lib/include/uhdlib/rfnoc/ctrlport_endpoint.hpp index 8f54932e5..11c456775 100644 --- a/host/lib/include/uhdlib/rfnoc/ctrlport_endpoint.hpp +++ b/host/lib/include/uhdlib/rfnoc/ctrlport_endpoint.hpp @@ -8,8 +8,8 @@ #define INCLUDED_LIBUHD_RFNOC_CTRLPORT_ENDPOINT_HPP #include <uhd/rfnoc/register_iface.hpp> -#include <uhdlib/rfnoc/clock_iface.hpp> #include <uhdlib/rfnoc/chdr_types.hpp> +#include <uhdlib/rfnoc/clock_iface.hpp> #include <memory> namespace uhd { namespace rfnoc { diff --git a/host/lib/include/uhdlib/rfnoc/device_id.hpp b/host/lib/include/uhdlib/rfnoc/device_id.hpp index d4cecc840..c86dd04df 100644 --- a/host/lib/include/uhdlib/rfnoc/device_id.hpp +++ b/host/lib/include/uhdlib/rfnoc/device_id.hpp @@ -19,4 +19,3 @@ device_id_t allocate_device_id(); }} /* namespace uhd::rfnoc */ #endif /* INCLUDED_LIBUHD_DEVICE_ID_HPP */ - diff --git a/host/lib/include/uhdlib/rfnoc/epid_allocator.hpp b/host/lib/include/uhdlib/rfnoc/epid_allocator.hpp index 8306b98a4..482cb1dac 100644 --- a/host/lib/include/uhdlib/rfnoc/epid_allocator.hpp +++ b/host/lib/include/uhdlib/rfnoc/epid_allocator.hpp @@ -43,8 +43,8 @@ public: * \param chdr_ctrl_xport The ctrl xport to use for initializing the SEP/EPID * \return The allocated EPID */ - sep_id_t allocate_epid(const sep_addr_t& addr, mgmt::mgmt_portal& mgmt_portal, - chdr_ctrl_xport& xport); + sep_id_t allocate_epid( + const sep_addr_t& addr, mgmt::mgmt_portal& mgmt_portal, chdr_ctrl_xport& xport); /*! \brief Get a pre-allocated EPID. Throws an exception is not allocated * diff --git a/host/lib/include/uhdlib/rfnoc/graph.hpp b/host/lib/include/uhdlib/rfnoc/graph.hpp index c7b06d636..e54c2fe7e 100644 --- a/host/lib/include/uhdlib/rfnoc/graph.hpp +++ b/host/lib/include/uhdlib/rfnoc/graph.hpp @@ -40,11 +40,11 @@ public: */ void connect(node_ref_t src_node, node_ref_t dst_node, graph_edge_t edge_info); - //void disconnect(node_ref_t src_node, - //node_ref_t dst_node, - //const size_t src_port, - //const size_t dst_port); - // + // void disconnect(node_ref_t src_node, + // node_ref_t dst_node, + // const size_t src_port, + // const size_t dst_port); + // /*! Commit graph and run initial checks * @@ -138,7 +138,7 @@ private: }; using ForwardEdgePredicate = ForwardBackwardEdgePredicate<true>; - using BackEdgePredicate = ForwardBackwardEdgePredicate<false>; + using BackEdgePredicate = ForwardBackwardEdgePredicate<false>; //! Vertex predicate, only selects nodes with dirty props struct DirtyNodePredicate; diff --git a/host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp b/host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp index 9251634bd..ecb90e4e9 100644 --- a/host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp +++ b/host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp @@ -72,8 +72,7 @@ public: // \param addr The physical address of the stream endpoint // \param epid The endpoint ID to assign to this endpoint // - virtual void register_endpoint( - const sep_addr_t& addr, const sep_id_t& epid) = 0; + virtual void register_endpoint(const sep_addr_t& addr, const sep_id_t& epid) = 0; //! Get information about a discovered (reachable) stream endpoint // diff --git a/host/lib/include/uhdlib/rfnoc/node_accessor.hpp b/host/lib/include/uhdlib/rfnoc/node_accessor.hpp index 517d2b517..bd4af96f4 100644 --- a/host/lib/include/uhdlib/rfnoc/node_accessor.hpp +++ b/host/lib/include/uhdlib/rfnoc/node_accessor.hpp @@ -93,7 +93,8 @@ public: * * This will call node_t::receive_action() (see that for details). */ - void send_action(node_t* node, const res_source_info& port_info, action_info::sptr action) + void send_action( + node_t* node, const res_source_info& port_info, action_info::sptr action) { node->receive_action(port_info, action); } diff --git a/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp b/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp index 4864707e1..1a78d7cab 100644 --- a/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp +++ b/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp @@ -52,16 +52,18 @@ public: * RF-specific API calls *************************************************************************/ // Setters - virtual void set_tx_antenna(const std::string &ant, const size_t chan); - virtual void set_rx_antenna(const std::string &ant, const size_t chan); + virtual void set_tx_antenna(const std::string& ant, const size_t chan); + virtual void set_rx_antenna(const std::string& ant, const size_t chan); virtual double set_tx_frequency(const double freq, const size_t chan); virtual double set_rx_frequency(const double freq, const size_t chan); virtual void set_tx_tune_args(const uhd::device_addr_t&, const size_t chan); virtual void set_rx_tune_args(const uhd::device_addr_t&, const size_t chan); virtual double set_tx_gain(const double gain, const size_t chan); - virtual double set_tx_gain(const double gain, const std::string& name, const size_t chan); + virtual double set_tx_gain( + const double gain, const std::string& name, const size_t chan); virtual double set_rx_gain(const double gain, const size_t chan); - virtual double set_rx_gain(const double gain, const std::string& name, const size_t chan); + virtual double set_rx_gain( + const double gain, const std::string& name, const size_t chan); virtual void set_rx_agc(const bool enable, const size_t chan); virtual double set_tx_bandwidth(const double bandwidth, const size_t chan); virtual double set_rx_bandwidth(const double bandwidth, const size_t chan); @@ -118,8 +120,7 @@ public: virtual std::vector<std::string> get_tx_lo_names(const size_t chan) const; virtual std::vector<std::string> get_tx_lo_sources( const std::string& name, const size_t chan); - virtual freq_range_t get_tx_lo_freq_range( - const std::string& name, const size_t chan); + virtual freq_range_t get_tx_lo_freq_range(const std::string& name, const size_t chan); virtual void set_tx_lo_source( const std::string& src, const std::string& name, const size_t chan); virtual const std::string get_tx_lo_source( @@ -147,9 +148,8 @@ public: * GPIO Controls *************************************************************************/ virtual std::vector<std::string> get_gpio_banks() const; - virtual void set_gpio_attr(const std::string& bank, - const std::string& attr, - const uint32_t value); + virtual void set_gpio_attr( + const std::string& bank, const std::string& attr, const uint32_t value); virtual uint32_t get_gpio_attr(const std::string& bank, const std::string& attr); /************************************************************************** @@ -185,16 +185,20 @@ public: * * See rfnoc_block_radio_regs.vh for details */ - struct regmap { - static const uint32_t REG_COMPAT_NUM = 0x00; // Compatibility number register offset - static const uint32_t REG_RADIO_WIDTH = 0x1000 + 0x04; // Upper 16 bits is sample width, lower 16 bits is NSPC + struct regmap + { + static const uint32_t REG_COMPAT_NUM = + 0x00; // Compatibility number register offset + static const uint32_t REG_RADIO_WIDTH = + 0x1000 + 0x04; // Upper 16 bits is sample width, lower 16 bits is NSPC static const uint32_t RADIO_BASE_ADDR = 0x1000; static const uint32_t REG_CHAN_OFFSET = 128; - static const uint32_t RADIO_ADDR_W = 7; // Address space size per radio + static const uint32_t RADIO_ADDR_W = 7; // Address space size per radio // General Radio Registers - static const uint32_t REG_LOOPBACK_EN = 0x00; // Loopback enable (connect Tx output to Rx input) + static const uint32_t REG_LOOPBACK_EN = + 0x00; // Loopback enable (connect Tx output to Rx input) // Note on the RX and TX Control Registers: These are per-channel, // which means the values here are offsets. The base address per @@ -202,35 +206,48 @@ public: // channel index. // RX Control Registers - static const uint32_t REG_RX_STATUS = 0x10; // Status of Rx radio - static const uint32_t REG_RX_CMD = 0x14; // The next radio command to execute - static const uint32_t REG_RX_CMD_NUM_WORDS_LO = 0x18; // Number of radio words for the next command (low word) - static const uint32_t REG_RX_CMD_NUM_WORDS_HI = 0x1C; // Number of radio words for the next command (high word) - static const uint32_t REG_RX_CMD_TIME_LO = 0x20; // Time for the next command (low word) - static const uint32_t REG_RX_CMD_TIME_HI = 0x24; // Time for the next command (high word) - static const uint32_t REG_RX_MAX_WORDS_PER_PKT = 0x28; // Maximum packet length to build from Rx data - static const uint32_t REG_RX_ERR_PORT = 0x2C; // Port ID for error reporting - static const uint32_t REG_RX_ERR_REM_PORT = 0x30; // Remote port ID for error reporting - static const uint32_t REG_RX_ERR_REM_EPID = 0x34; // Remote EPID (endpoint ID) for error reporting - static const uint32_t REG_RX_ERR_ADDR = 0x38; // Offset to which to write error code (ADDR+0) and time (ADDR+8) - static const uint32_t REG_RX_DATA = 0x3C; - static const uint32_t REG_RX_HAS_TIME = 0x70; // Set to one if radio output packets should have timestamps + static const uint32_t REG_RX_STATUS = 0x10; // Status of Rx radio + static const uint32_t REG_RX_CMD = 0x14; // The next radio command to execute + static const uint32_t REG_RX_CMD_NUM_WORDS_LO = + 0x18; // Number of radio words for the next command (low word) + static const uint32_t REG_RX_CMD_NUM_WORDS_HI = + 0x1C; // Number of radio words for the next command (high word) + static const uint32_t REG_RX_CMD_TIME_LO = + 0x20; // Time for the next command (low word) + static const uint32_t REG_RX_CMD_TIME_HI = + 0x24; // Time for the next command (high word) + static const uint32_t REG_RX_MAX_WORDS_PER_PKT = + 0x28; // Maximum packet length to build from Rx data + static const uint32_t REG_RX_ERR_PORT = 0x2C; // Port ID for error reporting + static const uint32_t REG_RX_ERR_REM_PORT = + 0x30; // Remote port ID for error reporting + static const uint32_t REG_RX_ERR_REM_EPID = + 0x34; // Remote EPID (endpoint ID) for error reporting + static const uint32_t REG_RX_ERR_ADDR = + 0x38; // Offset to which to write error code (ADDR+0) and time (ADDR+8) + static const uint32_t REG_RX_DATA = 0x3C; + static const uint32_t REG_RX_HAS_TIME = + 0x70; // Set to one if radio output packets should have timestamps // TX Control Registers - static const uint32_t REG_TX_IDLE_VALUE = 0x40; // Value to output when transmitter is idle + static const uint32_t REG_TX_IDLE_VALUE = + 0x40; // Value to output when transmitter is idle static const uint32_t REG_TX_ERROR_POLICY = 0x44; // Tx error policy static const uint32_t REG_TX_ERR_PORT = 0x48; // Port ID for error reporting - static const uint32_t REG_TX_ERR_REM_PORT = 0x4C; // Remote port ID for error reporting - static const uint32_t REG_TX_ERR_REM_EPID = 0x50; // Remote EPID (endpoint ID) for error reporting - static const uint32_t REG_TX_ERR_ADDR = 0x54; // Offset to which to write error code (ADDR+0) and time (ADDR+8) - - static const uint32_t RX_CMD_STOP = 0; // Stop acquiring at end of next packet - static const uint32_t RX_CMD_FINITE = 1; // Acquire NUM_SAMPS then stop + static const uint32_t REG_TX_ERR_REM_PORT = + 0x4C; // Remote port ID for error reporting + static const uint32_t REG_TX_ERR_REM_EPID = + 0x50; // Remote EPID (endpoint ID) for error reporting + static const uint32_t REG_TX_ERR_ADDR = + 0x54; // Offset to which to write error code (ADDR+0) and time (ADDR+8) + + static const uint32_t RX_CMD_STOP = 0; // Stop acquiring at end of next packet + static const uint32_t RX_CMD_FINITE = 1; // Acquire NUM_SAMPS then stop static const uint32_t RX_CMD_CONTINUOUS = 2; // Acquire until stopped static const uint32_t RX_CMD_TIMED_POS = 31; - static const uint32_t PERIPH_BASE = 0x80000; + static const uint32_t PERIPH_BASE = 0x80000; static const uint32_t PERIPH_REG_OFFSET = 8; static const uint32_t SWREG_TX_ERR = 0x0000; diff --git a/host/lib/include/uhdlib/rfnoc/reg_iface_adapter.hpp b/host/lib/include/uhdlib/rfnoc/reg_iface_adapter.hpp index 9a5dd39f4..f0eb78be4 100644 --- a/host/lib/include/uhdlib/rfnoc/reg_iface_adapter.hpp +++ b/host/lib/include/uhdlib/rfnoc/reg_iface_adapter.hpp @@ -13,12 +13,11 @@ #include <memory> //! Convenience macro to generate a reg_iface_adapter from within an RFNoC block -#define RFNOC_MAKE_WB_IFACE(BASE_OFFSET, CHAN) \ - std::make_shared<reg_iface_adapter>( \ - [this]() -> register_iface& { return regs(); }, \ - [this, chan = CHAN]() { return get_command_time(chan); }, \ - [this, chan = CHAN]( \ - const uhd::time_spec_t& time) { set_command_time(time, chan); }, \ +#define RFNOC_MAKE_WB_IFACE(BASE_OFFSET, CHAN) \ + std::make_shared<reg_iface_adapter>([this]() -> register_iface& { return regs(); }, \ + [this, chan = CHAN]() { return get_command_time(chan); }, \ + [this, chan = CHAN]( \ + const uhd::time_spec_t& time) { set_command_time(time, chan); }, \ BASE_OFFSET) namespace uhd { namespace rfnoc { @@ -39,7 +38,7 @@ class UHD_API reg_iface_adapter : public uhd::timed_wb_iface public: using regs_accessor_t = std::function<register_iface&(void)>; using time_accessor_t = std::function<uhd::time_spec_t(void)>; - using time_setter_t = std::function<void(const uhd::time_spec_t&)>; + using time_setter_t = std::function<void(const uhd::time_spec_t&)>; /*! * \param regs_accessor Function object to retrieve the register_iface diff --git a/host/lib/include/uhdlib/rfnoc/rpc_block_ctrl.hpp b/host/lib/include/uhdlib/rfnoc/rpc_block_ctrl.hpp index 91091d8c2..5125aef84 100644 --- a/host/lib/include/uhdlib/rfnoc/rpc_block_ctrl.hpp +++ b/host/lib/include/uhdlib/rfnoc/rpc_block_ctrl.hpp @@ -10,8 +10,7 @@ #include <uhd/types/device_addr.hpp> #include <uhdlib/utils/rpc.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! Abstraction for RPC client * @@ -30,12 +29,9 @@ public: * \param block_args Additional block arguments */ virtual void set_rpc_client( - uhd::rpc_client::sptr rpcc, - const uhd::device_addr_t &block_args - ) = 0; - + uhd::rpc_client::sptr rpcc, const uhd::device_addr_t& block_args) = 0; }; -}} +}} // namespace uhd::rfnoc #endif /* INCLUDED_LIBUHD_RFNOC_RPC_BLOCK_CTRL_HPP */ diff --git a/host/lib/include/uhdlib/transport/dpdk_io_service_client.hpp b/host/lib/include/uhdlib/transport/dpdk_io_service_client.hpp index d994fe376..300ca00b5 100644 --- a/host/lib/include/uhdlib/transport/dpdk_io_service_client.hpp +++ b/host/lib/include/uhdlib/transport/dpdk_io_service_client.hpp @@ -145,7 +145,8 @@ public: // first dequeue operation fails, even though we push onto it before // setting complete to true. Retrying successfully dequeues a value // in those cases. - while (rte_ring_dequeue(_buffer_queue, (void**)&buff_ptr)) {} + while (rte_ring_dequeue(_buffer_queue, (void**)&buff_ptr)) { + } } return frame_buff::uptr(buff_ptr); } @@ -200,7 +201,8 @@ public: size_t queue_size = (size_t)exp2(ceil(log2(num_recv_frames + 1))); dpdk::port_id_t nic_port = link->get_port()->get_port_id(); uint16_t id = io_srv->_get_unique_client_id(); - UHD_LOG_DEBUG("DPDK::IO_SERVICE", "Creating recv client with queue size of " << queue_size); + UHD_LOG_DEBUG( + "DPDK::IO_SERVICE", "Creating recv client with queue size of " << queue_size); char name[16]; snprintf(name, sizeof(name), "rx%hu-%hu", nic_port, id); _recv_queue = rte_ring_create( @@ -255,7 +257,8 @@ public: // first dequeue operation fails, even though we push onto it before // setting complete to true. Retrying successfully dequeues a value // in those cases. - while (rte_ring_dequeue(_recv_queue, (void**)&buff_ptr)) {} + while (rte_ring_dequeue(_recv_queue, (void**)&buff_ptr)) { + } } return frame_buff::uptr(buff_ptr); } diff --git a/host/lib/include/uhdlib/transport/liberio_link.hpp b/host/lib/include/uhdlib/transport/liberio_link.hpp index 8ab90976a..6cd550572 100644 --- a/host/lib/include/uhdlib/transport/liberio_link.hpp +++ b/host/lib/include/uhdlib/transport/liberio_link.hpp @@ -44,8 +44,7 @@ public: liberio_chan_put(_chan); } - liberio_frame_buff(const liberio_frame_buff& src) - : liberio_frame_buff(src._chan) {} + liberio_frame_buff(const liberio_frame_buff& src) : liberio_frame_buff(src._chan) {} UHD_FORCE_INLINE size_t get(int32_t timeout_ms) { @@ -55,7 +54,7 @@ public: return 0; } _packet_size = liberio_buf_get_len(_buff, 0); - _data = liberio_buf_get_mem(_buff, 0); + _data = liberio_buf_get_mem(_buff, 0); return _packet_size; } @@ -67,6 +66,7 @@ public: _buff = nullptr; _data = nullptr; } + private: struct liberio_buf* _buff = nullptr; struct liberio_chan* _chan; @@ -75,7 +75,7 @@ private: class liberio_adapter_info : public adapter_info { public: - liberio_adapter_info() = default; + liberio_adapter_info() = default; ~liberio_adapter_info() = default; std::string to_string() @@ -102,8 +102,9 @@ class liberio_link : public recv_link_base<liberio_link>, public: using sptr = std::shared_ptr<liberio_link>; - liberio_link( - const std::string& tx_path, const std::string& rx_path, const link_params_t& params); + liberio_link(const std::string& tx_path, + const std::string& rx_path, + const link_params_t& params); ~liberio_link(); diff --git a/host/lib/include/uhdlib/transport/rx_streamer_impl.hpp b/host/lib/include/uhdlib/transport/rx_streamer_impl.hpp index 04cd12c59..491a5ab98 100644 --- a/host/lib/include/uhdlib/transport/rx_streamer_impl.hpp +++ b/host/lib/include/uhdlib/transport/rx_streamer_impl.hpp @@ -75,8 +75,7 @@ class rx_streamer_impl : public rx_streamer public: //! Constructor rx_streamer_impl(const size_t num_ports, const uhd::stream_args_t stream_args) - : _zero_copy_streamer(num_ports) - , _in_buffs(num_ports) + : _zero_copy_streamer(num_ports), _in_buffs(num_ports) { if (stream_args.cpu_format.empty()) { throw uhd::value_error("[rx_stream] Must provide a cpu_format!"); @@ -95,7 +94,8 @@ public: } //! Connect a new channel to the streamer - // FIXME: Needs some way to handle virtual channels, since xport could be shared among them + // FIXME: Needs some way to handle virtual channels, since xport could be shared among + // them virtual void connect_channel(const size_t channel, typename transport_t::uptr xport) { const size_t mtu = xport->get_max_payload_size(); @@ -144,8 +144,8 @@ public: size_t total_samps_recv = _recv_one_packet(buffs, nsamps_per_buff, metadata, eov_positions, timeout_ms); - if (one_packet or metadata.end_of_burst or - (eov_positions.data() and eov_positions.remaining() == 0)) { + if (one_packet or metadata.end_of_burst + or (eov_positions.data() and eov_positions.remaining() == 0)) { return total_samps_recv; } @@ -260,9 +260,8 @@ private: { if (_buff_samps_remaining == 0) { // Current set of buffers has expired, get the next one - _buff_samps_remaining = - _zero_copy_streamer.get_recv_buffs( - _in_buffs, metadata, eov_positions, timeout_ms); + _buff_samps_remaining = _zero_copy_streamer.get_recv_buffs( + _in_buffs, metadata, eov_positions, timeout_ms); _fragment_offset_in_samps = 0; } else { // There are samples still left in the current set of buffers @@ -309,8 +308,7 @@ private: _converters[chan]->conv(buffer_ptr, out_buffs, num_samps); // Advance the pointer for the source buffer - _in_buffs[chan] = - buffer_ptr + num_samps * _convert_info.bytes_per_otw_item; + _in_buffs[chan] = buffer_ptr + num_samps * _convert_info.bytes_per_otw_item; if (_buff_samps_remaining == num_samps) { _zero_copy_streamer.release_recv_buff(chan); @@ -318,8 +316,7 @@ private: } //! Create converters and initialize _convert_info - void _setup_converters(const size_t num_ports, - const uhd::stream_args_t stream_args) + void _setup_converters(const size_t num_ports, const uhd::stream_args_t stream_args) { // Note to code archaeologists: In the past, we had to also specify the // endianness here, but that is no longer necessary because we can make diff --git a/host/lib/include/uhdlib/transport/rx_streamer_zero_copy.hpp b/host/lib/include/uhdlib/transport/rx_streamer_zero_copy.hpp index 98588c6f5..86f13f28d 100644 --- a/host/lib/include/uhdlib/transport/rx_streamer_zero_copy.hpp +++ b/host/lib/include/uhdlib/transport/rx_streamer_zero_copy.hpp @@ -35,8 +35,8 @@ public: ~eov_data_wrapper() { - _metadata.eov_positions = _data; - _metadata.eov_positions_size = _size; + _metadata.eov_positions = _data; + _metadata.eov_positions_size = _size; _metadata.eov_positions_count = _write_pos; } @@ -69,14 +69,14 @@ public: private: uhd::rx_metadata_t& _metadata; - size_t* _data; - size_t _size; - size_t _remaining; - size_t _write_pos; - size_t _running_sample_count; + size_t* _data; + size_t _size; + size_t _remaining; + size_t _write_pos; + size_t _running_sample_count; }; -} // namespace uhd::transport::detail +} // namespace detail /*! * Implementation of rx streamer manipulation of frame buffers and packet info. @@ -269,9 +269,8 @@ public: // channel 0 is checked for eov--in most cases, it should be the // same for all channels. if (eov_positions.data() && eov) { - eov_positions.push_back( - eov_positions.get_running_sample_count() + - info_0.payload_bytes / _bytes_per_item); + eov_positions.push_back(eov_positions.get_running_sample_count() + + info_0.payload_bytes / _bytes_per_item); } // Done with these packets, save timestamp info for next call diff --git a/host/lib/include/uhdlib/transport/tx_streamer_impl.hpp b/host/lib/include/uhdlib/transport/tx_streamer_impl.hpp index d6555ad35..c1cc3156f 100644 --- a/host/lib/include/uhdlib/transport/tx_streamer_impl.hpp +++ b/host/lib/include/uhdlib/transport/tx_streamer_impl.hpp @@ -90,9 +90,9 @@ public: private: size_t* _eov_positions; - size_t _eov_positions_size; - size_t _remaining; - size_t _read_pos; + size_t _eov_positions_size; + size_t _remaining; + size_t _read_pos; }; } // namespace detail diff --git a/host/lib/include/uhdlib/transport/udp_boost_asio_link.hpp b/host/lib/include/uhdlib/transport/udp_boost_asio_link.hpp index 88ad6e518..6b350e997 100644 --- a/host/lib/include/uhdlib/transport/udp_boost_asio_link.hpp +++ b/host/lib/include/uhdlib/transport/udp_boost_asio_link.hpp @@ -33,7 +33,9 @@ class udp_boost_asio_adapter_info : public adapter_info { public: udp_boost_asio_adapter_info(boost::asio::ip::udp::socket& s) - : _src_ip(s.local_endpoint().address()) {} + : _src_ip(s.local_endpoint().address()) + { + } ~udp_boost_asio_adapter_info() {} diff --git a/host/lib/include/uhdlib/transport/udp_common.hpp b/host/lib/include/uhdlib/transport/udp_common.hpp index e17deff9e..6deb265d4 100644 --- a/host/lib/include/uhdlib/transport/udp_common.hpp +++ b/host/lib/include/uhdlib/transport/udp_common.hpp @@ -132,7 +132,8 @@ UHD_INLINE void send_udp_packet(int sock_fd, void* mem, size_t len) // This is known to occur at least on some OSX systems. // But it should be safe to always check for the error. while (true) { - const ssize_t ret = uhd::narrow_cast<ssize_t>(::send(sock_fd, (const char*)mem, len, 0)); + const ssize_t ret = + uhd::narrow_cast<ssize_t>(::send(sock_fd, (const char*)mem, len, 0)); if (ret == ssize_t(len)) break; if (ret == -1 and errno == ENOBUFS) { diff --git a/host/lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp b/host/lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp index f30694dbf..c059a3a09 100644 --- a/host/lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp +++ b/host/lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp @@ -45,27 +45,23 @@ public: virtual ~ad9361_ctrl(void) {} //! make a new codec control object - static sptr make_spi( - ad9361_params::sptr client_settings, + static sptr make_spi(ad9361_params::sptr client_settings, uhd::spi_iface::sptr spi_iface, - uint32_t slave_num - ); + uint32_t slave_num); static sptr make_spi( - ad9361_params::sptr client_settings, - ad9361_io::sptr spi_io_iface - ); + ad9361_params::sptr client_settings, ad9361_io::sptr spi_io_iface); //! Get a list of gain names for RX or TX - static std::vector<std::string> get_gain_names(const std::string &/*which*/) + static std::vector<std::string> get_gain_names(const std::string& /*which*/) { return std::vector<std::string>(1, "PGA"); } //! get the gain range for a particular gain element - static uhd::meta_range_t get_gain_range(const std::string &which) + static uhd::meta_range_t get_gain_range(const std::string& which) { - if(which[0] == 'R') { + if (which[0] == 'R') { return uhd::meta_range_t(0.0, 76.0, 1.0); } else { return uhd::meta_range_t(0.0, 89.75, 0.25); @@ -81,29 +77,28 @@ public: //! get the filter range for the frontend which static uhd::meta_range_t get_bw_filter_range(void) { - return uhd::meta_range_t(ad9361_device_t::AD9361_MIN_BW, ad9361_device_t::AD9361_MAX_BW); + return uhd::meta_range_t( + ad9361_device_t::AD9361_MIN_BW, ad9361_device_t::AD9361_MAX_BW); } //! get the clock rate range for the frontend static uhd::meta_range_t get_clock_rate_range(void) { - return uhd::meta_range_t( - ad9361_device_t::AD9361_MIN_CLOCK_RATE, - ad9361_device_t::AD9361_MAX_CLOCK_RATE - ); + return uhd::meta_range_t(ad9361_device_t::AD9361_MIN_CLOCK_RATE, + ad9361_device_t::AD9361_MAX_CLOCK_RATE); } //! set the filter bandwidth for the frontend's analog low pass - virtual double set_bw_filter(const std::string &/*which*/, const double /*bw*/) = 0; + virtual double set_bw_filter(const std::string& /*which*/, const double /*bw*/) = 0; //! set the gain for a particular gain element - virtual double set_gain(const std::string &which, const double value) = 0; + virtual double set_gain(const std::string& which, const double value) = 0; //! Enable or disable the AGC module - virtual void set_agc(const std::string &which, bool enable) = 0; + virtual void set_agc(const std::string& which, bool enable) = 0; //! configure the AGC module to slow or fast mode - virtual void set_agc_mode(const std::string &which, const std::string &mode) = 0; + virtual void set_agc_mode(const std::string& which, const std::string& mode) = 0; //! set a new clock rate, return the exact value virtual double set_clock_rate(const double rate) = 0; @@ -112,55 +107,60 @@ public: virtual void set_active_chains(bool tx1, bool tx2, bool rx1, bool rx2) = 0; //! set which timing mode is used - virtual void set_timing_mode(const std::string &timing_mode) = 0; + virtual void set_timing_mode(const std::string& timing_mode) = 0; //! tune the given frontend, return the exact value - virtual double tune(const std::string &which, const double value) = 0; + virtual double tune(const std::string& which, const double value) = 0; //! set the DC offset for I and Q manually - void set_dc_offset(const std::string &, const std::complex<double>) + void set_dc_offset(const std::string&, const std::complex<double>) { - //This feature should not be used according to Analog Devices - throw uhd::runtime_error("ad9361_ctrl::set_dc_offset this feature is not supported on this device."); + // This feature should not be used according to Analog Devices + throw uhd::runtime_error( + "ad9361_ctrl::set_dc_offset this feature is not supported on this device."); } //! enable or disable the BB/RF DC tracking feature - virtual void set_dc_offset_auto(const std::string &which, const bool on) = 0; + virtual void set_dc_offset_auto(const std::string& which, const bool on) = 0; //! set the IQ correction value manually - void set_iq_balance(const std::string &, const std::complex<double>) + void set_iq_balance(const std::string&, const std::complex<double>) { - //This feature should not be used according to Analog Devices - throw uhd::runtime_error("ad9361_ctrl::set_iq_balance this feature is not supported on this device."); + // This feature should not be used according to Analog Devices + throw uhd::runtime_error( + "ad9361_ctrl::set_iq_balance this feature is not supported on this device."); } //! enable or disable the quadrature calibration - virtual void set_iq_balance_auto(const std::string &which, const bool on) = 0; + virtual void set_iq_balance_auto(const std::string& which, const bool on) = 0; //! get the current frequency for the given frontend - virtual double get_freq(const std::string &which) = 0; + virtual double get_freq(const std::string& which) = 0; //! turn on/off Catalina's data port loopback virtual void data_port_loopback(const bool on) = 0; //! read internal RSSI sensor - virtual sensor_value_t get_rssi(const std::string &which) = 0; + virtual sensor_value_t get_rssi(const std::string& which) = 0; //! read the internal temp sensor virtual sensor_value_t get_temperature() = 0; //! List all available filters by name - virtual std::vector<std::string> get_filter_names(const std::string &which) = 0; + virtual std::vector<std::string> get_filter_names(const std::string& which) = 0; //! Return a list of all filters - virtual filter_info_base::sptr get_filter(const std::string &which, const std::string &filter_name) = 0; + virtual filter_info_base::sptr get_filter( + const std::string& which, const std::string& filter_name) = 0; //! Write back a filter - virtual void set_filter(const std::string &which, const std::string &filter_name, const filter_info_base::sptr) = 0; + virtual void set_filter(const std::string& which, + const std::string& filter_name, + const filter_info_base::sptr) = 0; virtual void output_digital_test_tone(bool enb) = 0; }; -}} +}} // namespace uhd::usrp #endif /* INCLUDED_AD9361_CTRL_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/ad936x_manager.hpp b/host/lib/include/uhdlib/usrp/common/ad936x_manager.hpp index 2d21d55e7..d65983c72 100644 --- a/host/lib/include/uhdlib/usrp/common/ad936x_manager.hpp +++ b/host/lib/include/uhdlib/usrp/common/ad936x_manager.hpp @@ -8,15 +8,15 @@ #ifndef INCLUDED_AD9361_MANAGER_HPP #define INCLUDED_AD9361_MANAGER_HPP -#include <uhd/types/wb_iface.hpp> -#include <uhd/utils/math.hpp> #include <uhd/property_tree.hpp> #include <uhd/types/direction.hpp> +#include <uhd/types/wb_iface.hpp> +#include <uhd/utils/math.hpp> #include <uhdlib/usrp/common/ad9361_ctrl.hpp> -#include <boost/format.hpp> -#include <memory> #include <stdint.h> +#include <boost/format.hpp> #include <functional> +#include <memory> namespace uhd { namespace usrp { @@ -45,12 +45,9 @@ public: * \param codec_ctrl The actual AD936x control object * \param n_frontends Number of frontends (1 or 2) */ - static sptr make( - const ad9361_ctrl::sptr &codec_ctrl, - const size_t n_frontends - ); + static sptr make(const ad9361_ctrl::sptr& codec_ctrl, const size_t n_frontends); - virtual ~ad936x_manager(void) {}; + virtual ~ad936x_manager(void){}; /*! Put the AD936x into a default state. * @@ -67,14 +64,13 @@ public: * * \param iface An interface to the associated radio control core * \param iface The radio control core's address to write the loopback value - * \param iface The radio control core's readback address to read back the returned value + * \param iface The radio control core's readback address to read back the returned + * value * * \throws a uhd::runtime_error if the loopback value didn't match. */ - virtual void loopback_self_test( - std::function<void(uint32_t)> poker_functor, - std::function<uint64_t()> peeker_functor - ) = 0; + virtual void loopback_self_test(std::function<void(uint32_t)> poker_functor, + std::function<uint64_t()> peeker_functor) = 0; /*! Determine a tick rate that will work with a given sampling rate * (assuming a DDC/DUC chain is also available elsewhere). @@ -97,10 +93,7 @@ public: * \returns a valid tick rate that can be used with the given rate * \throws a uhd::value_error if \p lcm_rate exceeds the max tick rate */ - virtual double get_auto_tick_rate( - const double lcm_rate, - size_t num_chans - ) = 0; + virtual double get_auto_tick_rate(const double lcm_rate, size_t num_chans) = 0; /*! Check if a given sampling rate is within the available analog bandwidth. * @@ -110,11 +103,9 @@ public: /*! Populate the property tree for the device frontend */ - virtual void populate_frontend_subtree( - uhd::property_tree::sptr subtree, - const std::string &key, - uhd::direction_t dir - ) = 0; + virtual void populate_frontend_subtree(uhd::property_tree::sptr subtree, + const std::string& key, + uhd::direction_t dir) = 0; }; /* class ad936x_manager */ diff --git a/host/lib/include/uhdlib/usrp/common/adf4001_ctrl.hpp b/host/lib/include/uhdlib/usrp/common/adf4001_ctrl.hpp index 8aa449539..0c1b06458 100644 --- a/host/lib/include/uhdlib/usrp/common/adf4001_ctrl.hpp +++ b/host/lib/include/uhdlib/usrp/common/adf4001_ctrl.hpp @@ -15,28 +15,28 @@ #include <uhd/types/serial.hpp> #include <uhdlib/usrp/cores/spi_core_3000.hpp> -#include <boost/thread/thread.hpp> #include <stdint.h> +#include <boost/thread/thread.hpp> namespace uhd { namespace usrp { -class adf4001_regs_t { +class adf4001_regs_t +{ public: - /* Function prototypes */ uint32_t get_reg(uint8_t addr); adf4001_regs_t(void); /* Register values / addresses */ - uint16_t ref_counter; //14 bits - uint16_t n; //13 bits - uint8_t charge_pump_current_1; //3 bits - uint8_t charge_pump_current_2; //3 bits + uint16_t ref_counter; // 14 bits + uint16_t n; // 13 bits + uint8_t charge_pump_current_1; // 3 bits + uint8_t charge_pump_current_2; // 3 bits enum anti_backlash_width_t { - ANTI_BACKLASH_WIDTH_2_9NS = 0, - ANTI_BACKLASH_WIDTH_1_3NS = 1, - ANTI_BACKLASH_WIDTH_6_0NS = 2, + ANTI_BACKLASH_WIDTH_2_9NS = 0, + ANTI_BACKLASH_WIDTH_1_3NS = 1, + ANTI_BACKLASH_WIDTH_6_0NS = 2, ANTI_BACKLASH_WIDTH_2_9NS_WAT = 3 }; anti_backlash_width_t anti_backlash_width; @@ -46,31 +46,25 @@ public: LOCK_DETECT_PRECISION_5CYC = 1 }; lock_detect_precision_t lock_detect_precision; - enum charge_pump_gain_t { - CHARGE_PUMP_GAIN_1 = 0, - CHARGE_PUMP_GAIN_2 = 1 - }; + enum charge_pump_gain_t { CHARGE_PUMP_GAIN_1 = 0, CHARGE_PUMP_GAIN_2 = 1 }; charge_pump_gain_t charge_pump_gain; - enum counter_reset_t { - COUNTER_RESET_NORMAL = 0, - COUNTER_RESET_RESET = 1 - }; - counter_reset_t counter_reset; + enum counter_reset_t { COUNTER_RESET_NORMAL = 0, COUNTER_RESET_RESET = 1 }; + counter_reset_t counter_reset; enum power_down_t { POWER_DOWN_NORMAL = 0, - POWER_DOWN_ASYNC = 1, - POWER_DOWN_SYNC = 3 + POWER_DOWN_ASYNC = 1, + POWER_DOWN_SYNC = 3 }; power_down_t power_down; enum muxout_t { MUXOUT_TRISTATE_OUT = 0, - MUXOUT_DLD = 1, - MUXOUT_NDIV = 2, - MUXOUT_AVDD = 3, - MUXOUT_RDIV = 4, - MUXOUT_NCH_OD_ALD = 5, - MUXOUT_SDO = 6, - MUXOUT_GND = 7 + MUXOUT_DLD = 1, + MUXOUT_NDIV = 2, + MUXOUT_AVDD = 3, + MUXOUT_RDIV = 4, + MUXOUT_NCH_OD_ALD = 5, + MUXOUT_SDO = 6, + MUXOUT_GND = 7 }; muxout_t muxout; enum phase_detector_polarity_t { @@ -78,20 +72,17 @@ public: PHASE_DETECTOR_POLARITY_POSITIVE = 1 }; phase_detector_polarity_t phase_detector_polarity; - enum charge_pump_mode_t { - CHARGE_PUMP_NORMAL = 0, - CHARGE_PUMP_TRISTATE = 1 - }; + enum charge_pump_mode_t { CHARGE_PUMP_NORMAL = 0, CHARGE_PUMP_TRISTATE = 1 }; charge_pump_mode_t charge_pump_mode; enum fastlock_mode_t { FASTLOCK_MODE_DISABLED = 0, - FASTLOCK_MODE_1 = 1, - FASTLOCK_MODE_2 = 2 + FASTLOCK_MODE_1 = 1, + FASTLOCK_MODE_2 = 2 }; fastlock_mode_t fastlock_mode; enum timer_counter_control_t { - TIMEOUT_3CYC = 0, - TIMEOUT_7CYC = 1, + TIMEOUT_3CYC = 0, + TIMEOUT_7CYC = 1, TIMEOUT_11CYC = 2, TIMEOUT_15CYC = 3, TIMEOUT_19CYC = 4, @@ -111,7 +102,8 @@ public: }; -class adf4001_ctrl { +class adf4001_ctrl +{ public: adf4001_ctrl(uhd::spi_iface::sptr _spi, int slaveno); virtual void set_lock_to_ext_ref(bool external); @@ -126,6 +118,6 @@ private: void write_reg(uint8_t addr); }; -}} +}} // namespace uhd::usrp #endif diff --git a/host/lib/include/uhdlib/usrp/common/adf435x.hpp b/host/lib/include/uhdlib/usrp/common/adf435x.hpp index 7989420dd..e805f9754 100644 --- a/host/lib/include/uhdlib/usrp/common/adf435x.hpp +++ b/host/lib/include/uhdlib/usrp/common/adf435x.hpp @@ -17,9 +17,9 @@ #include <uhd/utils/log.hpp> #include <uhdlib/utils/math.hpp> #include <uhdlib/utils/narrow.hpp> -#include <functional> #include <boost/math/special_functions/round.hpp> #include <boost/thread.hpp> +#include <functional> #include <vector> class adf435x_iface diff --git a/host/lib/include/uhdlib/usrp/common/adf535x.hpp b/host/lib/include/uhdlib/usrp/common/adf535x.hpp index 6af8556be..65e552844 100644 --- a/host/lib/include/uhdlib/usrp/common/adf535x.hpp +++ b/host/lib/include/uhdlib/usrp/common/adf535x.hpp @@ -17,8 +17,8 @@ #include <uhdlib/utils/narrow.hpp> #include <stdint.h> #include <boost/format.hpp> -#include <functional> #include <algorithm> +#include <functional> #include <iomanip> #include <utility> #include <vector> diff --git a/host/lib/include/uhdlib/usrp/common/apply_corrections.hpp b/host/lib/include/uhdlib/usrp/common/apply_corrections.hpp index fca566493..dffefffea 100644 --- a/host/lib/include/uhdlib/usrp/common/apply_corrections.hpp +++ b/host/lib/include/uhdlib/usrp/common/apply_corrections.hpp @@ -12,7 +12,7 @@ #include <uhd/property_tree.hpp> #include <string> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { void apply_tx_fe_corrections(property_tree::sptr sub_tree, // starts at mboards/x const std::string& db_serial, @@ -34,6 +34,6 @@ void apply_rx_fe_corrections(property_tree::sptr sub_tree, // starts at mboards/ const fs_path rx_fe_corr_path, const double rx_lo_freq // actual lo freq ); -}} //namespace uhd::usrp +}} // namespace uhd::usrp #endif /* INCLUDED_LIBUHD_USRP_COMMON_APPLY_CORRECTIONS_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/async_packet_handler.hpp b/host/lib/include/uhdlib/usrp/common/async_packet_handler.hpp index de9d17001..957afe7c1 100644 --- a/host/lib/include/uhdlib/usrp/common/async_packet_handler.hpp +++ b/host/lib/include/uhdlib/usrp/common/async_packet_handler.hpp @@ -14,61 +14,52 @@ #include <uhd/utils/byteswap.hpp> #include <uhd/utils/log.hpp> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { - template <typename to_host_type> - void load_metadata_from_buff( - const to_host_type &to_host, - async_metadata_t &metadata, - const transport::vrt::if_packet_info_t &if_packet_info, - const uint32_t *vrt_hdr, - const double tick_rate, - const size_t channel = 0 - ){ - const uint32_t *payload = vrt_hdr + if_packet_info.num_header_words32; +template <typename to_host_type> +void load_metadata_from_buff(const to_host_type& to_host, + async_metadata_t& metadata, + const transport::vrt::if_packet_info_t& if_packet_info, + const uint32_t* vrt_hdr, + const double tick_rate, + const size_t channel = 0) +{ + const uint32_t* payload = vrt_hdr + if_packet_info.num_header_words32; - //load into metadata - metadata.channel = channel; - metadata.has_time_spec = if_packet_info.has_tsf; - if (tick_rate == 0.0) { - metadata.time_spec = 0.0; - } else { - metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate); - } - metadata.event_code = async_metadata_t::event_code_t(to_host(payload[0]) & 0xff); + // load into metadata + metadata.channel = channel; + metadata.has_time_spec = if_packet_info.has_tsf; + if (tick_rate == 0.0) { + metadata.time_spec = 0.0; + } else { + metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate); + } + metadata.event_code = async_metadata_t::event_code_t(to_host(payload[0]) & 0xff); - //load user payload - for (size_t i = 1; i < if_packet_info.num_payload_words32; i++){ - if (i-1 == 4) break; //limit of 4 words32 - metadata.user_payload[i-1] = to_host(payload[i]); - } + // load user payload + for (size_t i = 1; i < if_packet_info.num_payload_words32; i++) { + if (i - 1 == 4) + break; // limit of 4 words32 + metadata.user_payload[i - 1] = to_host(payload[i]); } +} - UHD_INLINE void standard_async_msg_prints(const async_metadata_t &metadata) - { - if (metadata.event_code & - ( async_metadata_t::EVENT_CODE_UNDERFLOW - | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET) - ) - { - UHD_LOG_FASTPATH("U") - } - else if (metadata.event_code & - ( async_metadata_t::EVENT_CODE_SEQ_ERROR - | async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST) - ) - { - UHD_LOG_FASTPATH("S") - } - else if (metadata.event_code & - async_metadata_t::EVENT_CODE_TIME_ERROR - ) - { - UHD_LOG_FASTPATH("L") - } +UHD_INLINE void standard_async_msg_prints(const async_metadata_t& metadata) +{ + if (metadata.event_code + & (async_metadata_t::EVENT_CODE_UNDERFLOW + | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET)) { + UHD_LOG_FASTPATH("U") + } else if (metadata.event_code + & (async_metadata_t::EVENT_CODE_SEQ_ERROR + | async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST)) { + UHD_LOG_FASTPATH("S") + } else if (metadata.event_code & async_metadata_t::EVENT_CODE_TIME_ERROR) { + UHD_LOG_FASTPATH("L") } +} -}} //namespace uhd::usrp +}} // namespace uhd::usrp #endif /* INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/fx2_ctrl.hpp b/host/lib/include/uhdlib/usrp/common/fx2_ctrl.hpp index 8579787f4..23498c96e 100644 --- a/host/lib/include/uhdlib/usrp/common/fx2_ctrl.hpp +++ b/host/lib/include/uhdlib/usrp/common/fx2_ctrl.hpp @@ -13,26 +13,27 @@ #include <uhd/utils/noncopyable.hpp> #include <memory> -#define FL_BEGIN 0 -#define FL_END 2 -#define FL_XFER 1 -#define USRP_HASH_SLOT_0_ADDR 0xe1e0 -#define USRP_HASH_SLOT_1_ADDR 0xe1f0 -#define VRQ_FPGA_LOAD 0x02 -#define VRQ_FPGA_SET_RESET 0x04 +#define FL_BEGIN 0 +#define FL_END 2 +#define FL_XFER 1 +#define USRP_HASH_SLOT_0_ADDR 0xe1e0 +#define USRP_HASH_SLOT_1_ADDR 0xe1f0 +#define VRQ_FPGA_LOAD 0x02 +#define VRQ_FPGA_SET_RESET 0x04 #define VRQ_FPGA_SET_TX_ENABLE 0x05 #define VRQ_FPGA_SET_RX_ENABLE 0x06 -#define VRQ_FPGA_SET_TX_RESET 0x0a -#define VRQ_FPGA_SET_RX_RESET 0x0b -#define VRQ_I2C_READ 0x81 -#define VRQ_I2C_WRITE 0x08 -#define VRQ_SET_LED 0x01 -#define VRT_VENDOR_IN 0xC0 -#define VRT_VENDOR_OUT 0x40 - -namespace uhd{ namespace usrp{ - -class fx2_ctrl : uhd::noncopyable, public uhd::i2c_iface{ +#define VRQ_FPGA_SET_TX_RESET 0x0a +#define VRQ_FPGA_SET_RX_RESET 0x0b +#define VRQ_I2C_READ 0x81 +#define VRQ_I2C_WRITE 0x08 +#define VRQ_SET_LED 0x01 +#define VRT_VENDOR_IN 0xC0 +#define VRT_VENDOR_OUT 0x40 + +namespace uhd { namespace usrp { + +class fx2_ctrl : uhd::noncopyable, public uhd::i2c_iface +{ public: typedef std::shared_ptr<fx2_ctrl> sptr; @@ -54,8 +55,7 @@ public: * \param filename name of firmware file * \param force reload firmware if already loaded */ - virtual void usrp_load_firmware(std::string filename, - bool force = false) = 0; + virtual void usrp_load_firmware(std::string filename, bool force = false) = 0; /*! * Load fpga file onto usrp @@ -79,10 +79,10 @@ public: * \return number of bytes read or error */ virtual int usrp_control_read(uint8_t request, - uint16_t value, - uint16_t index, - unsigned char *buff, - uint16_t length) = 0; + uint16_t value, + uint16_t index, + unsigned char* buff, + uint16_t length) = 0; /*! * Submit an OUT transfer @@ -94,10 +94,10 @@ public: * \return number of bytes written or error */ virtual int usrp_control_write(uint8_t request, - uint16_t value, - uint16_t index, - unsigned char *buff, - uint16_t length) = 0; + uint16_t value, + uint16_t index, + unsigned char* buff, + uint16_t length) = 0; /*! * Perform an I2C write @@ -107,9 +107,7 @@ public: * \return number of bytes written or error */ - virtual int usrp_i2c_write(uint16_t i2c_addr, - unsigned char *buf, - uint16_t len) = 0; + virtual int usrp_i2c_write(uint16_t i2c_addr, unsigned char* buf, uint16_t len) = 0; /*! * Perform an I2C read @@ -119,9 +117,7 @@ public: * \return number of bytes read or error */ - virtual int usrp_i2c_read(uint16_t i2c_addr, - unsigned char *buf, - uint16_t len) = 0; + virtual int usrp_i2c_read(uint16_t i2c_addr, unsigned char* buf, uint16_t len) = 0; //! enable/disable the rx path virtual void usrp_rx_enable(bool on) = 0; @@ -133,6 +129,6 @@ public: virtual void usrp_fpga_reset(bool on) = 0; }; -}} //namespace uhd::usrp +}} // namespace uhd::usrp #endif /* INCLUDED_LIBUHD_USRP_COMMON_FX2_CTRL_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/io_service_args.hpp b/host/lib/include/uhdlib/usrp/common/io_service_args.hpp index bdf1fa592..e294df8ee 100644 --- a/host/lib/include/uhdlib/usrp/common/io_service_args.hpp +++ b/host/lib/include/uhdlib/usrp/common/io_service_args.hpp @@ -64,13 +64,13 @@ struct io_service_args_t size_t num_poll_offload_threads = 1; //! CPU affinity of offload threads, if wait_mode is set to BLOCK - std::map<size_t,size_t> recv_offload_thread_cpu; + std::map<size_t, size_t> recv_offload_thread_cpu; //! CPU affinity of offload threads, if wait_mode is set to BLOCK std::map<size_t, size_t> send_offload_thread_cpu; //! CPU affinity of offload threads, if wait_mode is set to POLL - std::map<size_t,size_t> poll_offload_thread_cpu; + std::map<size_t, size_t> poll_offload_thread_cpu; }; /*! Reads I/O service args from provided dictionary diff --git a/host/lib/include/uhdlib/usrp/common/lmx2592.hpp b/host/lib/include/uhdlib/usrp/common/lmx2592.hpp index 9ee3f944f..74a4df437 100644 --- a/host/lib/include/uhdlib/usrp/common/lmx2592.hpp +++ b/host/lib/include/uhdlib/usrp/common/lmx2592.hpp @@ -12,9 +12,9 @@ #include <uhd/utils/math.hpp> #include <uhd/utils/safe_call.hpp> #include <boost/format.hpp> -#include <functional> #include <algorithm> #include <cstdint> +#include <functional> #include <utility> #include <vector> diff --git a/host/lib/include/uhdlib/usrp/common/max287x.hpp b/host/lib/include/uhdlib/usrp/common/max287x.hpp index 08ee5b16d..5e23649ef 100644 --- a/host/lib/include/uhdlib/usrp/common/max287x.hpp +++ b/host/lib/include/uhdlib/usrp/common/max287x.hpp @@ -16,13 +16,13 @@ #include <uhd/utils/log.hpp> #include <uhd/utils/math.hpp> #include <uhd/utils/safe_call.hpp> +#include <stdint.h> #include <boost/assign.hpp> -#include <functional> #include <boost/math/special_functions/round.hpp> -#include <vector> #include <chrono> +#include <functional> #include <thread> -#include <stdint.h> +#include <vector> /** * MAX287x interface @@ -37,7 +37,7 @@ public: /** * LD Pin Modes */ - typedef enum{ + typedef enum { LD_PIN_MODE_LOW, LD_PIN_MODE_DLD, LD_PIN_MODE_ALD, @@ -47,7 +47,7 @@ public: /** * MUXOUT Modes */ - typedef enum{ + typedef enum { MUXOUT_TRI_STATE, MUXOUT_HIGH, MUXOUT_LOW, @@ -62,7 +62,7 @@ public: /** * Charge Pump Currents */ - typedef enum{ + typedef enum { CHARGE_PUMP_CURRENT_0_32MA, CHARGE_PUMP_CURRENT_0_64MA, CHARGE_PUMP_CURRENT_0_96MA, @@ -84,7 +84,7 @@ public: /** * Output Powers */ - typedef enum{ + typedef enum { OUTPUT_POWER_M4DBM, OUTPUT_POWER_M1DBM, OUTPUT_POWER_2DBM, @@ -108,7 +108,8 @@ public: * @param write write function * @return shared pointer to object */ - template <typename max287X_t> static sptr make(write_fn write) + template <typename max287X_t> + static sptr make(write_fn write) { return sptr(new max287X_t(write)); } @@ -116,7 +117,7 @@ public: /** * Destructor */ - virtual ~max287x_iface() {}; + virtual ~max287x_iface(){}; /** * Power up the synthesizer @@ -142,10 +143,7 @@ public: * @return actual frequency */ virtual double set_frequency( - double target_freq, - double ref_freq, - double target_pfd_freq, - bool is_int_n) = 0; + double target_freq, double ref_freq, double target_pfd_freq, bool is_int_n) = 0; /** * Set output power @@ -231,10 +229,7 @@ public: virtual void shutdown(void); virtual bool is_shutdown(void); virtual double set_frequency( - double target_freq, - double ref_freq, - double target_pfd_freq, - bool is_int_n); + double target_freq, double ref_freq, double target_pfd_freq, bool is_int_n); virtual void set_output_power(output_power_t power); virtual void set_ld_pin_mode(ld_pin_mode_t mode); virtual void set_muxout_mode(muxout_mode_t mode); @@ -268,17 +263,16 @@ public: max2870(write_fn func) : max287x<max2870_regs_t>(func) {} ~max2870() {} double set_frequency( - double target_freq, - double ref_freq, - double target_pfd_freq, - bool is_int_n) + double target_freq, double ref_freq, double target_pfd_freq, bool is_int_n) { - _regs.cpoc = is_int_n ? max2870_regs_t::CPOC_ENABLED : max2870_regs_t::CPOC_DISABLED; - _regs.feedback_select = target_freq >= 3.0e9 ? - max2870_regs_t::FEEDBACK_SELECT_DIVIDED : - max2870_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; - - return max287x<max2870_regs_t>::set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); + _regs.cpoc = is_int_n ? max2870_regs_t::CPOC_ENABLED + : max2870_regs_t::CPOC_DISABLED; + _regs.feedback_select = target_freq >= 3.0e9 + ? max2870_regs_t::FEEDBACK_SELECT_DIVIDED + : max2870_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; + + return max287x<max2870_regs_t>::set_frequency( + target_freq, ref_freq, target_pfd_freq, is_int_n); } void commit(void) { @@ -360,46 +354,41 @@ class max2871 : public max287x<max2871_regs_t> { public: max2871(write_fn func) : max287x<max2871_regs_t>(func) {} - ~max2871() {}; + ~max2871(){}; void set_muxout_mode(muxout_mode_t mode) { - switch(mode) - { - case MUXOUT_SYNC: - _regs.muxout = max2871_regs_t::MUXOUT_SYNC; - break; - case MUXOUT_SPI: - _regs.muxout = max2871_regs_t::MUXOUT_SPI; - break; - default: - max287x<max2871_regs_t>::set_muxout_mode(mode); + switch (mode) { + case MUXOUT_SYNC: + _regs.muxout = max2871_regs_t::MUXOUT_SYNC; + break; + case MUXOUT_SPI: + _regs.muxout = max2871_regs_t::MUXOUT_SPI; + break; + default: + max287x<max2871_regs_t>::set_muxout_mode(mode); } } double set_frequency( - double target_freq, - double ref_freq, - double target_pfd_freq, - bool is_int_n) + double target_freq, double ref_freq, double target_pfd_freq, bool is_int_n) { _regs.feedback_select = max2871_regs_t::FEEDBACK_SELECT_DIVIDED; - double freq = max287x<max2871_regs_t>::set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); + double freq = max287x<max2871_regs_t>::set_frequency( + target_freq, ref_freq, target_pfd_freq, is_int_n); // To support phase synchronization on MAX2871, the same VCO // subband must be manually programmed on all synthesizers and // several registers must be set to specific values. - if (_config_for_sync) - { + if (_config_for_sync) { // Need to manually program VCO value static const double MIN_VCO_FREQ = 3e9; - double vco_freq = target_freq; + double vco_freq = target_freq; while (vco_freq < MIN_VCO_FREQ) - vco_freq *=2; + vco_freq *= 2; uint8_t vco_index = 0xFF; - for(const vco_map_t::value_type &vco: max2871_vco_map) - { - if (uhd::math::fp_compare::fp_compare_epsilon<double>(vco_freq) < vco.second.stop()) - { + for (const vco_map_t::value_type& vco : max2871_vco_map) { + if (uhd::math::fp_compare::fp_compare_epsilon<double>(vco_freq) + < vco.second.stop()) { vco_index = vco.first; break; } @@ -408,19 +397,18 @@ public: throw uhd::index_error("Invalid VCO frequency"); // Settings required for phase synchronization as per MAX2871 datasheet - _regs.shutdown_vas = max2871_regs_t::SHUTDOWN_VAS_DISABLED; - _regs.vco = vco_index; + _regs.shutdown_vas = max2871_regs_t::SHUTDOWN_VAS_DISABLED; + _regs.vco = vco_index; _regs.low_noise_and_spur = max2871_regs_t::LOW_NOISE_AND_SPUR_LOW_NOISE; - _regs.f01 = max2871_regs_t::F01_FRAC_N; - _regs.aux_output_select = max2871_regs_t::AUX_OUTPUT_SELECT_DIVIDED; - } - else - { + _regs.f01 = max2871_regs_t::F01_FRAC_N; + _regs.aux_output_select = max2871_regs_t::AUX_OUTPUT_SELECT_DIVIDED; + } else { // Reset values to defaults - _regs.shutdown_vas = max2871_regs_t::SHUTDOWN_VAS_ENABLED; // turn VCO auto selection on + _regs.shutdown_vas = + max2871_regs_t::SHUTDOWN_VAS_ENABLED; // turn VCO auto selection on _regs.low_noise_and_spur = max2871_regs_t::LOW_NOISE_AND_SPUR_LOW_SPUR_2; - _regs.f01 = max2871_regs_t::F01_AUTO; - _regs.aux_output_select = max2871_regs_t::AUX_OUTPUT_SELECT_FUNDAMENTAL; + _regs.f01 = max2871_regs_t::F01_AUTO; + _regs.aux_output_select = max2871_regs_t::AUX_OUTPUT_SELECT_FUNDAMENTAL; } return freq; @@ -430,17 +418,18 @@ public: { max287x<max2871_regs_t>::commit(); - // According to Maxim support, the following factors must be true to allow for phase synchronization - if (_regs.int_n_mode == max2871_regs_t::INT_N_MODE_FRAC_N and - _regs.feedback_select == max2871_regs_t::FEEDBACK_SELECT_DIVIDED and - _regs.aux_output_select == max2871_regs_t::AUX_OUTPUT_SELECT_DIVIDED and - _regs.rf_divider_select <= max2871_regs_t::RF_DIVIDER_SELECT_DIV16 and - _regs.low_noise_and_spur == max2871_regs_t::LOW_NOISE_AND_SPUR_LOW_NOISE and - _regs.f01 == max2871_regs_t::F01_FRAC_N and - _regs.reference_doubler == max2871_regs_t::REFERENCE_DOUBLER_DISABLED and - _regs.reference_divide_by_2 == max2871_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED and - _regs.r_counter_10_bit == 1) - { + // According to Maxim support, the following factors must be true to allow for + // phase synchronization + if (_regs.int_n_mode == max2871_regs_t::INT_N_MODE_FRAC_N + and _regs.feedback_select == max2871_regs_t::FEEDBACK_SELECT_DIVIDED + and _regs.aux_output_select == max2871_regs_t::AUX_OUTPUT_SELECT_DIVIDED + and _regs.rf_divider_select <= max2871_regs_t::RF_DIVIDER_SELECT_DIV16 + and _regs.low_noise_and_spur == max2871_regs_t::LOW_NOISE_AND_SPUR_LOW_NOISE + and _regs.f01 == max2871_regs_t::F01_FRAC_N + and _regs.reference_doubler == max2871_regs_t::REFERENCE_DOUBLER_DISABLED + and _regs.reference_divide_by_2 + == max2871_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED + and _regs.r_counter_10_bit == 1) { _can_sync = true; } else { _can_sync = false; @@ -456,12 +445,12 @@ public: // include it here. template <typename max287x_regs_t> -max287x<max287x_regs_t>::max287x(write_fn func) : - _can_sync(false), - _config_for_sync(false), - _write_all_regs(true), - _write(func), - _delay_after_write(true) +max287x<max287x_regs_t>::max287x(write_fn func) + : _can_sync(false) + , _config_for_sync(false) + , _write_all_regs(true) + , _write(func) + , _delay_after_write(true) { power_up(); } @@ -469,16 +458,13 @@ max287x<max287x_regs_t>::max287x(write_fn func) : template <typename max287x_regs_t> max287x<max287x_regs_t>::~max287x() { - UHD_SAFE_CALL - ( - shutdown(); - ) + UHD_SAFE_CALL(shutdown();) } template <typename max287x_regs_t> void max287x<max287x_regs_t>::power_up(void) { - _regs.power_down = max287x_regs_t::POWER_DOWN_NORMAL; + _regs.power_down = max287x_regs_t::POWER_DOWN_NORMAL; _regs.double_buffer = max287x_regs_t::DOUBLE_BUFFER_ENABLED; // According to MAX287x data sheets: @@ -489,7 +475,7 @@ void max287x<max287x_regs_t>::power_up(void) // The first write and the 20ms wait are done here. The second write // is done when any other function that does a write to the registers // is called (such as tuning). - _write_all_regs = true; + _write_all_regs = true; _delay_after_write = true; commit(); _write_all_regs = true; // Next call to commit() writes all regs @@ -498,9 +484,9 @@ void max287x<max287x_regs_t>::power_up(void) template <typename max287x_regs_t> void max287x<max287x_regs_t>::shutdown(void) { - _regs.rf_output_enable = max287x_regs_t::RF_OUTPUT_ENABLE_DISABLED; + _regs.rf_output_enable = max287x_regs_t::RF_OUTPUT_ENABLE_DISABLED; _regs.aux_output_enable = max287x_regs_t::AUX_OUTPUT_ENABLE_DISABLED; - _regs.power_down = max287x_regs_t::POWER_DOWN_SHUTDOWN; + _regs.power_down = max287x_regs_t::POWER_DOWN_SHUTDOWN; commit(); } @@ -512,50 +498,48 @@ bool max287x<max287x_regs_t>::is_shutdown(void) template <typename max287x_regs_t> double max287x<max287x_regs_t>::set_frequency( - double target_freq, - double ref_freq, - double target_pfd_freq, - bool is_int_n) + double target_freq, double ref_freq, double target_pfd_freq, bool is_int_n) { - //map rf divider select output dividers to enums - static const uhd::dict<int, typename max287x_regs_t::rf_divider_select_t> rfdivsel_to_enum = - boost::assign::map_list_of - (1, max287x_regs_t::RF_DIVIDER_SELECT_DIV1) - (2, max287x_regs_t::RF_DIVIDER_SELECT_DIV2) - (4, max287x_regs_t::RF_DIVIDER_SELECT_DIV4) - (8, max287x_regs_t::RF_DIVIDER_SELECT_DIV8) - (16, max287x_regs_t::RF_DIVIDER_SELECT_DIV16) - (32, max287x_regs_t::RF_DIVIDER_SELECT_DIV32) - (64, max287x_regs_t::RF_DIVIDER_SELECT_DIV64) - (128, max287x_regs_t::RF_DIVIDER_SELECT_DIV128); - - //map mode setting to valid integer divider (N) values - static const uhd::range_t int_n_mode_div_range(16,65535,1); - static const uhd::range_t frac_n_mode_div_range(19,4091,1); - - //other ranges and constants from MAX287X datasheets - static const uhd::range_t clock_div_range(1,4095,1); - static const uhd::range_t r_range(1,1023,1); + // map rf divider select output dividers to enums + static const uhd::dict<int, typename max287x_regs_t::rf_divider_select_t> + rfdivsel_to_enum = + boost::assign::map_list_of(1, max287x_regs_t::RF_DIVIDER_SELECT_DIV1)( + 2, max287x_regs_t::RF_DIVIDER_SELECT_DIV2)( + 4, max287x_regs_t::RF_DIVIDER_SELECT_DIV4)( + 8, max287x_regs_t::RF_DIVIDER_SELECT_DIV8)( + 16, max287x_regs_t::RF_DIVIDER_SELECT_DIV16)( + 32, max287x_regs_t::RF_DIVIDER_SELECT_DIV32)( + 64, max287x_regs_t::RF_DIVIDER_SELECT_DIV64)( + 128, max287x_regs_t::RF_DIVIDER_SELECT_DIV128); + + // map mode setting to valid integer divider (N) values + static const uhd::range_t int_n_mode_div_range(16, 65535, 1); + static const uhd::range_t frac_n_mode_div_range(19, 4091, 1); + + // other ranges and constants from MAX287X datasheets + static const uhd::range_t clock_div_range(1, 4095, 1); + static const uhd::range_t r_range(1, 1023, 1); static const double MIN_VCO_FREQ = 3e9; - static const double BS_FREQ = 50e3; - static const int MAX_BS_VALUE = 1023; - - int T = 0; - int D = ref_freq <= 10.0e6 ? 1 : 0; - int R = 0; - int BS = 0; - int N = 0; - int FRAC = 0; - int MOD = 4095; - int RFdiv = 1; + static const double BS_FREQ = 50e3; + static const int MAX_BS_VALUE = 1023; + + int T = 0; + int D = ref_freq <= 10.0e6 ? 1 : 0; + int R = 0; + int BS = 0; + int N = 0; + int FRAC = 0; + int MOD = 4095; + int RFdiv = 1; double pfd_freq = target_pfd_freq; - bool feedback_divided = (_regs.feedback_select == max287x_regs_t::FEEDBACK_SELECT_DIVIDED); + bool feedback_divided = + (_regs.feedback_select == max287x_regs_t::FEEDBACK_SELECT_DIVIDED); - //increase RF divider until acceptable VCO frequency (MIN freq for MAX287x VCO is 3GHz) + // increase RF divider until acceptable VCO frequency (MIN freq for MAX287x VCO is + // 3GHz) UHD_ASSERT_THROW(target_freq > 0); double vco_freq = target_freq; - while (vco_freq < MIN_VCO_FREQ) - { + while (vco_freq < MIN_VCO_FREQ) { vco_freq *= 2; RFdiv *= 2; } @@ -580,56 +564,60 @@ double max287x<max287x_regs_t>::set_frequency( * N = f_vco/f_pfd - FRAC/MOD = f_vco*((R*(T+1))/(f_ref*(1+D))) - FRAC/MOD * f_rf = f_vco/RFdiv */ - for(R = int(ref_freq*(1+D)/(target_pfd_freq*(1+T))); R <= r_range.stop(); R++) - { - //PFD input frequency = f_ref/R ... ignoring Reference doubler/divide-by-2 (D & T) - pfd_freq = ref_freq*(1+D)/(R*(1+T)); + for (R = int(ref_freq * (1 + D) / (target_pfd_freq * (1 + T))); R <= r_range.stop(); + R++) { + // PFD input frequency = f_ref/R ... ignoring Reference doubler/divide-by-2 (D & + // T) + pfd_freq = ref_freq * (1 + D) / (R * (1 + T)); - //keep the PFD frequency at or below target + // keep the PFD frequency at or below target if (pfd_freq > target_pfd_freq) continue; - //ignore fractional part of tuning - N = int((vco_freq/pfd_freq)/fb_divisor); + // ignore fractional part of tuning + N = int((vco_freq / pfd_freq) / fb_divisor); - //Fractional-N calculation - FRAC = int(boost::math::round(((vco_freq/pfd_freq)/fb_divisor - N)*MOD)); + // Fractional-N calculation + FRAC = int(boost::math::round(((vco_freq / pfd_freq) / fb_divisor - N) * MOD)); - if(is_int_n) - { - if (FRAC > (MOD / 2)) //Round integer such that actual freq is closest to target + if (is_int_n) { + if (FRAC + > (MOD / 2)) // Round integer such that actual freq is closest to target N++; FRAC = 0; } - //keep N within int divider requirements - if(is_int_n) - { - if(N <= int_n_mode_div_range.start()) continue; - if(N >= int_n_mode_div_range.stop()) continue; - } - else - { - if(N <= frac_n_mode_div_range.start()) continue; - if(N >= frac_n_mode_div_range.stop()) continue; + // keep N within int divider requirements + if (is_int_n) { + if (N <= int_n_mode_div_range.start()) + continue; + if (N >= int_n_mode_div_range.stop()) + continue; + } else { + if (N <= frac_n_mode_div_range.start()) + continue; + if (N >= frac_n_mode_div_range.stop()) + continue; } - //keep pfd freq low enough to achieve 50kHz BS clock + // keep pfd freq low enough to achieve 50kHz BS clock BS = static_cast<int>(std::ceil(pfd_freq / BS_FREQ)); - if(BS <= MAX_BS_VALUE) break; + if (BS <= MAX_BS_VALUE) + break; } UHD_ASSERT_THROW(R <= r_range.stop()); - //Reference divide-by-2 for 50% duty cycle + // Reference divide-by-2 for 50% duty cycle // if R even, move one divide by 2 to to regs.reference_divide_by_2 - if(R % 2 == 0) - { + if (R % 2 == 0) { T = 1; R /= 2; } - //actual frequency calculation - double actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))) * fb_divisor / RFdiv; + // actual frequency calculation + double actual_freq = double((N + (double(FRAC) / double(MOD))) * ref_freq + * (1 + int(D)) / (R * (1 + int(T)))) + * fb_divisor / RFdiv; UHD_LOGGER_TRACE("MAX287X") << boost::format("Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % ref_freq @@ -645,40 +633,38 @@ double max287x<max287x_regs_t>::set_frequency( % (target_freq / 1e6) % (actual_freq / 1e6) % (vco_freq / 1e6) % (pfd_freq / 1e6) % (pfd_freq / BS / 1e6); - //load the register values + // load the register values _regs.rf_output_enable = max287x_regs_t::RF_OUTPUT_ENABLE_ENABLED; - if(is_int_n) { - _regs.cpl = max287x_regs_t::CPL_DISABLED; - _regs.ldf = max287x_regs_t::LDF_INT_N; + if (is_int_n) { + _regs.cpl = max287x_regs_t::CPL_DISABLED; + _regs.ldf = max287x_regs_t::LDF_INT_N; _regs.int_n_mode = max287x_regs_t::INT_N_MODE_INT_N; } else { - _regs.cpl = max287x_regs_t::CPL_ENABLED; - _regs.ldf = max287x_regs_t::LDF_FRAC_N; + _regs.cpl = max287x_regs_t::CPL_ENABLED; + _regs.ldf = max287x_regs_t::LDF_FRAC_N; _regs.int_n_mode = max287x_regs_t::INT_N_MODE_FRAC_N; } _regs.lds = pfd_freq <= 32e6 ? max287x_regs_t::LDS_SLOW : max287x_regs_t::LDS_FAST; _regs.frac_12_bit = FRAC; - _regs.int_16_bit = N; - _regs.mod_12_bit = MOD; - _regs.clock_divider_12_bit = std::max(int(clock_div_range.start()), int(std::ceil(400e-6*pfd_freq/MOD))); + _regs.int_16_bit = N; + _regs.mod_12_bit = MOD; + _regs.clock_divider_12_bit = + std::max(int(clock_div_range.start()), int(std::ceil(400e-6 * pfd_freq / MOD))); UHD_ASSERT_THROW(_regs.clock_divider_12_bit <= clock_div_range.stop()); - _regs.r_counter_10_bit = R; - _regs.reference_divide_by_2 = T ? - max287x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED : - max287x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED; - _regs.reference_doubler = D ? - max287x_regs_t::REFERENCE_DOUBLER_ENABLED : - max287x_regs_t::REFERENCE_DOUBLER_DISABLED; + _regs.r_counter_10_bit = R; + _regs.reference_divide_by_2 = T ? max287x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED + : max287x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED; + _regs.reference_doubler = D ? max287x_regs_t::REFERENCE_DOUBLER_ENABLED + : max287x_regs_t::REFERENCE_DOUBLER_DISABLED; _regs.band_select_clock_div = BS & 0xFF; - _regs.bs_msb = (BS & 0x300) >> 8; + _regs.bs_msb = (BS & 0x300) >> 8; UHD_ASSERT_THROW(rfdivsel_to_enum.has_key(RFdiv)); _regs.rf_divider_select = rfdivsel_to_enum[RFdiv]; - if (_regs.clock_div_mode == max287x_regs_t::CLOCK_DIV_MODE_FAST_LOCK) - { + if (_regs.clock_div_mode == max287x_regs_t::CLOCK_DIV_MODE_FAST_LOCK) { // Charge pump current needs to be set to lowest value in fast lock mode _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_32MA; // Make sure the register containing the charge pump current is written @@ -691,165 +677,163 @@ double max287x<max287x_regs_t>::set_frequency( template <typename max287x_regs_t> void max287x<max287x_regs_t>::set_output_power(output_power_t power) { - switch (power) - { - case OUTPUT_POWER_M4DBM: - _regs.output_power = max287x_regs_t::OUTPUT_POWER_M4DBM; - break; - case OUTPUT_POWER_M1DBM: - _regs.output_power = max287x_regs_t::OUTPUT_POWER_M1DBM; - break; - case OUTPUT_POWER_2DBM: - _regs.output_power = max287x_regs_t::OUTPUT_POWER_2DBM; - break; - case OUTPUT_POWER_5DBM: - _regs.output_power = max287x_regs_t::OUTPUT_POWER_5DBM; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (power) { + case OUTPUT_POWER_M4DBM: + _regs.output_power = max287x_regs_t::OUTPUT_POWER_M4DBM; + break; + case OUTPUT_POWER_M1DBM: + _regs.output_power = max287x_regs_t::OUTPUT_POWER_M1DBM; + break; + case OUTPUT_POWER_2DBM: + _regs.output_power = max287x_regs_t::OUTPUT_POWER_2DBM; + break; + case OUTPUT_POWER_5DBM: + _regs.output_power = max287x_regs_t::OUTPUT_POWER_5DBM; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } template <typename max287x_regs_t> void max287x<max287x_regs_t>::set_ld_pin_mode(ld_pin_mode_t mode) { - switch(mode) - { - case LD_PIN_MODE_LOW: - _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_LOW; - break; - case LD_PIN_MODE_DLD: - _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_DLD; - break; - case LD_PIN_MODE_ALD: - _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_ALD; - break; - case LD_PIN_MODE_HIGH: - _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_HIGH; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (mode) { + case LD_PIN_MODE_LOW: + _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_LOW; + break; + case LD_PIN_MODE_DLD: + _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_DLD; + break; + case LD_PIN_MODE_ALD: + _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_ALD; + break; + case LD_PIN_MODE_HIGH: + _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_HIGH; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } template <typename max287x_regs_t> void max287x<max287x_regs_t>::set_muxout_mode(muxout_mode_t mode) { - switch(mode) - { - case MUXOUT_TRI_STATE: - _regs.muxout = max287x_regs_t::MUXOUT_TRI_STATE; - break; - case MUXOUT_HIGH: - _regs.muxout = max287x_regs_t::MUXOUT_HIGH; - break; - case MUXOUT_LOW: - _regs.muxout = max287x_regs_t::MUXOUT_LOW; - break; - case MUXOUT_RDIV: - _regs.muxout = max287x_regs_t::MUXOUT_RDIV; - break; - case MUXOUT_NDIV: - _regs.muxout = max287x_regs_t::MUXOUT_NDIV; - break; - case MUXOUT_ALD: - _regs.muxout = max287x_regs_t::MUXOUT_ALD; - break; - case MUXOUT_DLD: - _regs.muxout = max287x_regs_t::MUXOUT_DLD; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (mode) { + case MUXOUT_TRI_STATE: + _regs.muxout = max287x_regs_t::MUXOUT_TRI_STATE; + break; + case MUXOUT_HIGH: + _regs.muxout = max287x_regs_t::MUXOUT_HIGH; + break; + case MUXOUT_LOW: + _regs.muxout = max287x_regs_t::MUXOUT_LOW; + break; + case MUXOUT_RDIV: + _regs.muxout = max287x_regs_t::MUXOUT_RDIV; + break; + case MUXOUT_NDIV: + _regs.muxout = max287x_regs_t::MUXOUT_NDIV; + break; + case MUXOUT_ALD: + _regs.muxout = max287x_regs_t::MUXOUT_ALD; + break; + case MUXOUT_DLD: + _regs.muxout = max287x_regs_t::MUXOUT_DLD; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } template <typename max287x_regs_t> void max287x<max287x_regs_t>::set_charge_pump_current(charge_pump_current_t cp_current) { - switch(cp_current) - { - case CHARGE_PUMP_CURRENT_0_32MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_32MA; - break; - case CHARGE_PUMP_CURRENT_0_64MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_64MA; - break; - case CHARGE_PUMP_CURRENT_0_96MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_96MA; - break; - case CHARGE_PUMP_CURRENT_1_28MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_1_28MA; - break; - case CHARGE_PUMP_CURRENT_1_60MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_1_60MA; - break; - case CHARGE_PUMP_CURRENT_1_92MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_1_92MA; - break; - case CHARGE_PUMP_CURRENT_2_24MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_2_24MA; - break; - case CHARGE_PUMP_CURRENT_2_56MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_2_56MA; - break; - case CHARGE_PUMP_CURRENT_2_88MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_2_88MA; - break; - case CHARGE_PUMP_CURRENT_3_20MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_3_20MA; - break; - case CHARGE_PUMP_CURRENT_3_52MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_3_52MA; - break; - case CHARGE_PUMP_CURRENT_3_84MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_3_84MA; - break; - case CHARGE_PUMP_CURRENT_4_16MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_4_16MA; - break; - case CHARGE_PUMP_CURRENT_4_48MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_4_48MA; - break; - case CHARGE_PUMP_CURRENT_4_80MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_4_80MA; - break; - case CHARGE_PUMP_CURRENT_5_12MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_5_12MA; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (cp_current) { + case CHARGE_PUMP_CURRENT_0_32MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_32MA; + break; + case CHARGE_PUMP_CURRENT_0_64MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_64MA; + break; + case CHARGE_PUMP_CURRENT_0_96MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_96MA; + break; + case CHARGE_PUMP_CURRENT_1_28MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_1_28MA; + break; + case CHARGE_PUMP_CURRENT_1_60MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_1_60MA; + break; + case CHARGE_PUMP_CURRENT_1_92MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_1_92MA; + break; + case CHARGE_PUMP_CURRENT_2_24MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_2_24MA; + break; + case CHARGE_PUMP_CURRENT_2_56MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_2_56MA; + break; + case CHARGE_PUMP_CURRENT_2_88MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_2_88MA; + break; + case CHARGE_PUMP_CURRENT_3_20MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_3_20MA; + break; + case CHARGE_PUMP_CURRENT_3_52MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_3_52MA; + break; + case CHARGE_PUMP_CURRENT_3_84MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_3_84MA; + break; + case CHARGE_PUMP_CURRENT_4_16MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_4_16MA; + break; + case CHARGE_PUMP_CURRENT_4_48MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_4_48MA; + break; + case CHARGE_PUMP_CURRENT_4_80MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_4_80MA; + break; + case CHARGE_PUMP_CURRENT_5_12MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_5_12MA; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } template <typename max287x_regs_t> void max287x<max287x_regs_t>::set_auto_retune(bool enabled) { - _regs.retune = enabled ? max287x_regs_t::RETUNE_ENABLED : max287x_regs_t::RETUNE_DISABLED; + _regs.retune = enabled ? max287x_regs_t::RETUNE_ENABLED + : max287x_regs_t::RETUNE_DISABLED; } template <> inline void max287x<max2871_regs_t>::set_auto_retune(bool enabled) { - _regs.retune = enabled ? max2871_regs_t::RETUNE_ENABLED : max2871_regs_t::RETUNE_DISABLED; - _regs.vas_dly = enabled ? max2871_regs_t::VAS_DLY_ENABLED : max2871_regs_t::VAS_DLY_DISABLED; + _regs.retune = enabled ? max2871_regs_t::RETUNE_ENABLED + : max2871_regs_t::RETUNE_DISABLED; + _regs.vas_dly = enabled ? max2871_regs_t::VAS_DLY_ENABLED + : max2871_regs_t::VAS_DLY_DISABLED; } template <typename max287x_regs_t> void max287x<max287x_regs_t>::set_clock_divider_mode(clock_divider_mode_t mode) { - switch(mode) - { - case CLOCK_DIV_MODE_CLOCK_DIVIDER_OFF: - _regs.clock_div_mode = max287x_regs_t::CLOCK_DIV_MODE_CLOCK_DIVIDER_OFF; - break; - case CLOCK_DIV_MODE_FAST_LOCK: - _regs.clock_div_mode = max287x_regs_t::CLOCK_DIV_MODE_FAST_LOCK; - break; - case CLOCK_DIV_MODE_PHASE: - _regs.clock_div_mode = max287x_regs_t::CLOCK_DIV_MODE_PHASE; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (mode) { + case CLOCK_DIV_MODE_CLOCK_DIVIDER_OFF: + _regs.clock_div_mode = max287x_regs_t::CLOCK_DIV_MODE_CLOCK_DIVIDER_OFF; + break; + case CLOCK_DIV_MODE_FAST_LOCK: + _regs.clock_div_mode = max287x_regs_t::CLOCK_DIV_MODE_FAST_LOCK; + break; + case CLOCK_DIV_MODE_PHASE: + _regs.clock_div_mode = max287x_regs_t::CLOCK_DIV_MODE_PHASE; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } @@ -857,25 +841,25 @@ template <typename max287x_regs_t> void max287x<max287x_regs_t>::set_cycle_slip_mode(bool enabled) { if (enabled) - throw uhd::runtime_error("Cycle slip mode not supported on this MAX287x synthesizer."); + throw uhd::runtime_error( + "Cycle slip mode not supported on this MAX287x synthesizer."); } template <typename max287x_regs_t> void max287x<max287x_regs_t>::set_low_noise_and_spur(low_noise_and_spur_t mode) { - switch(mode) - { - case LOW_NOISE_AND_SPUR_LOW_NOISE: - _regs.low_noise_and_spur = max287x_regs_t::LOW_NOISE_AND_SPUR_LOW_NOISE; - break; - case LOW_NOISE_AND_SPUR_LOW_SPUR_1: - _regs.low_noise_and_spur = max287x_regs_t::LOW_NOISE_AND_SPUR_LOW_SPUR_1; - break; - case LOW_NOISE_AND_SPUR_LOW_SPUR_2: - _regs.low_noise_and_spur = max287x_regs_t::LOW_NOISE_AND_SPUR_LOW_SPUR_2; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (mode) { + case LOW_NOISE_AND_SPUR_LOW_NOISE: + _regs.low_noise_and_spur = max287x_regs_t::LOW_NOISE_AND_SPUR_LOW_NOISE; + break; + case LOW_NOISE_AND_SPUR_LOW_SPUR_1: + _regs.low_noise_and_spur = max287x_regs_t::LOW_NOISE_AND_SPUR_LOW_SPUR_1; + break; + case LOW_NOISE_AND_SPUR_LOW_SPUR_2: + _regs.low_noise_and_spur = max287x_regs_t::LOW_NOISE_AND_SPUR_LOW_SPUR_2; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } @@ -892,21 +876,18 @@ void max287x<max287x_regs_t>::commit() std::set<uint32_t> changed_regs; // Get only regs with changes - if (_write_all_regs) - { + if (_write_all_regs) { for (int addr = 5; addr >= 0; addr--) regs.push_back(_regs.get_reg(uint32_t(addr))); } else { try { - changed_regs = _regs.template get_changed_addrs<uint32_t> (); + changed_regs = _regs.template get_changed_addrs<uint32_t>(); // register 0 must be written to apply double buffered fields - if (changed_regs.size() > 0) - { + if (changed_regs.size() > 0) { changed_regs.insert(0); } - for (int addr = 5; addr >= 0; addr--) - { + for (int addr = 5; addr >= 0; addr--) { if (changed_regs.find(uint32_t(addr)) != changed_regs.end()) regs.push_back(_regs.get_reg(uint32_t(addr))); } @@ -921,8 +902,7 @@ void max287x<max287x_regs_t>::commit() _regs.save_state(); _write_all_regs = false; - if (_delay_after_write) - { + if (_delay_after_write) { std::this_thread::sleep_for(std::chrono::milliseconds(20)); _delay_after_write = false; } diff --git a/host/lib/include/uhdlib/usrp/common/mpmd_mb_controller.hpp b/host/lib/include/uhdlib/usrp/common/mpmd_mb_controller.hpp index 8111d05b8..25d32ee28 100644 --- a/host/lib/include/uhdlib/usrp/common/mpmd_mb_controller.hpp +++ b/host/lib/include/uhdlib/usrp/common/mpmd_mb_controller.hpp @@ -27,7 +27,10 @@ public: mpmd_mb_controller(uhd::rpc_client::sptr rpcc, uhd::device_addr_t device_info); //! Return reference to the RPC client - uhd::rpc_client::sptr get_rpc_client() { return _rpc; } + uhd::rpc_client::sptr get_rpc_client() + { + return _rpc; + } /************************************************************************** * Timekeeper API diff --git a/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer.hpp b/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer.hpp index c61e0ba99..09882378e 100644 --- a/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer.hpp +++ b/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer.hpp @@ -10,24 +10,28 @@ #include <uhd/config.hpp> #include <uhd/transport/zero_copy.hpp> -#include <memory> #include <stdint.h> +#include <memory> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { - class recv_packet_demuxer{ - public: - typedef std::shared_ptr<recv_packet_demuxer> sptr; +class recv_packet_demuxer +{ +public: + typedef std::shared_ptr<recv_packet_demuxer> sptr; - virtual ~recv_packet_demuxer(void) = 0; + virtual ~recv_packet_demuxer(void) = 0; - //! Make a new demuxer from a transport and parameters - static sptr make(transport::zero_copy_if::sptr transport, const size_t size, const uint32_t sid_base); + //! Make a new demuxer from a transport and parameters + static sptr make(transport::zero_copy_if::sptr transport, + const size_t size, + const uint32_t sid_base); - //! Get a buffer at the given index from the transport - virtual transport::managed_recv_buffer::sptr get_recv_buff(const size_t index, const double timeout) = 0; - }; + //! Get a buffer at the given index from the transport + virtual transport::managed_recv_buffer::sptr get_recv_buff( + const size_t index, const double timeout) = 0; +}; -}} //namespace uhd::usrp +}} // namespace uhd::usrp #endif /* INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer_3000.hpp b/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer_3000.hpp index bb5b070c5..4d20e17cc 100644 --- a/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer_3000.hpp +++ b/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer_3000.hpp @@ -10,140 +10,156 @@ #include <uhd/config.hpp> #include <uhd/transport/zero_copy.hpp> -#include <uhd/utils/log.hpp> #include <uhd/types/time_spec.hpp> #include <uhd/utils/byteswap.hpp> +#include <uhd/utils/log.hpp> +#include <stdint.h> #include <boost/thread.hpp> +#include <chrono> +#include <map> #include <memory> #include <queue> -#include <map> -#include <chrono> -#include <stdint.h> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { - struct recv_packet_demuxer_3000 : std::enable_shared_from_this<recv_packet_demuxer_3000> +struct recv_packet_demuxer_3000 : std::enable_shared_from_this<recv_packet_demuxer_3000> +{ + typedef std::shared_ptr<recv_packet_demuxer_3000> sptr; + static sptr make(transport::zero_copy_if::sptr xport) { - typedef std::shared_ptr<recv_packet_demuxer_3000> sptr; - static sptr make(transport::zero_copy_if::sptr xport) - { - return sptr(new recv_packet_demuxer_3000(xport)); - } + return sptr(new recv_packet_demuxer_3000(xport)); + } - recv_packet_demuxer_3000(transport::zero_copy_if::sptr xport): - _xport(xport) - {/*NOP*/} + recv_packet_demuxer_3000(transport::zero_copy_if::sptr xport) : _xport(xport) + { /*NOP*/ + } - transport::managed_recv_buffer::sptr get_recv_buff(const uint32_t sid, const double timeout) + transport::managed_recv_buffer::sptr get_recv_buff( + const uint32_t sid, const double timeout) + { + const auto exit_time = std::chrono::high_resolution_clock::now() + + std::chrono::microseconds(int64_t(timeout * 1e6)); + transport::managed_recv_buffer::sptr buff; + buff = _internal_get_recv_buff(sid, timeout); + while (not buff) // loop until timeout { - const auto exit_time = std::chrono::high_resolution_clock::now() - + std::chrono::microseconds(int64_t(timeout * 1e6)); - transport::managed_recv_buffer::sptr buff; - buff = _internal_get_recv_buff(sid, timeout); - while (not buff) //loop until timeout - { - const auto delta = exit_time - std::chrono::high_resolution_clock::now(); - const double new_timeout = - std::chrono::duration_cast<std::chrono::duration<double>>(delta) - .count(); - if (new_timeout < 0.0) { - break; - } - buff = _internal_get_recv_buff(sid, new_timeout); + const auto delta = exit_time - std::chrono::high_resolution_clock::now(); + const double new_timeout = + std::chrono::duration_cast<std::chrono::duration<double>>(delta).count(); + if (new_timeout < 0.0) { + break; } - return buff; + buff = _internal_get_recv_buff(sid, new_timeout); } + return buff; + } + + transport::managed_recv_buffer::sptr _internal_get_recv_buff( + const uint32_t sid, const double timeout) + { + transport::managed_recv_buffer::sptr buff; - transport::managed_recv_buffer::sptr _internal_get_recv_buff(const uint32_t sid, const double timeout) + //---------------------------------------------------------- + //-- Check the queue to see if we already have a buffer + //---------------------------------------------------------- { - transport::managed_recv_buffer::sptr buff; - - //---------------------------------------------------------- - //-- Check the queue to see if we already have a buffer - //---------------------------------------------------------- - { - boost::mutex::scoped_lock l(mutex); - queue_type_t &queue = _queues[sid]; - if (not queue.empty()) - { - buff = queue.front(); - queue.front().reset(); - queue.pop(); - return buff; - } - } - { - buff = _xport->get_recv_buff(timeout); - if (buff) - { - const uint32_t new_sid = uhd::wtohx(buff->cast<const uint32_t *>()[1]); - if (new_sid != sid) - { - boost::mutex::scoped_lock l(mutex); - if (_queues.count(new_sid) == 0) UHD_LOGGER_ERROR("STREAMER") - << "recv packet demuxer unexpected sid 0x" << std::hex << new_sid << std::dec - ; - else _queues[new_sid].push(buff); - buff.reset(); - } - } + boost::mutex::scoped_lock l(mutex); + queue_type_t& queue = _queues[sid]; + if (not queue.empty()) { + buff = queue.front(); + queue.front().reset(); + queue.pop(); + return buff; } - return buff; } - - void realloc_sid(const uint32_t sid) { - boost::mutex::scoped_lock l(mutex); - while(not _queues[sid].empty()) //allocated and clears if already allocated - { - _queues[sid].pop(); + buff = _xport->get_recv_buff(timeout); + if (buff) { + const uint32_t new_sid = uhd::wtohx(buff->cast<const uint32_t*>()[1]); + if (new_sid != sid) { + boost::mutex::scoped_lock l(mutex); + if (_queues.count(new_sid) == 0) + UHD_LOGGER_ERROR("STREAMER") + << "recv packet demuxer unexpected sid 0x" << std::hex + << new_sid << std::dec; + else + _queues[new_sid].push(buff); + buff.reset(); + } } } + return buff; + } - transport::zero_copy_if::sptr make_proxy(const uint32_t sid); - - typedef std::queue<transport::managed_recv_buffer::sptr> queue_type_t; - std::map<uint32_t, queue_type_t> _queues; - transport::zero_copy_if::sptr _xport; - boost::mutex mutex; - }; - - struct recv_packet_demuxer_proxy_3000 : transport::zero_copy_if + void realloc_sid(const uint32_t sid) { - recv_packet_demuxer_proxy_3000(recv_packet_demuxer_3000::sptr demux, transport::zero_copy_if::sptr xport, const uint32_t sid): - _demux(demux), _xport(xport), _sid(sid) + boost::mutex::scoped_lock l(mutex); + while (not _queues[sid].empty()) // allocated and clears if already allocated { - _demux->realloc_sid(_sid); //causes clear + _queues[sid].pop(); } + } - ~recv_packet_demuxer_proxy_3000(void) - { - _demux->realloc_sid(_sid); //causes clear - } + transport::zero_copy_if::sptr make_proxy(const uint32_t sid); - size_t get_num_recv_frames(void) const {return _xport->get_num_recv_frames();} - size_t get_recv_frame_size(void) const {return _xport->get_recv_frame_size();} - transport::managed_recv_buffer::sptr get_recv_buff(double timeout) - { - return _demux->get_recv_buff(_sid, timeout); - } - size_t get_num_send_frames(void) const {return _xport->get_num_send_frames();} - size_t get_send_frame_size(void) const {return _xport->get_send_frame_size();} - transport::managed_send_buffer::sptr get_send_buff(double timeout) - { - return _xport->get_send_buff(timeout); - } + typedef std::queue<transport::managed_recv_buffer::sptr> queue_type_t; + std::map<uint32_t, queue_type_t> _queues; + transport::zero_copy_if::sptr _xport; + boost::mutex mutex; +}; + +struct recv_packet_demuxer_proxy_3000 : transport::zero_copy_if +{ + recv_packet_demuxer_proxy_3000(recv_packet_demuxer_3000::sptr demux, + transport::zero_copy_if::sptr xport, + const uint32_t sid) + : _demux(demux), _xport(xport), _sid(sid) + { + _demux->realloc_sid(_sid); // causes clear + } - recv_packet_demuxer_3000::sptr _demux; - transport::zero_copy_if::sptr _xport; - const uint32_t _sid; - }; + ~recv_packet_demuxer_proxy_3000(void) + { + _demux->realloc_sid(_sid); // causes clear + } - inline transport::zero_copy_if::sptr recv_packet_demuxer_3000::make_proxy(const uint32_t sid) + size_t get_num_recv_frames(void) const { - return transport::zero_copy_if::sptr(new recv_packet_demuxer_proxy_3000(this->shared_from_this(), _xport, sid)); + return _xport->get_num_recv_frames(); } + size_t get_recv_frame_size(void) const + { + return _xport->get_recv_frame_size(); + } + transport::managed_recv_buffer::sptr get_recv_buff(double timeout) + { + return _demux->get_recv_buff(_sid, timeout); + } + size_t get_num_send_frames(void) const + { + return _xport->get_num_send_frames(); + } + size_t get_send_frame_size(void) const + { + return _xport->get_send_frame_size(); + } + transport::managed_send_buffer::sptr get_send_buff(double timeout) + { + return _xport->get_send_buff(timeout); + } + + recv_packet_demuxer_3000::sptr _demux; + transport::zero_copy_if::sptr _xport; + const uint32_t _sid; +}; + +inline transport::zero_copy_if::sptr recv_packet_demuxer_3000::make_proxy( + const uint32_t sid) +{ + return transport::zero_copy_if::sptr( + new recv_packet_demuxer_proxy_3000(this->shared_from_this(), _xport, sid)); +} -}} //namespace uhd::usrp +}} // namespace uhd::usrp #endif /* INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/validate_subdev_spec.hpp b/host/lib/include/uhdlib/usrp/common/validate_subdev_spec.hpp index f2f3ce035..eb56da12e 100644 --- a/host/lib/include/uhdlib/usrp/common/validate_subdev_spec.hpp +++ b/host/lib/include/uhdlib/usrp/common/validate_subdev_spec.hpp @@ -9,20 +9,18 @@ #define INCLUDED_LIBUHD_USRP_COMMON_VALIDATE_SUBDEV_SPEC_HPP #include <uhd/config.hpp> -#include <uhd/usrp/subdev_spec.hpp> #include <uhd/property_tree.hpp> +#include <uhd/usrp/subdev_spec.hpp> #include <string> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { - //! Validate a subdev spec against a property tree - void validate_subdev_spec( - property_tree::sptr tree, - const subdev_spec_t &spec, - const std::string &type, //rx or tx - const std::string &mb = "0" - ); +//! Validate a subdev spec against a property tree +void validate_subdev_spec(property_tree::sptr tree, + const subdev_spec_t& spec, + const std::string& type, // rx or tx + const std::string& mb = "0"); -}} //namespace uhd::usrp +}} // namespace uhd::usrp #endif /* INCLUDED_LIBUHD_USRP_COMMON_VALIDATE_SUBDEV_SPEC_HPP */ diff --git a/host/lib/include/uhdlib/usrp/constrained_device_args.hpp b/host/lib/include/uhdlib/usrp/constrained_device_args.hpp index edb0dd2fc..7c516f80c 100644 --- a/host/lib/include/uhdlib/usrp/constrained_device_args.hpp +++ b/host/lib/include/uhdlib/usrp/constrained_device_args.hpp @@ -8,311 +8,334 @@ #ifndef INCLUDED_LIBUHD_USRP_COMMON_CONSTRAINED_DEV_ARGS_HPP #define INCLUDED_LIBUHD_USRP_COMMON_CONSTRAINED_DEV_ARGS_HPP -#include <uhd/types/device_addr.hpp> #include <uhd/exception.hpp> -#include <boost/format.hpp> +#include <uhd/types/device_addr.hpp> +#include <unordered_map> #include <boost/algorithm/string.hpp> #include <boost/assign/list_of.hpp> -#include <vector> -#include <string> +#include <boost/format.hpp> #include <sstream> -#include <unordered_map> +#include <string> +#include <vector> -namespace uhd { -namespace usrp { +namespace uhd { namespace usrp { +/*! + * constrained_device_args_t provides a base and utilities to + * map key=value pairs passed in through the device creation + * args interface (device_addr_t). + * + * Inherit from this class to create typed device specific + * arguments and use the base class methods to handle parsing + * the device_addr or any key=value string to populate the args + * + * This file contains a library of different types of args the + * the user can pass in. The library can be extended to support + * non-intrinsic types by the client. + * + */ +class constrained_device_args_t +{ +public: // Types /*! - * constrained_device_args_t provides a base and utilities to - * map key=value pairs passed in through the device creation - * args interface (device_addr_t). - * - * Inherit from this class to create typed device specific - * arguments and use the base class methods to handle parsing - * the device_addr or any key=value string to populate the args - * - * This file contains a library of different types of args the - * the user can pass in. The library can be extended to support - * non-intrinsic types by the client. - * + * Base argument type. All other arguments inherit from this. */ - class constrained_device_args_t { - public: //Types + class generic_arg + { + public: + generic_arg(const std::string& key) : _key(key) {} + inline const std::string& key() const + { + return _key; + } + inline virtual std::string to_string() const = 0; - /*! - * Base argument type. All other arguments inherit from this. - */ - class generic_arg { - public: - generic_arg(const std::string& key): _key(key) {} - inline const std::string& key() const { return _key; } - inline virtual std::string to_string() const = 0; - private: - std::string _key; - }; + private: + std::string _key; + }; - /*! - * String argument type. Can be case sensitive or insensitive - */ - template<bool case_sensitive> - class str_arg : public generic_arg { - public: - str_arg(const std::string& name, const std::string& default_value) : - generic_arg(name) { set(default_value); } + /*! + * String argument type. Can be case sensitive or insensitive + */ + template <bool case_sensitive> + class str_arg : public generic_arg + { + public: + str_arg(const std::string& name, const std::string& default_value) + : generic_arg(name) + { + set(default_value); + } - inline void set(const std::string& value) { - _value = case_sensitive ? value : boost::algorithm::to_lower_copy(value); - } - inline const std::string& get() const { - return _value; - } - inline void parse(const std::string& str_rep) { - set(str_rep); - } - inline virtual std::string to_string() const { - return key() + "=" + get(); - } - inline bool operator==(const std::string& rhs) const { - return get() == boost::algorithm::to_lower_copy(rhs); - } - private: - std::string _value; - }; - typedef str_arg<false> str_ci_arg; - typedef str_arg<true> str_cs_arg; + inline void set(const std::string& value) + { + _value = case_sensitive ? value : boost::algorithm::to_lower_copy(value); + } + inline const std::string& get() const + { + return _value; + } + inline void parse(const std::string& str_rep) + { + set(str_rep); + } + inline virtual std::string to_string() const + { + return key() + "=" + get(); + } + inline bool operator==(const std::string& rhs) const + { + return get() == boost::algorithm::to_lower_copy(rhs); + } - /*! - * Numeric argument type. The template type data_t allows the - * client to constrain the type of the number. - */ - template<typename data_t> - class num_arg : public generic_arg { - public: - num_arg(const std::string& name, const data_t default_value) : - generic_arg(name) { set(default_value); } + private: + std::string _value; + }; + typedef str_arg<false> str_ci_arg; + typedef str_arg<true> str_cs_arg; - inline void set(const data_t value) { - _value = value; - } - inline const data_t get() const { - return _value; - } - inline void parse(const std::string& str_rep) { - try { - _value = boost::lexical_cast<data_t>(str_rep); - } catch (std::exception& ex) { - throw uhd::value_error(str(boost::format( - "Error parsing numeric parameter %s: %s.") % - key() % ex.what() - )); - } - } - inline virtual std::string to_string() const { - return key() + "=" + std::to_string(get()); - } - private: - data_t _value; - }; + /*! + * Numeric argument type. The template type data_t allows the + * client to constrain the type of the number. + */ + template <typename data_t> + class num_arg : public generic_arg + { + public: + num_arg(const std::string& name, const data_t default_value) : generic_arg(name) + { + set(default_value); + } - /*! - * Enumeration argument type. The template type enum_t allows the - * client to use their own enum and specify a string mapping for - * the values of the enum - */ - template<typename enum_t> - class enum_arg : public generic_arg { - public: - enum_arg( - const std::string& name, - const enum_t default_value, - const std::unordered_map<std::string, enum_t>& values) : - generic_arg(name), _str_values(_enum_map_to_lowercase<enum_t>(values)) - { - set(default_value); - } - inline void set(const enum_t value) { - _value = value; - } - inline const enum_t get() const { - return _value; + inline void set(const data_t value) + { + _value = value; + } + inline const data_t get() const + { + return _value; + } + inline void parse(const std::string& str_rep) + { + try { + _value = boost::lexical_cast<data_t>(str_rep); + } catch (std::exception& ex) { + throw uhd::value_error( + str(boost::format("Error parsing numeric parameter %s: %s.") % key() + % ex.what())); } - inline void parse( - const std::string& str_rep, - const bool assert_invalid = true - ) { - const std::string str_rep_lowercase = - boost::algorithm::to_lower_copy(str_rep); - if (_str_values.count(str_rep_lowercase) == 0) { - if (assert_invalid) { - std::string valid_values_str = ""; - for (const auto &value : _str_values) { - valid_values_str += - (valid_values_str.empty()?"":", ") - + value.first; - } - throw uhd::value_error(str(boost::format( - "Invalid device arg value: %s=%s (Valid: {%s})") % - key() % str_rep % valid_values_str - )); - } else { - return; - } - } + } + inline virtual std::string to_string() const + { + return key() + "=" + std::to_string(get()); + } - set(_str_values.at(str_rep_lowercase)); - } - inline virtual std::string to_string() const { - std::string repr; - for (const auto& value : _str_values) { - if (value.second == _value) { - repr = value.first; - break; + private: + data_t _value; + }; + + /*! + * Enumeration argument type. The template type enum_t allows the + * client to use their own enum and specify a string mapping for + * the values of the enum + */ + template <typename enum_t> + class enum_arg : public generic_arg + { + public: + enum_arg(const std::string& name, + const enum_t default_value, + const std::unordered_map<std::string, enum_t>& values) + : generic_arg(name), _str_values(_enum_map_to_lowercase<enum_t>(values)) + { + set(default_value); + } + inline void set(const enum_t value) + { + _value = value; + } + inline const enum_t get() const + { + return _value; + } + inline void parse(const std::string& str_rep, const bool assert_invalid = true) + { + const std::string str_rep_lowercase = + boost::algorithm::to_lower_copy(str_rep); + if (_str_values.count(str_rep_lowercase) == 0) { + if (assert_invalid) { + std::string valid_values_str = ""; + for (const auto& value : _str_values) { + valid_values_str += + (valid_values_str.empty() ? "" : ", ") + value.first; } + throw uhd::value_error( + str(boost::format("Invalid device arg value: %s=%s (Valid: {%s})") + % key() % str_rep % valid_values_str)); + } else { + return; } + } - UHD_ASSERT_THROW(!repr.empty()); - return key() + "=" + repr; + set(_str_values.at(str_rep_lowercase)); + } + inline virtual std::string to_string() const + { + std::string repr; + for (const auto& value : _str_values) { + if (value.second == _value) { + repr = value.first; + break; + } } - private: - enum_t _value; - const std::unordered_map<std::string, enum_t> _str_values; - }; + UHD_ASSERT_THROW(!repr.empty()); + return key() + "=" + repr; + } - /*! - * Boolean argument type. - */ - class bool_arg : public generic_arg { - public: - bool_arg(const std::string& name, const bool default_value) : - generic_arg(name) { set(default_value); } + private: + enum_t _value; + const std::unordered_map<std::string, enum_t> _str_values; + }; - inline void set(const bool value) { - _value = value; - } - inline bool get() const { - return _value; - } - inline void parse(const std::string& str_rep) { - try { - _value = (std::stoi(str_rep) != 0); - } catch (std::exception& ex) { - if (str_rep.empty()) { - //If str_rep is empty then the device_addr was set - //without a value which means that the user "set" the flag - _value = true; - } else if (boost::algorithm::to_lower_copy(str_rep) == "true" || - boost::algorithm::to_lower_copy(str_rep) == "yes" || - boost::algorithm::to_lower_copy(str_rep) == "y" || - str_rep == "1" - ) { - _value = true; - } else if (boost::algorithm::to_lower_copy(str_rep) == "false" || - boost::algorithm::to_lower_copy(str_rep) == "no" || - boost::algorithm::to_lower_copy(str_rep) == "n" || - str_rep == "0" - ) { - _value = false; - } else { - throw uhd::value_error(str(boost::format( - "Error parsing boolean parameter %s: %s.") % - key() % ex.what() - )); - } + /*! + * Boolean argument type. + */ + class bool_arg : public generic_arg + { + public: + bool_arg(const std::string& name, const bool default_value) : generic_arg(name) + { + set(default_value); + } + + inline void set(const bool value) + { + _value = value; + } + inline bool get() const + { + return _value; + } + inline void parse(const std::string& str_rep) + { + try { + _value = (std::stoi(str_rep) != 0); + } catch (std::exception& ex) { + if (str_rep.empty()) { + // If str_rep is empty then the device_addr was set + // without a value which means that the user "set" the flag + _value = true; + } else if (boost::algorithm::to_lower_copy(str_rep) == "true" + || boost::algorithm::to_lower_copy(str_rep) == "yes" + || boost::algorithm::to_lower_copy(str_rep) == "y" + || str_rep == "1") { + _value = true; + } else if (boost::algorithm::to_lower_copy(str_rep) == "false" + || boost::algorithm::to_lower_copy(str_rep) == "no" + || boost::algorithm::to_lower_copy(str_rep) == "n" + || str_rep == "0") { + _value = false; + } else { + throw uhd::value_error( + str(boost::format("Error parsing boolean parameter %s: %s.") + % key() % ex.what())); } } - inline virtual std::string to_string() const { - return key() + "=" + (get() ? "true" : "false"); - } - private: - bool _value; - }; + } + inline virtual std::string to_string() const + { + return key() + "=" + (get() ? "true" : "false"); + } - public: //Methods - constrained_device_args_t() {} - virtual ~constrained_device_args_t() {} + private: + bool _value; + }; - void parse(const std::string& str_args) { - device_addr_t dev_args(str_args); - _parse(dev_args); - } +public: // Methods + constrained_device_args_t() {} + virtual ~constrained_device_args_t() {} - void parse(const device_addr_t& dev_args) { - _parse(dev_args); - } + void parse(const std::string& str_args) + { + device_addr_t dev_args(str_args); + _parse(dev_args); + } - inline virtual std::string to_string() const = 0; + void parse(const device_addr_t& dev_args) + { + _parse(dev_args); + } - template <typename arg_type> - void parse_arg_default( - const device_addr_t& dev_args, - arg_type& constrained_arg - ) { - if (dev_args.has_key(constrained_arg.key())) { - constrained_arg.parse(dev_args[constrained_arg.key()]); - } + inline virtual std::string to_string() const = 0; + + template <typename arg_type> + void parse_arg_default(const device_addr_t& dev_args, arg_type& constrained_arg) + { + if (dev_args.has_key(constrained_arg.key())) { + constrained_arg.parse(dev_args[constrained_arg.key()]); } + } - protected: //Methods - //Override _parse to provide an implementation to parse all - //client specific device args - virtual void _parse(const device_addr_t& dev_args) = 0; +protected: // Methods + // Override _parse to provide an implementation to parse all + // client specific device args + virtual void _parse(const device_addr_t& dev_args) = 0; - /*! - * Utility: Ensure that the value of the device arg is between min and max - */ - template<typename num_data_t> - static inline void _enforce_range(const num_arg<num_data_t>& arg, const num_data_t& min, const num_data_t& max) { - if (arg.get() > max || arg.get() < min) { - throw uhd::value_error(str(boost::format( - "Invalid device arg value: %s (Minimum: %s, Maximum: %s)") % - arg.to_string() % - std::to_string(min) % std::to_string(max))); - } + /*! + * Utility: Ensure that the value of the device arg is between min and max + */ + template <typename num_data_t> + static inline void _enforce_range( + const num_arg<num_data_t>& arg, const num_data_t& min, const num_data_t& max) + { + if (arg.get() > max || arg.get() < min) { + throw uhd::value_error(str( + boost::format("Invalid device arg value: %s (Minimum: %s, Maximum: %s)") + % arg.to_string() % std::to_string(min) % std::to_string(max))); } + } - /*! - * Utility: Ensure that the value of the device arg is is contained in valid_values - */ - template<typename arg_t, typename data_t> - static inline void _enforce_discrete(const arg_t& arg, const std::vector<data_t>& valid_values) { - bool match = false; - for(const data_t& val: valid_values) { - if (val == arg.get()) { - match = true; - break; - } + /*! + * Utility: Ensure that the value of the device arg is is contained in valid_values + */ + template <typename arg_t, typename data_t> + static inline void _enforce_discrete( + const arg_t& arg, const std::vector<data_t>& valid_values) + { + bool match = false; + for (const data_t& val : valid_values) { + if (val == arg.get()) { + match = true; + break; } - if (!match) { - std::string valid_values_str; - for (size_t i = 0; i < valid_values.size(); i++) { - std::stringstream valid_values_ss; - valid_values_ss << ((i==0)?"":", ") << valid_values[i]; - throw uhd::value_error(str(boost::format( - "Invalid device arg value: %s (Valid: {%s})") % - arg.to_string() % valid_values_ss.str() - )); - } + } + if (!match) { + std::string valid_values_str; + for (size_t i = 0; i < valid_values.size(); i++) { + std::stringstream valid_values_ss; + valid_values_ss << ((i == 0) ? "" : ", ") << valid_values[i]; + throw uhd::value_error( + str(boost::format("Invalid device arg value: %s (Valid: {%s})") + % arg.to_string() % valid_values_ss.str())); } } + } - //! Helper for enum_arg: Create a new map where keys are converted to - // lowercase. - template<typename enum_t> - static std::unordered_map<std::string, enum_t> _enum_map_to_lowercase( - const std::unordered_map<std::string, enum_t>& in_map - ) { - std::unordered_map<std::string, enum_t> new_map; - for (const auto& str_to_enum : in_map) { - new_map.insert( - std::pair<std::string, enum_t>( - boost::algorithm::to_lower_copy(str_to_enum.first), - str_to_enum.second - ) - ); - } - return new_map; + //! Helper for enum_arg: Create a new map where keys are converted to + // lowercase. + template <typename enum_t> + static std::unordered_map<std::string, enum_t> _enum_map_to_lowercase( + const std::unordered_map<std::string, enum_t>& in_map) + { + std::unordered_map<std::string, enum_t> new_map; + for (const auto& str_to_enum : in_map) { + new_map.insert(std::pair<std::string, enum_t>( + boost::algorithm::to_lower_copy(str_to_enum.first), str_to_enum.second)); } - }; -}} //namespaces + return new_map; + } +}; +}} // namespace uhd::usrp #endif /* INCLUDED_LIBUHD_USRP_COMMON_CONSTRAINED_DEV_ARGS_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/dsp_core_utils.hpp b/host/lib/include/uhdlib/usrp/cores/dsp_core_utils.hpp index 2632f4a1f..5e1c90845 100644 --- a/host/lib/include/uhdlib/usrp/cores/dsp_core_utils.hpp +++ b/host/lib/include/uhdlib/usrp/cores/dsp_core_utils.hpp @@ -13,12 +13,10 @@ /*! For a requested frequency and sampling rate, return the * correct frequency word (to set the CORDIC) and the actual frequency. */ -void get_freq_and_freq_word( - const double requested_freq, - const double tick_rate, - double &actual_freq, - int32_t &freq_word -); +void get_freq_and_freq_word(const double requested_freq, + const double tick_rate, + double& actual_freq, + int32_t& freq_word); /*! For a requested frequency and sampling rate, return the * correct frequency word (to set the CORDIC) and the actual frequency. diff --git a/host/lib/include/uhdlib/usrp/cores/gpio_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/gpio_core_200.hpp index d6f104be1..920dd1e3c 100644 --- a/host/lib/include/uhdlib/usrp/cores/gpio_core_200.hpp +++ b/host/lib/include/uhdlib/usrp/cores/gpio_core_200.hpp @@ -9,15 +9,16 @@ #define INCLUDED_LIBUHD_USRP_GPIO_CORE_200_HPP #include <uhd/config.hpp> +#include <uhd/types/wb_iface.hpp> #include <uhd/usrp/dboard_iface.hpp> #include <uhd/usrp/gpio_defs.hpp> #include <uhd/utils/noncopyable.hpp> -#include <memory> -#include <uhd/types/wb_iface.hpp> -#include <map> #include <stdint.h> +#include <map> +#include <memory> -class gpio_core_200 : uhd::noncopyable{ +class gpio_core_200 : uhd::noncopyable +{ public: typedef std::shared_ptr<gpio_core_200> sptr; @@ -27,8 +28,7 @@ public: virtual ~gpio_core_200(void) = 0; //! makes a new GPIO core from iface and slave base - static sptr make( - uhd::wb_iface::sptr iface, const size_t base, const size_t rb_addr); + static sptr make(uhd::wb_iface::sptr iface, const size_t base, const size_t rb_addr); //! 1 = ATR virtual void set_pin_ctrl( @@ -36,8 +36,10 @@ public: virtual uint16_t get_pin_ctrl(unit_t unit) = 0; - virtual void set_atr_reg( - const unit_t unit, const atr_reg_t atr, const uint16_t value, const uint16_t mask) = 0; + virtual void set_atr_reg(const unit_t unit, + const atr_reg_t atr, + const uint16_t value, + const uint16_t mask) = 0; virtual uint16_t get_atr_reg(unit_t unit, atr_reg_t reg) = 0; @@ -56,7 +58,8 @@ public: }; //! Simple wrapper for 32 bit write only -class gpio_core_200_32wo : uhd::noncopyable{ +class gpio_core_200_32wo : uhd::noncopyable +{ public: typedef std::shared_ptr<gpio_core_200_32wo> sptr; diff --git a/host/lib/include/uhdlib/usrp/cores/i2c_core_100_wb32.hpp b/host/lib/include/uhdlib/usrp/cores/i2c_core_100_wb32.hpp index 42e57ca16..15afda0ef 100644 --- a/host/lib/include/uhdlib/usrp/cores/i2c_core_100_wb32.hpp +++ b/host/lib/include/uhdlib/usrp/cores/i2c_core_100_wb32.hpp @@ -10,11 +10,12 @@ #include <uhd/config.hpp> #include <uhd/types/serial.hpp> -#include <uhd/utils/noncopyable.hpp> #include <uhd/types/wb_iface.hpp> +#include <uhd/utils/noncopyable.hpp> #include <memory> -class i2c_core_100_wb32 : uhd::noncopyable, public uhd::i2c_iface{ +class i2c_core_100_wb32 : uhd::noncopyable, public uhd::i2c_iface +{ public: typedef std::shared_ptr<i2c_core_100_wb32> sptr; diff --git a/host/lib/include/uhdlib/usrp/cores/i2c_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/i2c_core_200.hpp index 6d987b68a..2f6c4da79 100644 --- a/host/lib/include/uhdlib/usrp/cores/i2c_core_200.hpp +++ b/host/lib/include/uhdlib/usrp/cores/i2c_core_200.hpp @@ -10,12 +10,13 @@ #include <uhd/config.hpp> #include <uhd/types/serial.hpp> +#include <uhd/types/wb_iface.hpp> #include <uhd/utils/noncopyable.hpp> #include <boost/utility.hpp> #include <memory> -#include <uhd/types/wb_iface.hpp> -class i2c_core_200 : uhd::noncopyable, public uhd::i2c_iface{ +class i2c_core_200 : uhd::noncopyable, public uhd::i2c_iface +{ public: typedef std::shared_ptr<i2c_core_200> sptr; diff --git a/host/lib/include/uhdlib/usrp/cores/radio_ctrl_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/radio_ctrl_core_3000.hpp index 427a72586..c94217e82 100644 --- a/host/lib/include/uhdlib/usrp/cores/radio_ctrl_core_3000.hpp +++ b/host/lib/include/uhdlib/usrp/cores/radio_ctrl_core_3000.hpp @@ -8,12 +8,12 @@ #ifndef INCLUDED_LIBUHD_USRP_RADIO_CTRL_3000_HPP #define INCLUDED_LIBUHD_USRP_RADIO_CTRL_3000_HPP -#include <uhd/utils/msg_task.hpp> -#include <uhd/types/time_spec.hpp> #include <uhd/transport/zero_copy.hpp> +#include <uhd/types/time_spec.hpp> #include <uhd/types/wb_iface.hpp> -#include <memory> +#include <uhd/utils/msg_task.hpp> #include <boost/utility.hpp> +#include <memory> #include <string> /*! @@ -27,22 +27,20 @@ public: virtual ~radio_ctrl_core_3000(void) = 0; //! Make a new control object - static sptr make( - const bool big_endian, + static sptr make(const bool big_endian, uhd::transport::zero_copy_if::sptr ctrl_xport, uhd::transport::zero_copy_if::sptr resp_xport, const uint32_t sid, - const std::string &name = "0" - ); + const std::string& name = "0"); //! Hold a ref to a task thats feeding push response virtual void hold_task(uhd::msg_task::sptr task) = 0; //! Push a response externall (resp_xport is NULL) - virtual void push_response(const uint32_t *buff) = 0; + virtual void push_response(const uint32_t* buff) = 0; //! Set the command time that will activate - virtual void set_time(const uhd::time_spec_t &time) = 0; + virtual void set_time(const uhd::time_spec_t& time) = 0; //! Get the command time that will activate virtual uhd::time_spec_t get_time(void) = 0; diff --git a/host/lib/include/uhdlib/usrp/cores/rx_dsp_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/rx_dsp_core_200.hpp index 240838495..7f0cd9995 100644 --- a/host/lib/include/uhdlib/usrp/cores/rx_dsp_core_200.hpp +++ b/host/lib/include/uhdlib/usrp/cores/rx_dsp_core_200.hpp @@ -11,31 +11,32 @@ #include <uhd/config.hpp> #include <uhd/stream.hpp> #include <uhd/types/ranges.hpp> -#include <uhd/utils/noncopyable.hpp> -#include <memory> #include <uhd/types/stream_cmd.hpp> #include <uhd/types/wb_iface.hpp> +#include <uhd/utils/noncopyable.hpp> +#include <memory> #include <string> -class rx_dsp_core_200 : uhd::noncopyable{ +class rx_dsp_core_200 : uhd::noncopyable +{ public: typedef std::shared_ptr<rx_dsp_core_200> sptr; virtual ~rx_dsp_core_200(void) = 0; - static sptr make( - uhd::wb_iface::sptr iface, - const size_t dsp_base, const size_t ctrl_base, - const uint32_t sid, const bool lingering_packet = false - ); + static sptr make(uhd::wb_iface::sptr iface, + const size_t dsp_base, + const size_t ctrl_base, + const uint32_t sid, + const bool lingering_packet = false); virtual void clear(void) = 0; virtual void set_nsamps_per_packet(const size_t nsamps) = 0; - virtual void issue_stream_command(const uhd::stream_cmd_t &stream_cmd) = 0; + virtual void issue_stream_command(const uhd::stream_cmd_t& stream_cmd) = 0; - virtual void set_mux(const std::string &mode, const bool fe_swapped = false) = 0; + virtual void set_mux(const std::string& mode, const bool fe_swapped = false) = 0; virtual void set_tick_rate(const double rate) = 0; @@ -53,7 +54,7 @@ public: virtual void handle_overflow(void) = 0; - virtual void setup(const uhd::stream_args_t &stream_args) = 0; + virtual void setup(const uhd::stream_args_t& stream_args) = 0; }; #endif /* INCLUDED_LIBUHD_USRP_RX_DSP_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_200.hpp index 6a91f83da..8c51dac6c 100644 --- a/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_200.hpp +++ b/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_200.hpp @@ -9,14 +9,15 @@ #define INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_200_HPP #include <uhd/config.hpp> -#include <uhd/types/wb_iface.hpp> #include <uhd/property_tree.hpp> +#include <uhd/types/wb_iface.hpp> #include <uhd/utils/noncopyable.hpp> -#include <memory> #include <complex> +#include <memory> #include <string> -class rx_frontend_core_200 : uhd::noncopyable{ +class rx_frontend_core_200 : uhd::noncopyable +{ public: static const std::complex<double> DEFAULT_DC_OFFSET_VALUE; static const bool DEFAULT_DC_OFFSET_ENABLE; @@ -32,12 +33,11 @@ public: virtual void set_dc_offset_auto(const bool enb) = 0; - virtual std::complex<double> set_dc_offset(const std::complex<double> &off) = 0; + virtual std::complex<double> set_dc_offset(const std::complex<double>& off) = 0; - virtual void set_iq_balance(const std::complex<double> &cor) = 0; + virtual void set_iq_balance(const std::complex<double>& cor) = 0; virtual void populate_subtree(uhd::property_tree::sptr subtree) = 0; - }; #endif /* INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_3000.hpp index b1dfd307e..d340d6f4d 100644 --- a/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_3000.hpp +++ b/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_3000.hpp @@ -13,8 +13,8 @@ #include <uhd/types/wb_iface.hpp> #include <uhd/usrp/fe_connection.hpp> #include <uhd/utils/noncopyable.hpp> -#include <memory> #include <complex> +#include <memory> #include <string> class rx_frontend_core_3000 : uhd::noncopyable diff --git a/host/lib/include/uhdlib/usrp/cores/rx_vita_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/rx_vita_core_3000.hpp index 615ca2319..0f1850ddc 100644 --- a/host/lib/include/uhdlib/usrp/cores/rx_vita_core_3000.hpp +++ b/host/lib/include/uhdlib/usrp/cores/rx_vita_core_3000.hpp @@ -11,10 +11,10 @@ #include <uhd/config.hpp> #include <uhd/stream.hpp> #include <uhd/types/ranges.hpp> -#include <uhd/utils/noncopyable.hpp> -#include <memory> #include <uhd/types/stream_cmd.hpp> #include <uhd/types/wb_iface.hpp> +#include <uhd/utils/noncopyable.hpp> +#include <memory> #include <string> class rx_vita_core_3000 : uhd::noncopyable @@ -24,16 +24,13 @@ public: virtual ~rx_vita_core_3000(void) = 0; - static sptr make( - uhd::wb_iface::sptr iface, - const size_t base - ); + static sptr make(uhd::wb_iface::sptr iface, const size_t base); virtual void clear(void) = 0; virtual void set_nsamps_per_packet(const size_t nsamps) = 0; - virtual void issue_stream_command(const uhd::stream_cmd_t &stream_cmd) = 0; + virtual void issue_stream_command(const uhd::stream_cmd_t& stream_cmd) = 0; virtual void set_tick_rate(const double rate) = 0; @@ -41,7 +38,7 @@ public: virtual void handle_overflow(void) = 0; - virtual void setup(const uhd::stream_args_t &stream_args) = 0; + virtual void setup(const uhd::stream_args_t& stream_args) = 0; virtual void configure_flow_control(const size_t window_size) = 0; diff --git a/host/lib/include/uhdlib/usrp/cores/spi_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/spi_core_3000.hpp index 4d08071f7..6dc0474ce 100644 --- a/host/lib/include/uhdlib/usrp/cores/spi_core_3000.hpp +++ b/host/lib/include/uhdlib/usrp/cores/spi_core_3000.hpp @@ -10,16 +10,15 @@ #include <uhd/config.hpp> #include <uhd/types/serial.hpp> -#include <uhd/utils/noncopyable.hpp> #include <uhd/types/wb_iface.hpp> -#include <memory> -#include <memory> +#include <uhd/utils/noncopyable.hpp> #include <functional> +#include <memory> class spi_core_3000 : uhd::noncopyable, public uhd::spi_iface { public: - using sptr = std::shared_ptr<spi_core_3000>; + using sptr = std::shared_ptr<spi_core_3000>; using poke32_fn_t = std::function<void(uint32_t, uint32_t)>; using peek32_fn_t = std::function<uint32_t(uint32_t)>; diff --git a/host/lib/include/uhdlib/usrp/cores/time64_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/time64_core_200.hpp index 4001d7d4d..27ef775f8 100644 --- a/host/lib/include/uhdlib/usrp/cores/time64_core_200.hpp +++ b/host/lib/include/uhdlib/usrp/cores/time64_core_200.hpp @@ -10,18 +10,20 @@ #include <uhd/config.hpp> #include <uhd/types/time_spec.hpp> -#include <uhd/utils/noncopyable.hpp> #include <uhd/types/wb_iface.hpp> +#include <uhd/utils/noncopyable.hpp> #include <boost/utility.hpp> #include <memory> #include <string> #include <vector> -class time64_core_200 : uhd::noncopyable{ +class time64_core_200 : uhd::noncopyable +{ public: typedef std::shared_ptr<time64_core_200> sptr; - struct readback_bases_type{ + struct readback_bases_type + { size_t rb_hi_now, rb_lo_now; size_t rb_hi_pps, rb_lo_pps; }; @@ -29,9 +31,9 @@ public: virtual ~time64_core_200(void) = 0; //! makes a new time64 core from iface and slave base - static sptr make( - uhd::wb_iface::sptr iface, const size_t base, - const readback_bases_type &readback_bases, + static sptr make(uhd::wb_iface::sptr iface, + const size_t base, + const readback_bases_type& readback_bases, const size_t mimo_delay_cycles = 0 // 0 means no-mimo ); @@ -43,14 +45,13 @@ public: virtual uhd::time_spec_t get_time_last_pps(void) = 0; - virtual void set_time_now(const uhd::time_spec_t &time) = 0; + virtual void set_time_now(const uhd::time_spec_t& time) = 0; - virtual void set_time_next_pps(const uhd::time_spec_t &time) = 0; + virtual void set_time_next_pps(const uhd::time_spec_t& time) = 0; - virtual void set_time_source(const std::string &source) = 0; + virtual void set_time_source(const std::string& source) = 0; virtual std::vector<std::string> get_time_sources(void) = 0; - }; #endif /* INCLUDED_LIBUHD_USRP_TIME64_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/time_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/time_core_3000.hpp index 8031ed130..93575bfaa 100644 --- a/host/lib/include/uhdlib/usrp/cores/time_core_3000.hpp +++ b/host/lib/include/uhdlib/usrp/cores/time_core_3000.hpp @@ -10,9 +10,9 @@ #include <uhd/config.hpp> #include <uhd/types/time_spec.hpp> +#include <uhd/types/wb_iface.hpp> #include <uhd/utils/noncopyable.hpp> #include <memory> -#include <uhd/types/wb_iface.hpp> class time_core_3000 : uhd::noncopyable { @@ -28,10 +28,9 @@ public: virtual ~time_core_3000(void) = 0; //! makes a new time core from iface and slave base - static sptr make( - uhd::wb_iface::sptr iface, const size_t base, - const readback_bases_type &readback_bases - ); + static sptr make(uhd::wb_iface::sptr iface, + const size_t base, + const readback_bases_type& readback_bases); virtual void self_test(void) = 0; @@ -41,12 +40,11 @@ public: virtual uhd::time_spec_t get_time_last_pps(void) = 0; - virtual void set_time_now(const uhd::time_spec_t &time) = 0; - - virtual void set_time_sync(const uhd::time_spec_t &time) = 0; + virtual void set_time_now(const uhd::time_spec_t& time) = 0; - virtual void set_time_next_pps(const uhd::time_spec_t &time) = 0; + virtual void set_time_sync(const uhd::time_spec_t& time) = 0; + virtual void set_time_next_pps(const uhd::time_spec_t& time) = 0; }; #endif /* INCLUDED_LIBUHD_USRP_TIME_CORE_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/tx_dsp_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/tx_dsp_core_200.hpp index 86a704c66..55423bceb 100644 --- a/host/lib/include/uhdlib/usrp/cores/tx_dsp_core_200.hpp +++ b/host/lib/include/uhdlib/usrp/cores/tx_dsp_core_200.hpp @@ -11,21 +11,21 @@ #include <uhd/config.hpp> #include <uhd/stream.hpp> #include <uhd/types/ranges.hpp> +#include <uhd/types/wb_iface.hpp> #include <uhd/utils/noncopyable.hpp> #include <memory> -#include <uhd/types/wb_iface.hpp> -class tx_dsp_core_200 : uhd::noncopyable{ +class tx_dsp_core_200 : uhd::noncopyable +{ public: typedef std::shared_ptr<tx_dsp_core_200> sptr; virtual ~tx_dsp_core_200(void) = 0; - static sptr make( - uhd::wb_iface::sptr iface, - const size_t dsp_base, const size_t ctrl_base, - const uint32_t sid - ); + static sptr make(uhd::wb_iface::sptr iface, + const size_t dsp_base, + const size_t ctrl_base, + const uint32_t sid); virtual void clear(void) = 0; @@ -45,7 +45,7 @@ public: virtual void set_updates(const size_t cycles_per_up, const size_t packets_per_up) = 0; - virtual void setup(const uhd::stream_args_t &stream_args) = 0; + virtual void setup(const uhd::stream_args_t& stream_args) = 0; }; #endif /* INCLUDED_LIBUHD_USRP_TX_DSP_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/tx_frontend_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/tx_frontend_core_200.hpp index 8a7178bb4..23a097085 100644 --- a/host/lib/include/uhdlib/usrp/cores/tx_frontend_core_200.hpp +++ b/host/lib/include/uhdlib/usrp/cores/tx_frontend_core_200.hpp @@ -9,14 +9,15 @@ #define INCLUDED_LIBUHD_USRP_RX_FRONTEND_CORE_200_HPP #include <uhd/config.hpp> -#include <uhd/types/wb_iface.hpp> #include <uhd/property_tree.hpp> +#include <uhd/types/wb_iface.hpp> #include <uhd/utils/noncopyable.hpp> -#include <memory> #include <complex> +#include <memory> #include <string> -class tx_frontend_core_200 : uhd::noncopyable{ +class tx_frontend_core_200 : uhd::noncopyable +{ public: typedef std::shared_ptr<tx_frontend_core_200> sptr; @@ -25,16 +26,16 @@ public: virtual ~tx_frontend_core_200(void) = 0; - static sptr make(uhd::wb_iface::sptr iface, const size_t base, const size_t offset=4); + static sptr make( + uhd::wb_iface::sptr iface, const size_t base, const size_t offset = 4); - virtual void set_mux(const std::string &mode) = 0; + virtual void set_mux(const std::string& mode) = 0; - virtual std::complex<double> set_dc_offset(const std::complex<double> &off) = 0; + virtual std::complex<double> set_dc_offset(const std::complex<double>& off) = 0; - virtual void set_iq_balance(const std::complex<double> &cor) = 0; + virtual void set_iq_balance(const std::complex<double>& cor) = 0; virtual void populate_subtree(uhd::property_tree::sptr subtree) = 0; - }; #endif /* INCLUDED_LIBUHD_USRP_RX_FRONTEND_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/tx_vita_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/tx_vita_core_3000.hpp index 9d03549de..22b6865c1 100644 --- a/host/lib/include/uhdlib/usrp/cores/tx_vita_core_3000.hpp +++ b/host/lib/include/uhdlib/usrp/cores/tx_vita_core_3000.hpp @@ -11,10 +11,10 @@ #include <uhd/config.hpp> #include <uhd/stream.hpp> #include <uhd/types/ranges.hpp> -#include <uhd/utils/noncopyable.hpp> -#include <memory> #include <uhd/types/stream_cmd.hpp> #include <uhd/types/wb_iface.hpp> +#include <uhd/utils/noncopyable.hpp> +#include <memory> #include <string> class tx_vita_core_3000 : uhd::noncopyable @@ -22,30 +22,22 @@ class tx_vita_core_3000 : uhd::noncopyable public: typedef std::shared_ptr<tx_vita_core_3000> sptr; - enum fc_monitor_loc { - FC_DEFAULT, - FC_PRE_RADIO, - FC_PRE_FIFO - }; + enum fc_monitor_loc { FC_DEFAULT, FC_PRE_RADIO, FC_PRE_FIFO }; virtual ~tx_vita_core_3000(void) = 0; - static sptr make( - uhd::wb_iface::sptr iface, + static sptr make(uhd::wb_iface::sptr iface, const size_t base, - fc_monitor_loc fc_location = FC_PRE_RADIO - ); + fc_monitor_loc fc_location = FC_PRE_RADIO); - static sptr make_no_radio_buff( - uhd::wb_iface::sptr iface, - const size_t base - ); + static sptr make_no_radio_buff(uhd::wb_iface::sptr iface, const size_t base); virtual void clear(void) = 0; - virtual void setup(const uhd::stream_args_t &stream_args) = 0; + virtual void setup(const uhd::stream_args_t& stream_args) = 0; - virtual void configure_flow_control(const size_t cycs_per_up, const size_t pkts_per_up) = 0; + virtual void configure_flow_control( + const size_t cycs_per_up, const size_t pkts_per_up) = 0; }; #endif /* INCLUDED_LIBUHD_USRP_TX_VITA_CORE_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/user_settings_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/user_settings_core_200.hpp index 810c8fd7e..717b4a8b1 100644 --- a/host/lib/include/uhdlib/usrp/cores/user_settings_core_200.hpp +++ b/host/lib/include/uhdlib/usrp/cores/user_settings_core_200.hpp @@ -9,12 +9,13 @@ #define INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_200_HPP #include <uhd/config.hpp> -#include <uhd/utils/noncopyable.hpp> #include <uhd/types/wb_iface.hpp> +#include <uhd/utils/noncopyable.hpp> #include <boost/utility.hpp> #include <memory> -class user_settings_core_200 : uhd::noncopyable{ +class user_settings_core_200 : uhd::noncopyable +{ public: typedef std::shared_ptr<user_settings_core_200> sptr; typedef std::pair<uint8_t, uint32_t> user_reg_t; @@ -23,7 +24,7 @@ public: static sptr make(uhd::wb_iface::sptr iface, const size_t base); - virtual void set_reg(const user_reg_t ®) = 0; + virtual void set_reg(const user_reg_t& reg) = 0; }; #endif /* INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/user_settings_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/user_settings_core_3000.hpp index 4b6d0bd6c..002b04a3f 100644 --- a/host/lib/include/uhdlib/usrp/cores/user_settings_core_3000.hpp +++ b/host/lib/include/uhdlib/usrp/cores/user_settings_core_3000.hpp @@ -9,17 +9,18 @@ #define INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_3000_HPP #include <uhd/config.hpp> +#include <uhd/types/wb_iface.hpp> #include <boost/utility.hpp> #include <memory> -#include <uhd/types/wb_iface.hpp> -class user_settings_core_3000 : public uhd::wb_iface { +class user_settings_core_3000 : public uhd::wb_iface +{ public: virtual ~user_settings_core_3000() {} - static sptr make( - wb_iface::sptr iface, - const wb_addr_type sr_base_addr, const wb_addr_type rb_reg_addr); + static sptr make(wb_iface::sptr iface, + const wb_addr_type sr_base_addr, + const wb_addr_type rb_reg_addr); }; #endif /* INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/gpio_defs.hpp b/host/lib/include/uhdlib/usrp/gpio_defs.hpp index b16ea7311..09d74cfad 100644 --- a/host/lib/include/uhdlib/usrp/gpio_defs.hpp +++ b/host/lib/include/uhdlib/usrp/gpio_defs.hpp @@ -13,115 +13,90 @@ namespace uhd { namespace usrp { namespace gpio_atr { - enum gpio_atr_mode_t { - MODE_ATR = 0, //Output driven by the auto-transmit-receive engine - MODE_GPIO = 1 //Output value is static - }; - - enum gpio_ddr_t { - DDR_INPUT = 0, - DDR_OUTPUT = 1 - }; - - enum gpio_attr_t { - GPIO_SRC, - GPIO_CTRL, - GPIO_DDR, - GPIO_OUT, - GPIO_ATR_0X, - GPIO_ATR_RX, - GPIO_ATR_TX, - GPIO_ATR_XX, - GPIO_READBACK - }; - - static const std::string GPIO_ATTR_SRC = "SRC"; - //! Attribute name for GPIO control. - static const std::string GPIO_ATTR_CTRL = "CTRL"; - //! Attribute name for GPIO data direction register. - static const std::string GPIO_ATTR_DDR = "DDR"; - //! Attribute name for GPIO ouput value. - static const std::string GPIO_ATTR_OUT = "OUT"; - //! Attribute name for GPIO ATR idle state register. - static const std::string GPIO_ATTR_ATR0X = "ATR_0X"; - //! Attribute name for GPIO ATR receive only register. - static const std::string GPIO_ATTR_ATRRX = "ATR_RX"; - //! Attribute name for GPIO ATR transmit only register. - static const std::string GPIO_ATTR_ATRTX = "ATR_TX"; - //! Attribute name for GPIO ATR full duplex state register. - static const std::string GPIO_ATTR_ATRXX = "ATR_XX"; - //! Attribute name for GPIO READBACK register. - static const std::string GPIO_ATTR_READBACK = "READBACK"; - - typedef std::map<gpio_attr_t, std::string> gpio_attr_map_t; - - static const gpio_attr_map_t gpio_attr_map{ - {GPIO_SRC, GPIO_ATTR_SRC}, - {GPIO_CTRL, GPIO_ATTR_CTRL}, - {GPIO_DDR, GPIO_ATTR_DDR}, - {GPIO_OUT, GPIO_ATTR_OUT}, - {GPIO_ATR_0X, GPIO_ATTR_ATR0X}, - {GPIO_ATR_RX, GPIO_ATTR_ATRRX}, - {GPIO_ATR_TX, GPIO_ATTR_ATRTX}, - {GPIO_ATR_XX, GPIO_ATTR_ATRXX}, - {GPIO_READBACK, GPIO_ATTR_READBACK} - }; - - static const std::map<gpio_attr_t, std::map<uint32_t, std::string>> attr_value_map{ - {GPIO_CTRL, {{0, "ATR"}, {1, "GPIO"}}}, - {GPIO_DDR, {{0, "INPUT"}, {1, "OUTPUT"}}} - }; - - static const std::map<std::string, gpio_attr_t> gpio_attr_rev_map{ - {GPIO_ATTR_SRC, GPIO_SRC}, - {GPIO_ATTR_CTRL, GPIO_CTRL}, - {GPIO_ATTR_DDR, GPIO_DDR}, - {GPIO_ATTR_OUT, GPIO_OUT}, - {GPIO_ATTR_ATR0X, GPIO_ATR_0X}, - {GPIO_ATTR_ATRRX, GPIO_ATR_RX}, - {GPIO_ATTR_ATRTX, GPIO_ATR_TX}, - {GPIO_ATTR_ATRXX, GPIO_ATR_XX}, - {GPIO_ATTR_READBACK, GPIO_READBACK} - }; - - static const gpio_attr_map_t default_attr_value_map{ - {GPIO_SRC, "RADIO_0/0"}, - {GPIO_CTRL, "GPIO"}, - {GPIO_DDR, "INPUT"} - }; - - static const std::map<std::string, uint32_t> gpio_level_map{ - {"HIGH", 1}, - {"LOW", 0}, - {"ON", 1}, - {"OFF", 0}, - {"TRUE", 1}, - {"FALSE", 0} - }; - - static const std::map<std::string, uint32_t> gpio_direction{ - {"OUT", 1}, - {"IN", 0}, - {"OUTPUT", 1}, - {"INPUT", 0} - }; - - static const std::map<std::string, uint32_t> gpio_ctrl_mode{ - {"ATR", 0}, - {"GPIO", 1} - }; - - static const std::map<std::string, std::map<std::string, uint32_t>> gpio_attr_value_pair{ - {GPIO_ATTR_CTRL, uhd::usrp::gpio_atr::gpio_ctrl_mode}, - {GPIO_ATTR_DDR, uhd::usrp::gpio_atr::gpio_direction}, - {GPIO_ATTR_OUT, uhd::usrp::gpio_atr::gpio_level_map}, - {GPIO_ATTR_ATR0X, uhd::usrp::gpio_atr::gpio_level_map}, - {GPIO_ATTR_ATRRX, uhd::usrp::gpio_atr::gpio_level_map}, - {GPIO_ATTR_ATRTX, uhd::usrp::gpio_atr::gpio_level_map}, - {GPIO_ATTR_ATRXX, uhd::usrp::gpio_atr::gpio_level_map}, - {GPIO_ATTR_READBACK, uhd::usrp::gpio_atr::gpio_level_map} - }; - -}}} //namespaces +enum gpio_atr_mode_t { + MODE_ATR = 0, // Output driven by the auto-transmit-receive engine + MODE_GPIO = 1 // Output value is static +}; + +enum gpio_ddr_t { DDR_INPUT = 0, DDR_OUTPUT = 1 }; + +enum gpio_attr_t { + GPIO_SRC, + GPIO_CTRL, + GPIO_DDR, + GPIO_OUT, + GPIO_ATR_0X, + GPIO_ATR_RX, + GPIO_ATR_TX, + GPIO_ATR_XX, + GPIO_READBACK +}; + +static const std::string GPIO_ATTR_SRC = "SRC"; +//! Attribute name for GPIO control. +static const std::string GPIO_ATTR_CTRL = "CTRL"; +//! Attribute name for GPIO data direction register. +static const std::string GPIO_ATTR_DDR = "DDR"; +//! Attribute name for GPIO ouput value. +static const std::string GPIO_ATTR_OUT = "OUT"; +//! Attribute name for GPIO ATR idle state register. +static const std::string GPIO_ATTR_ATR0X = "ATR_0X"; +//! Attribute name for GPIO ATR receive only register. +static const std::string GPIO_ATTR_ATRRX = "ATR_RX"; +//! Attribute name for GPIO ATR transmit only register. +static const std::string GPIO_ATTR_ATRTX = "ATR_TX"; +//! Attribute name for GPIO ATR full duplex state register. +static const std::string GPIO_ATTR_ATRXX = "ATR_XX"; +//! Attribute name for GPIO READBACK register. +static const std::string GPIO_ATTR_READBACK = "READBACK"; + +typedef std::map<gpio_attr_t, std::string> gpio_attr_map_t; + +static const gpio_attr_map_t gpio_attr_map{{GPIO_SRC, GPIO_ATTR_SRC}, + {GPIO_CTRL, GPIO_ATTR_CTRL}, + {GPIO_DDR, GPIO_ATTR_DDR}, + {GPIO_OUT, GPIO_ATTR_OUT}, + {GPIO_ATR_0X, GPIO_ATTR_ATR0X}, + {GPIO_ATR_RX, GPIO_ATTR_ATRRX}, + {GPIO_ATR_TX, GPIO_ATTR_ATRTX}, + {GPIO_ATR_XX, GPIO_ATTR_ATRXX}, + {GPIO_READBACK, GPIO_ATTR_READBACK}}; + +static const std::map<gpio_attr_t, std::map<uint32_t, std::string>> attr_value_map{ + {GPIO_CTRL, {{0, "ATR"}, {1, "GPIO"}}}, {GPIO_DDR, {{0, "INPUT"}, {1, "OUTPUT"}}}}; + +static const std::map<std::string, gpio_attr_t> gpio_attr_rev_map{ + {GPIO_ATTR_SRC, GPIO_SRC}, + {GPIO_ATTR_CTRL, GPIO_CTRL}, + {GPIO_ATTR_DDR, GPIO_DDR}, + {GPIO_ATTR_OUT, GPIO_OUT}, + {GPIO_ATTR_ATR0X, GPIO_ATR_0X}, + {GPIO_ATTR_ATRRX, GPIO_ATR_RX}, + {GPIO_ATTR_ATRTX, GPIO_ATR_TX}, + {GPIO_ATTR_ATRXX, GPIO_ATR_XX}, + {GPIO_ATTR_READBACK, GPIO_READBACK}}; + +static const gpio_attr_map_t default_attr_value_map{ + {GPIO_SRC, "RADIO_0/0"}, {GPIO_CTRL, "GPIO"}, {GPIO_DDR, "INPUT"}}; + +static const std::map<std::string, uint32_t> gpio_level_map{ + {"HIGH", 1}, {"LOW", 0}, {"ON", 1}, {"OFF", 0}, {"TRUE", 1}, {"FALSE", 0}}; + +static const std::map<std::string, uint32_t> gpio_direction{ + {"OUT", 1}, {"IN", 0}, {"OUTPUT", 1}, {"INPUT", 0}}; + +static const std::map<std::string, uint32_t> gpio_ctrl_mode{{"ATR", 0}, {"GPIO", 1}}; + +static const std::map<std::string, std::map<std::string, uint32_t>> gpio_attr_value_pair{ + {GPIO_ATTR_CTRL, uhd::usrp::gpio_atr::gpio_ctrl_mode}, + {GPIO_ATTR_DDR, uhd::usrp::gpio_atr::gpio_direction}, + {GPIO_ATTR_OUT, uhd::usrp::gpio_atr::gpio_level_map}, + {GPIO_ATTR_ATR0X, uhd::usrp::gpio_atr::gpio_level_map}, + {GPIO_ATTR_ATRRX, uhd::usrp::gpio_atr::gpio_level_map}, + {GPIO_ATTR_ATRTX, uhd::usrp::gpio_atr::gpio_level_map}, + {GPIO_ATTR_ATRXX, uhd::usrp::gpio_atr::gpio_level_map}, + {GPIO_ATTR_READBACK, uhd::usrp::gpio_atr::gpio_level_map}}; + +}}} // namespace uhd::usrp::gpio_atr #endif /* INCLUDED_LIBUHD_USRP_GPIO_DEFS_LIB_HPP */ diff --git a/host/lib/include/uhdlib/utils/atomic.hpp b/host/lib/include/uhdlib/utils/atomic.hpp index 303df1bc9..98b1cfa7b 100644 --- a/host/lib/include/uhdlib/utils/atomic.hpp +++ b/host/lib/include/uhdlib/utils/atomic.hpp @@ -14,62 +14,65 @@ #include <atomic> #include <chrono> -namespace uhd{ +namespace uhd { - /*! DEPRECATED -- Will be removed in coming versions of UHD. - * - * Spin-wait on a condition with a timeout. - * \param cond an atomic variable to compare - * \param value compare to atomic for true/false - * \param timeout the timeout in seconds - * \return true for cond == value, false for timeout - */ - template<typename T> - UHD_INLINE bool spin_wait_with_timeout( - std::atomic<T> &cond, - const T value, - const double timeout - ){ - if (cond == value) return true; - const auto exit_time = std::chrono::high_resolution_clock::now() - + std::chrono::microseconds(int64_t(timeout * 1e6)); - while (cond != value) { - if (std::chrono::high_resolution_clock::now() > exit_time) { - return false; - } - boost::this_thread::interruption_point(); - boost::this_thread::yield(); - } +/*! DEPRECATED -- Will be removed in coming versions of UHD. + * + * Spin-wait on a condition with a timeout. + * \param cond an atomic variable to compare + * \param value compare to atomic for true/false + * \param timeout the timeout in seconds + * \return true for cond == value, false for timeout + */ +template <typename T> +UHD_INLINE bool spin_wait_with_timeout( + std::atomic<T>& cond, const T value, const double timeout) +{ + if (cond == value) return true; + const auto exit_time = std::chrono::high_resolution_clock::now() + + std::chrono::microseconds(int64_t(timeout * 1e6)); + while (cond != value) { + if (std::chrono::high_resolution_clock::now() > exit_time) { + return false; + } + boost::this_thread::interruption_point(); + boost::this_thread::yield(); } + return true; +} - /*! DEPRECATED -- Will be removed in coming versions of UHD. - * - * Claimer class to provide synchronization for multi-thread access. - * Claiming enables buffer classes to be used with a buffer queue. - */ - class simple_claimer{ - public: - simple_claimer(void){ - this->release(); - } +/*! DEPRECATED -- Will be removed in coming versions of UHD. + * + * Claimer class to provide synchronization for multi-thread access. + * Claiming enables buffer classes to be used with a buffer queue. + */ +class simple_claimer +{ +public: + simple_claimer(void) + { + this->release(); + } - UHD_INLINE void release(void){ - _locked = false; - } + UHD_INLINE void release(void) + { + _locked = false; + } - UHD_INLINE bool claim_with_wait(const double timeout){ - if (spin_wait_with_timeout(_locked, false, timeout)){ - _locked = true; - return true; - } - return false; + UHD_INLINE bool claim_with_wait(const double timeout) + { + if (spin_wait_with_timeout(_locked, false, timeout)) { + _locked = true; + return true; } + return false; + } - private: - std::atomic<bool> _locked; - }; +private: + std::atomic<bool> _locked; +}; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_UTILS_ATOMIC_HPP */ diff --git a/host/lib/include/uhdlib/utils/auto_timer.hpp b/host/lib/include/uhdlib/utils/auto_timer.hpp index 227750a2f..5d1c88911 100644 --- a/host/lib/include/uhdlib/utils/auto_timer.hpp +++ b/host/lib/include/uhdlib/utils/auto_timer.hpp @@ -17,46 +17,50 @@ #ifdef UHD_PLATFORM_WIN32 // Defines struct tm -#include "time.h" - -#include <windows.h> - -#include <uhd/utils/msg.hpp> +# include "time.h" +# include <uhd/utils/msg.hpp> +# include <windows.h> /*! - * Inserts a timer that logs the duration of its existence (construction to destruction) and the context string to UHD_MSG - * \param context The context string to log in addition to the duration. String buffer MUST be maintained by caling code throughout lifetime of timer object. + * Inserts a timer that logs the duration of its existence (construction to destruction) + * and the context string to UHD_MSG \param context The context string to log in addition + * to the duration. String buffer MUST be maintained by caling code throughout lifetime of + * timer object. */ -#define PROFILE_TIMING(context) \ - uhd::_auto_timer::auto_timer ___at(context); +# define PROFILE_TIMING(context) uhd::_auto_timer::auto_timer ___at(context); /*! - * Inserts a timer that logs the duration (if exceeds threshold) of its existence (construction to destruction) and the context string to UHD_MSG - * \param context The context string to log in addition to the duration. String buffer MUST be maintained by caling code throughout lifetime of timer object. - * \param threshold Only if the lifetime of the timer exceeds this value will it be logged + * Inserts a timer that logs the duration (if exceeds threshold) of its existence + * (construction to destruction) and the context string to UHD_MSG \param context The + * context string to log in addition to the duration. String buffer MUST be maintained by + * caling code throughout lifetime of timer object. \param threshold Only if the lifetime + * of the timer exceeds this value will it be logged */ -#define PROFILE_TIMING_WITH_THRESHOLD(context,threshold) \ - uhd::_auto_timer::auto_timer ___at(context,threshold); +# define PROFILE_TIMING_WITH_THRESHOLD(context, threshold) \ + uhd::_auto_timer::auto_timer ___at(context, threshold); - /*! - * Inserts a timer that logs the duration of its existence (construction to destruction) and the context string to UHD_MSG - * \param context The context string to log in addition to the duration. String buffer MUST be maintained by caling code throughout lifetime of timer object. - * \param unitScale Report duration in ms or us (kUnitScaleMS or kUnitScaleUS) +/*! + * Inserts a timer that logs the duration of its existence (construction to destruction) + * and the context string to UHD_MSG \param context The context string to log in addition + * to the duration. String buffer MUST be maintained by caling code throughout lifetime of + * timer object. \param unitScale Report duration in ms or us (kUnitScaleMS or + * kUnitScaleUS) */ -#define PROFILE_TIMING_WITH_SCALE(context,unitScale) \ - uhd::_auto_timer::auto_timer ___at(context,0,unitScale); - - /*! - * Inserts a timer that logs the duration (if exceeds threshold) of its existence (construction to destruction) and the context string to UHD_MSG - * \param context The context string to log in addition to the duration. String buffer MUST be maintained by caling code throughout lifetime of timer object. - * \param threshold Only if the lifetime of the timer exceeds this value will it be logged - * \param unitScale Report duration in ms or us (kUnitScaleMS or kUnitScaleUS) +# define PROFILE_TIMING_WITH_SCALE(context, unitScale) \ + uhd::_auto_timer::auto_timer ___at(context, 0, unitScale); + +/*! + * Inserts a timer that logs the duration (if exceeds threshold) of its existence + * (construction to destruction) and the context string to UHD_MSG \param context The + * context string to log in addition to the duration. String buffer MUST be maintained by + * caling code throughout lifetime of timer object. \param threshold Only if the lifetime + * of the timer exceeds this value will it be logged \param unitScale Report duration in + * ms or us (kUnitScaleMS or kUnitScaleUS) */ -#define PROFILE_TIMING_WITH_THRESHOLD_AND_SCALE(context,threshold,unitScale) \ - uhd::_auto_timer::auto_timer ___at(context,threshold,unitScale); +# define PROFILE_TIMING_WITH_THRESHOLD_AND_SCALE(context, threshold, unitScale) \ + uhd::_auto_timer::auto_timer ___at(context, threshold, unitScale); -namespace uhd { - namespace _auto_timer { +namespace uhd { namespace _auto_timer { static const uint64_t kUnitScaleMS = 1000; static const uint64_t kUnitScaleUS = 1000000; @@ -65,72 +69,66 @@ static const uint64_t kUnitScaleUS = 1000000; class auto_timer { public: - - auto_timer( - const char* context, - uint64_t reporting_threshold = 0, - uint64_t unit_scale = kUnitScaleUS) : - _context(context), - _reporting_threshold(reporting_threshold), - _unit_scale(unit_scale) - { - ::QueryPerformanceCounter(&_start_time); - switch (unit_scale) - { - case kUnitScaleMS: - _unit_scale_str = "ms"; - break; - case kUnitScaleUS: - default: - _unit_scale_str = "us"; - break; - } - } - - ~auto_timer() - { - LARGE_INTEGER freq; - uint64_t diff_time = 0; - - ::QueryPerformanceCounter(&_end_time); - QueryPerformanceFrequency(&freq); - diff_time = - (uint64_t)(_end_time.QuadPart - _start_time.QuadPart)* - _unit_scale / - freq.QuadPart; - - if (diff_time >= _reporting_threshold) - { - UHD_MSG(status) << "^ " << _context << "\t" << std::dec << diff_time << _unit_scale_str << std::endl; - } - - } + auto_timer(const char* context, + uint64_t reporting_threshold = 0, + uint64_t unit_scale = kUnitScaleUS) + : _context(context) + , _reporting_threshold(reporting_threshold) + , _unit_scale(unit_scale) + { + ::QueryPerformanceCounter(&_start_time); + switch (unit_scale) { + case kUnitScaleMS: + _unit_scale_str = "ms"; + break; + case kUnitScaleUS: + default: + _unit_scale_str = "us"; + break; + } + } + + ~auto_timer() + { + LARGE_INTEGER freq; + uint64_t diff_time = 0; + + ::QueryPerformanceCounter(&_end_time); + QueryPerformanceFrequency(&freq); + diff_time = (uint64_t)(_end_time.QuadPart - _start_time.QuadPart) * _unit_scale + / freq.QuadPart; + + if (diff_time >= _reporting_threshold) { + UHD_MSG(status) << "^ " << _context << "\t" << std::dec << diff_time + << _unit_scale_str << std::endl; + } + } private: - // Usage - auto_timer(); - auto_timer(const auto_timer&); + // Usage + auto_timer(); + auto_timer(const auto_timer&); - LARGE_INTEGER _start_time; - LARGE_INTEGER _end_time; - uint64_t _unit_scale; - uint64_t _reporting_threshold; - const char* _context; - char* _unit_scale_str; + LARGE_INTEGER _start_time; + LARGE_INTEGER _end_time; + uint64_t _unit_scale; + uint64_t _reporting_threshold; + const char* _context; + char* _unit_scale_str; }; // class auto_timer -}} //namespace uhd::_auto_timer +}} // namespace uhd::_auto_timer -#else //non-windows platforms +#else // non-windows platforms -#define PROFILE_TIMING(context) +# define PROFILE_TIMING(context) -#define PROFILE_TIMING_WITH_THRESHOLD(context,threshold) +# define PROFILE_TIMING_WITH_THRESHOLD(context, threshold) -#define PROFILE_TIMING_WITH_SCALE(context,unitScale) +# define PROFILE_TIMING_WITH_SCALE(context, unitScale) -#define PROFILE_TIMING_WITH_THRESHOLD_AND_SCALE(context,threshold,unitScale) +# define PROFILE_TIMING_WITH_THRESHOLD_AND_SCALE(context, threshold, unitScale) #endif diff --git a/host/lib/include/uhdlib/utils/compat_check.hpp b/host/lib/include/uhdlib/utils/compat_check.hpp index 8fe96d118..708c5ab16 100644 --- a/host/lib/include/uhdlib/utils/compat_check.hpp +++ b/host/lib/include/uhdlib/utils/compat_check.hpp @@ -12,31 +12,27 @@ namespace uhd { - /*! Checks for FPGA compatibility, and throws an exception on mismatch. - * - * \throws uhd::runtime_error on mismatch. - */ - void assert_fpga_compat( - const size_t uhd_major, - const size_t uhd_minor, - const uint64_t fpga_compat, - const std::string& fpga_component, - const std::string& log_component, - const bool fail_on_minor_behind=false - ); +/*! Checks for FPGA compatibility, and throws an exception on mismatch. + * + * \throws uhd::runtime_error on mismatch. + */ +void assert_fpga_compat(const size_t uhd_major, + const size_t uhd_minor, + const uint64_t fpga_compat, + const std::string& fpga_component, + const std::string& log_component, + const bool fail_on_minor_behind = false); - /*! Checks for FPGA compatibility, and throws an exception on mismatch. - * - * \throws uhd::runtime_error on mismatch. - */ - void assert_fpga_compat( - const size_t uhd_major, - const size_t uhd_minor, - const uint32_t fpga_compat, - const std::string& fpga_component, - const std::string& log_component, - const bool fail_on_minor_behind=false - ); +/*! Checks for FPGA compatibility, and throws an exception on mismatch. + * + * \throws uhd::runtime_error on mismatch. + */ +void assert_fpga_compat(const size_t uhd_major, + const size_t uhd_minor, + const uint32_t fpga_compat, + const std::string& fpga_component, + const std::string& log_component, + const bool fail_on_minor_behind = false); } /* namespace uhd */ diff --git a/host/lib/include/uhdlib/utils/config_parser.hpp b/host/lib/include/uhdlib/utils/config_parser.hpp index 0cff0868d..13a6346e8 100644 --- a/host/lib/include/uhdlib/utils/config_parser.hpp +++ b/host/lib/include/uhdlib/utils/config_parser.hpp @@ -35,20 +35,20 @@ public: * * \throws uhd::runtime_error if the parsing failed. */ - config_parser(const std::string &path=""); + config_parser(const std::string& path = ""); /*! Load another config file and update the current values. * * If a value exists in both the new and current file, the new value wins. */ - void read_file(const std::string &path); + void read_file(const std::string& path); //! Return a list of sections std::vector<std::string> sections(); //! Return a list of options (keys) in a section, or an empty list if // section does not exist - std::vector<std::string> options(const std::string §ion); + std::vector<std::string> options(const std::string& section); /*! Return the value of a key * @@ -57,15 +57,12 @@ public: * \param def Default value, in case the key does not exist */ template <typename T> - T get( - const std::string §ion, - const std::string &key, - const T &def - ) { + T get(const std::string& section, const std::string& key, const T& def) + { try { const auto child = _pt.get_child(section); return child.get<T>(key, def); - } catch (const boost::property_tree::ptree_bad_path &) { + } catch (const boost::property_tree::ptree_bad_path&) { return def; } } @@ -78,27 +75,20 @@ public: * \throws uhd::key_error if the key or the section don't exist */ template <typename T> - T get( - const std::string §ion, - const std::string &key - ) { + T get(const std::string& section, const std::string& key) + { try { const auto child = _pt.get_child(section); return child.get<T>(key); - } catch (const boost::property_tree::ptree_bad_path &) { - throw uhd::key_error( - std::string("[config_parser] Key ") + key + - " not found in section " + section - ); + } catch (const boost::property_tree::ptree_bad_path&) { + throw uhd::key_error(std::string("[config_parser] Key ") + key + + " not found in section " + section); } } template <typename T> - void set( - const std::string §ion, - const std::string &key, - const T &value - ) { + void set(const std::string& section, const std::string& key, const T& value) + { _pt.put<T>(section + "." + key, value); } diff --git a/host/lib/include/uhdlib/utils/eeprom_utils.hpp b/host/lib/include/uhdlib/utils/eeprom_utils.hpp index 5104e1530..53390b200 100644 --- a/host/lib/include/uhdlib/utils/eeprom_utils.hpp +++ b/host/lib/include/uhdlib/utils/eeprom_utils.hpp @@ -7,19 +7,19 @@ #include <uhd/types/byte_vector.hpp> #include <uhd/types/dict.hpp> #include <uhd/types/mac_addr.hpp> -#include <boost/asio/ip/address_v4.hpp> #include <uhd/utils/log.hpp> +#include <boost/asio/ip/address_v4.hpp> #include <string> #include <vector> -static const size_t SERIAL_LEN = 9; +static const size_t SERIAL_LEN = 9; static const size_t NAME_MAX_LEN = 32 - SERIAL_LEN; //! convert a string to a byte vector to write to eeprom -uhd::byte_vector_t string_to_uint16_bytes(const std::string &num_str); +uhd::byte_vector_t string_to_uint16_bytes(const std::string& num_str); //! convert a byte vector read from eeprom to a string -std::string uint16_bytes_to_string(const uhd::byte_vector_t &bytes); +std::string uint16_bytes_to_string(const uhd::byte_vector_t& bytes); /*! * Check for duplicate values within a given set of keys. Assumes the desire @@ -37,21 +37,18 @@ std::string uint16_bytes_to_string(const uhd::byte_vector_t &bytes); * \return true if duplicates are found, false if not */ template <typename field_type> -bool check_for_duplicates( - const std::string& error_label, +bool check_for_duplicates(const std::string& error_label, const uhd::dict<std::string, std::string>& new_eeprom, const uhd::dict<std::string, std::string>& curr_eeprom, const std::string& category, - const std::vector<std::string>& keys -) { + const std::vector<std::string>& keys) +{ bool has_duplicates = false; - for (size_t i = 0; i < keys.size(); i++) - { + for (size_t i = 0; i < keys.size(); i++) { bool found_duplicate = false; - auto key = keys[i]; + auto key = keys[i]; - if (not new_eeprom.has_key(key)) - { + if (not new_eeprom.has_key(key)) { continue; } @@ -59,38 +56,33 @@ bool check_for_duplicates( // Check other values in new_eeprom for duplicate // Starting at key index i+1 so the same duplicate is not found twice - for (size_t j = i+1; j < keys.size(); j++) - { + for (size_t j = i + 1; j < keys.size(); j++) { auto other_key = keys[j]; - if (not new_eeprom.has_key(other_key)) - { + if (not new_eeprom.has_key(other_key)) { continue; } auto other_value = field_type::from_string(new_eeprom[other_key]).to_string(); - if (value == other_value) - { + if (value == other_value) { // Value is a duplicate of another supplied value - UHD_LOG_ERROR(error_label, "Duplicate " << category << " " - << new_eeprom[key] << " is supplied for both " << key - << " and " << other_key); + UHD_LOG_ERROR(error_label, + "Duplicate " << category << " " << new_eeprom[key] + << " is supplied for both " << key << " and " + << other_key); found_duplicate = true; } } // Check all keys in curr_eeprom for duplicate value - for (auto other_key: keys) - { + for (auto other_key : keys) { // Skip any keys in new_eeprom - if (new_eeprom.has_key(other_key)) - { + if (new_eeprom.has_key(other_key)) { continue; } - if (value == curr_eeprom[other_key]) - { + if (value == curr_eeprom[other_key]) { // Value is duplicate of one in the EEPROM - UHD_LOG_ERROR(error_label, "Duplicate " << category << " " - << new_eeprom[key] << " is already in use for " - << other_key); + UHD_LOG_ERROR(error_label, + "Duplicate " << category << " " << new_eeprom[key] + << " is already in use for " << other_key); found_duplicate = true; } } diff --git a/host/lib/include/uhdlib/utils/ihex.hpp b/host/lib/include/uhdlib/utils/ihex.hpp index ac12a83b5..58e4d5637 100644 --- a/host/lib/include/uhdlib/utils/ihex.hpp +++ b/host/lib/include/uhdlib/utils/ihex.hpp @@ -8,9 +8,8 @@ #ifndef INCLUDED_IHEX_READER_HPP #define INCLUDED_IHEX_READER_HPP -#include <functional> -#include <functional> #include <stdint.h> +#include <functional> #include <string> #include <vector> @@ -20,12 +19,13 @@ class ihex_reader { public: // Arguments are: lower address bits, upper address bits, buff, length - typedef std::function<int(uint16_t,uint16_t,unsigned char*,uint16_t)> record_handle_type; + typedef std::function<int(uint16_t, uint16_t, unsigned char*, uint16_t)> + record_handle_type; /* * \param ihex_filename Path to the *.ihx file */ - ihex_reader(const std::string &ihex_filename); + ihex_reader(const std::string& ihex_filename); /*! Read an Intel HEX file and handle it record by record. * @@ -46,7 +46,7 @@ public: * * \throws uhd::io_error if the HEX file is corrupted or unreadable. */ - void to_bin_file(const std::string &bin_filename); + void to_bin_file(const std::string& bin_filename); /*! Copy the ihex file into a buffer. * @@ -66,4 +66,3 @@ private: }; /* namespace uhd */ #endif /* INCLUDED_IHEX_READER_HPP */ - diff --git a/host/lib/include/uhdlib/utils/isatty.hpp b/host/lib/include/uhdlib/utils/isatty.hpp index cb8d07afb..03ca23893 100644 --- a/host/lib/include/uhdlib/utils/isatty.hpp +++ b/host/lib/include/uhdlib/utils/isatty.hpp @@ -14,40 +14,40 @@ namespace uhd { #ifdef UHD_PLATFORM_WIN32 -# include <io.h> - - /*! Portable version of isatty() - * - * We call it is_a_tty() to distinguish from the from the POSIX version. - * Also, we simply return a Boolean since the Windows version doesn't set - * errno. - */ - bool is_a_tty(const int fd) - { - return uhd::narrow_cast<bool>(_isatty(fd)); - } +# include <io.h> + +/*! Portable version of isatty() + * + * We call it is_a_tty() to distinguish from the from the POSIX version. + * Also, we simply return a Boolean since the Windows version doesn't set + * errno. + */ +bool is_a_tty(const int fd) +{ + return uhd::narrow_cast<bool>(_isatty(fd)); +} #elif _POSIX_C_SOURCE >= _200112L # include <unistd.h> - /*! Portable version of isatty() - * - * We call it is_a_tty() to distinguish from the from the POSIX version. - * Also, we simply return a Boolean since the Windows version doesn't set - * errno. - */ - bool is_a_tty(const int fd) - { - return isatty(fd); - } +/*! Portable version of isatty() + * + * We call it is_a_tty() to distinguish from the from the POSIX version. + * Also, we simply return a Boolean since the Windows version doesn't set + * errno. + */ +bool is_a_tty(const int fd) +{ + return isatty(fd); +} #else - bool is_a_tty(const int fd) - { - return false; - } +bool is_a_tty(const int fd) +{ + return false; +} #endif diff --git a/host/lib/include/uhdlib/utils/math.hpp b/host/lib/include/uhdlib/utils/math.hpp index bcb1b4395..924459ec9 100644 --- a/host/lib/include/uhdlib/utils/math.hpp +++ b/host/lib/include/uhdlib/utils/math.hpp @@ -18,8 +18,9 @@ namespace uhd { namespace math { /*! log2(num), rounded up to the nearest integer. */ template <class T> -T ceil_log2(T num){ - return std::ceil(std::log(num)/std::log(T(2))); +T ceil_log2(T num) +{ + return std::ceil(std::log(num) / std::log(T(2))); } /** diff --git a/host/lib/include/uhdlib/utils/narrow.hpp b/host/lib/include/uhdlib/utils/narrow.hpp index 25acb63d4..daedd55db 100644 --- a/host/lib/include/uhdlib/utils/narrow.hpp +++ b/host/lib/include/uhdlib/utils/narrow.hpp @@ -50,7 +50,7 @@ #if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable : 4127) // conditional expression is constant -#endif // _MSC_VER +#endif // _MSC_VER namespace uhd { @@ -83,8 +83,9 @@ inline T narrow(U u) if (static_cast<U>(t) != u) { throw narrowing_error(""); } - if (!std::integral_constant<bool, std::is_signed<T>::value == std::is_signed<U>::value>::value - && ((t < T{}) != (u < U{}))) { + if (!std::integral_constant<bool, + std::is_signed<T>::value == std::is_signed<U>::value>::value + && ((t < T{}) != (u < U{}))) { throw narrowing_error(""); } return t; diff --git a/host/lib/include/uhdlib/utils/paths.hpp b/host/lib/include/uhdlib/utils/paths.hpp index d74973301..7f0dc4046 100644 --- a/host/lib/include/uhdlib/utils/paths.hpp +++ b/host/lib/include/uhdlib/utils/paths.hpp @@ -11,14 +11,13 @@ namespace uhd { - /*! Expand environment variables in paths, like Python's - * os.path.expandvars(). - * - * If expansion fails, will simply return the original path. - */ - std::string path_expandvars(const std::string& path); +/*! Expand environment variables in paths, like Python's + * os.path.expandvars(). + * + * If expansion fails, will simply return the original path. + */ +std::string path_expandvars(const std::string& path); } /* namespace uhd */ #endif /* INCLUDED_UHDLIB_UTILS_PATHS_HPP */ - diff --git a/host/lib/include/uhdlib/utils/prefs.hpp b/host/lib/include/uhdlib/utils/prefs.hpp index e528450cd..6d75ac7ea 100644 --- a/host/lib/include/uhdlib/utils/prefs.hpp +++ b/host/lib/include/uhdlib/utils/prefs.hpp @@ -13,76 +13,75 @@ namespace uhd { namespace prefs { - /*! Return a reference to an object representing the UHD config file - * state. - * - * Note: Don't call this in static initializers. - */ - config_parser& get_uhd_config(); +/*! Return a reference to an object representing the UHD config file + * state. + * + * Note: Don't call this in static initializers. + */ +config_parser& get_uhd_config(); - /*! Convenience function to update device args with settings from - * config files. - * - * Assume the user has a configuration file as such: - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.ini} - * [type=b200] - * master_clock_rate=20e6 - * - * [serial=f42f9b] ; Let's assume this is another B200 - * master_clock_rate=10e6 - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * If get_usrp_args() gets called with "type" key equal to "b200", it will - * first apply the `master_clock_rate=20e6` settings, as if they had been - * passed in as device args into the initialization sequence. If the device - * happens to have the serial number listed above, i.e., "serial" equals - * "f42f9b", then the new value `master_clock_rate=10e6` will get applied. - * - * If the user actually specified their own value of `master_clock_rate`, - * that value would get applied. - * - * - * \param user_args After getting the device args from the config - * files, all of these key/value pairs will be applied - * and will overwrite the settings from config files - * if they exist. - */ - uhd::device_addr_t get_usrp_args(const uhd::device_addr_t &user_args); +/*! Convenience function to update device args with settings from + * config files. + * + * Assume the user has a configuration file as such: + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.ini} + * [type=b200] + * master_clock_rate=20e6 + * + * [serial=f42f9b] ; Let's assume this is another B200 + * master_clock_rate=10e6 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * If get_usrp_args() gets called with "type" key equal to "b200", it will + * first apply the `master_clock_rate=20e6` settings, as if they had been + * passed in as device args into the initialization sequence. If the device + * happens to have the serial number listed above, i.e., "serial" equals + * "f42f9b", then the new value `master_clock_rate=10e6` will get applied. + * + * If the user actually specified their own value of `master_clock_rate`, + * that value would get applied. + * + * + * \param user_args After getting the device args from the config + * files, all of these key/value pairs will be applied + * and will overwrite the settings from config files + * if they exist. + */ +uhd::device_addr_t get_usrp_args(const uhd::device_addr_t& user_args); - /*! Convenience function to update global DPDK args with settings from - * config files. - * - * Searches for a profile attached to the dpdk-conf key, like this: - * [dpdk-conf=myconfig] - * num_mbufs=4095 - * mbuf_cache_size=315 - * mtu=8000 - * - * \param user_args After getting the device args from the config - * files, all of these key/value pairs will be applied - * and will overwrite the settings from config files - * if they exist. - */ - uhd::device_addr_t get_dpdk_args(const uhd::device_addr_t &user_args); +/*! Convenience function to update global DPDK args with settings from + * config files. + * + * Searches for a profile attached to the dpdk-conf key, like this: + * [dpdk-conf=myconfig] + * num_mbufs=4095 + * mbuf_cache_size=315 + * mtu=8000 + * + * \param user_args After getting the device args from the config + * files, all of these key/value pairs will be applied + * and will overwrite the settings from config files + * if they exist. + */ +uhd::device_addr_t get_dpdk_args(const uhd::device_addr_t& user_args); - /*! Convenience function to update per-NIC DPDK args with settings from - * config files. - * - * Grabs settings based on provided MAC address. Sections created like so: - * [dpdk-mac=00:01:02:03:04:05] - * dpdk-ipv4 = 192.168.20.1/24 - * dpdk-io-cpu = 1 - * - * [dpdk-mac=00:01:02:03:04:06] - * dpdk-ipv4 = 192.168.40.1/24 - * dpdk-io-cpu = 1 - * - * \param user_args After getting the device args from the config - * files, all of these key/value pairs will be applied - * and will overwrite the settings from config files - * if they exist. - */ - uhd::device_addr_t get_dpdk_nic_args(const uhd::device_addr_t &user_args); +/*! Convenience function to update per-NIC DPDK args with settings from + * config files. + * + * Grabs settings based on provided MAC address. Sections created like so: + * [dpdk-mac=00:01:02:03:04:05] + * dpdk-ipv4 = 192.168.20.1/24 + * dpdk-io-cpu = 1 + * + * [dpdk-mac=00:01:02:03:04:06] + * dpdk-ipv4 = 192.168.40.1/24 + * dpdk-io-cpu = 1 + * + * \param user_args After getting the device args from the config + * files, all of these key/value pairs will be applied + * and will overwrite the settings from config files + * if they exist. + */ +uhd::device_addr_t get_dpdk_nic_args(const uhd::device_addr_t& user_args); }} /* namespace uhd::prefs */ #endif /* INCLUDED_LIBUHD_UTILS_PREFS_HPP */ - diff --git a/host/lib/include/uhdlib/utils/semaphore.hpp b/host/lib/include/uhdlib/utils/semaphore.hpp index ae77ed102..fc869d64a 100644 --- a/host/lib/include/uhdlib/utils/semaphore.hpp +++ b/host/lib/include/uhdlib/utils/semaphore.hpp @@ -9,7 +9,7 @@ #include <mutex> #ifndef INCLUDED_UHDLIB_UTILS_SEMAPHORE_HPP -#define INCLUDED_UHDLIB_UTILS_SEMAPHORE_HPP +# define INCLUDED_UHDLIB_UTILS_SEMAPHORE_HPP namespace uhd { diff --git a/host/lib/include/uhdlib/utils/system_time.hpp b/host/lib/include/uhdlib/utils/system_time.hpp index 30cd5a673..1465460d2 100644 --- a/host/lib/include/uhdlib/utils/system_time.hpp +++ b/host/lib/include/uhdlib/utils/system_time.hpp @@ -8,11 +8,11 @@ namespace uhd { - /*! - * Get the system time in time_spec_t format. - * Uses the highest precision clock available. - * \return the system time as a time_spec_t - */ - time_spec_t get_system_time(void); +/*! + * Get the system time in time_spec_t format. + * Uses the highest precision clock available. + * \return the system time as a time_spec_t + */ +time_spec_t get_system_time(void); }; /* namespace uhd */ diff --git a/host/lib/property_tree.cpp b/host/lib/property_tree.cpp index 599f610ad..ba9670913 100644 --- a/host/lib/property_tree.cpp +++ b/host/lib/property_tree.cpp @@ -8,9 +8,9 @@ #include <uhd/property_tree.hpp> #include <uhd/types/dict.hpp> -#include <memory> #include <boost/thread/mutex.hpp> #include <iostream> +#include <memory> #include <typeindex> using namespace uhd; @@ -157,7 +157,8 @@ public: return prop; } - void _create(const fs_path& path_, const std::shared_ptr<void>& prop, + void _create(const fs_path& path_, + const std::shared_ptr<void>& prop, std::type_index prop_type) { const fs_path path = _root / path_; @@ -172,7 +173,7 @@ public: if (node->prop.get() != NULL) throw uhd::runtime_error( "Cannot create! Property already exists at: " + path); - node->prop = prop; + node->prop = prop; node->prop_type_hash = prop_type.hash_code(); } @@ -207,7 +208,8 @@ public: if (node->prop.get() == NULL) throw uhd::runtime_error("Cannot access! Property uninitialized at: " + path); if (node->prop_type_hash != expected_prop_type.hash_code()) - throw uhd::runtime_error("Cannot access! Property types do not match at: " + path); + throw uhd::runtime_error( + "Cannot access! Property types do not match at: " + path); return node->prop; } diff --git a/host/lib/rfnoc/actions.cpp b/host/lib/rfnoc/actions.cpp index 3276c456c..86bc576f3 100644 --- a/host/lib/rfnoc/actions.cpp +++ b/host/lib/rfnoc/actions.cpp @@ -11,9 +11,9 @@ using namespace uhd::rfnoc; namespace { - // A static counter, which we use to uniquely label actions - std::atomic<size_t> action_counter{0}; -} +// A static counter, which we use to uniquely label actions +std::atomic<size_t> action_counter{0}; +} // namespace action_info::action_info(const std::string& key, const uhd::device_addr_t& args) : id(action_counter++), key(key), args(args) @@ -72,7 +72,8 @@ rx_event_action_info::sptr rx_event_action_info::make( /*** TX Metadata Action Info *************************************************/ tx_event_action_info::tx_event_action_info( - uhd::async_metadata_t::event_code_t event_code_, const boost::optional<uint64_t>& tsf_) + uhd::async_metadata_t::event_code_t event_code_, + const boost::optional<uint64_t>& tsf_) : action_info(ACTION_KEY_TX_EVENT), event_code(event_code_), has_tsf(tsf_) { if (has_tsf) { diff --git a/host/lib/rfnoc/chdr_ctrl_xport.cpp b/host/lib/rfnoc/chdr_ctrl_xport.cpp index 043055b75..a59d56b30 100644 --- a/host/lib/rfnoc/chdr_ctrl_xport.cpp +++ b/host/lib/rfnoc/chdr_ctrl_xport.cpp @@ -23,20 +23,18 @@ chdr_ctrl_xport::chdr_ctrl_xport(io_service::sptr io_srv, : _my_epid(my_epid), _recv_packet(pkt_factory.make_generic()) { /* Make dumb send pipe */ - send_io_if::send_callback_t send_cb = [this](frame_buff::uptr buff, - send_link_if* link) { + send_io_if::send_callback_t send_cb = [this]( + frame_buff::uptr buff, send_link_if* link) { link->release_send_buff(std::move(buff)); }; _send_if = io_srv->make_send_client( send_link, num_send_frames, send_cb, recv_link_if::sptr(), 0, nullptr, nullptr); /* Make dumb recv pipe that matches management and control packets */ - uhd::transport::recv_callback_t ctrl_recv_cb = [this](frame_buff::uptr& buff, - recv_link_if* /*recv_link*/, - send_link_if - * /*send_link*/) -> bool { - return this->_ctrl_recv_cb(buff); - }; + uhd::transport::recv_callback_t ctrl_recv_cb = + [this](frame_buff::uptr& buff, + recv_link_if* /*recv_link*/, + send_link_if * /*send_link*/) -> bool { return this->_ctrl_recv_cb(buff); }; recv_io_if::fc_callback_t release_cb = [this](frame_buff::uptr buff, recv_link_if* link, send_link_if* /*send_link*/) { @@ -46,12 +44,10 @@ chdr_ctrl_xport::chdr_ctrl_xport(io_service::sptr io_srv, _ctrl_recv_if = io_srv->make_recv_client( recv_link, num_recv_frames, ctrl_recv_cb, send_link_if::sptr(), 0, release_cb); - uhd::transport::recv_callback_t mgmt_recv_cb = [this](frame_buff::uptr& buff, - recv_link_if* /*recv_link*/, - send_link_if - * /*send_link*/) -> bool { - return this->_mgmt_recv_cb(buff); - }; + uhd::transport::recv_callback_t mgmt_recv_cb = + [this](frame_buff::uptr& buff, + recv_link_if* /*recv_link*/, + send_link_if * /*send_link*/) -> bool { return this->_mgmt_recv_cb(buff); }; _mgmt_recv_if = io_srv->make_recv_client( recv_link, 1, mgmt_recv_cb, send_link_if::sptr(), 0, release_cb); @@ -89,8 +85,8 @@ bool chdr_ctrl_xport::_mgmt_recv_cb(uhd::transport::frame_buff::uptr& buff) return false; } -void chdr_ctrl_xport::_release_cb(uhd::transport::frame_buff::uptr buff, - uhd::transport::recv_link_if* recv_link) +void chdr_ctrl_xport::_release_cb( + uhd::transport::frame_buff::uptr buff, uhd::transport::recv_link_if* recv_link) { recv_link->release_recv_buff(std::move(buff)); } diff --git a/host/lib/rfnoc/chdr_packet.cpp b/host/lib/rfnoc/chdr_packet.cpp index d4b7494e2..fc6c24838 100644 --- a/host/lib/rfnoc/chdr_packet.cpp +++ b/host/lib/rfnoc/chdr_packet.cpp @@ -115,8 +115,8 @@ public: + (chdr_w_stride * (_mdata_offset + get_chdr_header().get_num_mdata()))); } - virtual size_t calculate_payload_offset(const packet_type_t pkt_type, - const uint8_t num_mdata = 0) const + virtual size_t calculate_payload_offset( + const packet_type_t pkt_type, const uint8_t num_mdata = 0) const { chdr_header header; header.set_pkt_type(pkt_type); diff --git a/host/lib/rfnoc/chdr_tx_data_xport.cpp b/host/lib/rfnoc/chdr_tx_data_xport.cpp index 8837e2dbe..321b6ea85 100644 --- a/host/lib/rfnoc/chdr_tx_data_xport.cpp +++ b/host/lib/rfnoc/chdr_tx_data_xport.cpp @@ -62,9 +62,7 @@ chdr_tx_data_xport::chdr_tx_data_xport(uhd::transport::io_service::sptr io_srv, return this->_recv_callback(buff, recv_link, send_link); }; - auto fc_cb = [this](size_t num_bytes) { - return this->_fc_callback(num_bytes); - }; + auto fc_cb = [this](size_t num_bytes) { return this->_fc_callback(num_bytes); }; // Needs just a single recv frame for strs packets _send_io = io_srv->make_send_client(send_link, diff --git a/host/lib/rfnoc/ctrlport_endpoint.cpp b/host/lib/rfnoc/ctrlport_endpoint.cpp index 43bbf815c..f259f8f5d 100644 --- a/host/lib/rfnoc/ctrlport_endpoint.cpp +++ b/host/lib/rfnoc/ctrlport_endpoint.cpp @@ -297,9 +297,9 @@ public: // Flow control not needed because we have allocated special room in the // buffer for async message responses ctrl_payload tx_ctrl(rx_ctrl); - tx_ctrl.is_ack = true; - tx_ctrl.src_epid = _my_epid; - tx_ctrl.status = status; + tx_ctrl.is_ack = true; + tx_ctrl.src_epid = _my_epid; + tx_ctrl.status = status; const auto timeout = [&]() { std::unique_lock<std::mutex> lock(_mutex); return _policy.timeout; @@ -368,7 +368,6 @@ private: const uhd::time_spec_t& time_spec, const steady_clock::time_point& timeout_time) { - if (!_client_clk.is_running()) { throw uhd::system_error("Ctrlport client clock is not running"); } @@ -411,9 +410,8 @@ private: if (!buff_not_full()) { // If we're sending a timed command or if we have a timed command in the // queue, use the MASSIVE_TIMEOUT instead - auto timed_timeout = (check_timed_in_queue() - ? start_timeout(MASSIVE_TIMEOUT) - : timeout_time); + auto timed_timeout = + (check_timed_in_queue() ? start_timeout(MASSIVE_TIMEOUT) : timeout_time); if (not _buff_free_cond.wait_until(lock, timed_timeout, buff_not_full)) { throw uhd::op_timeout( "Control operation timed out waiting for space in command buffer"); diff --git a/host/lib/rfnoc/ddc_block_control.cpp b/host/lib/rfnoc/ddc_block_control.cpp index 8ab76f8ae..8942d128d 100644 --- a/host/lib/rfnoc/ddc_block_control.cpp +++ b/host/lib/rfnoc/ddc_block_control.cpp @@ -369,8 +369,7 @@ private: "Calling resolver for `samp_rate_out/scaling_out'@" << chan); if (samp_rate_out.is_valid()) { if (samp_rate_in.is_valid()) { - decim = - coerce_decim(samp_rate_in.get() / samp_rate_out.get()); + decim = coerce_decim(samp_rate_in.get() / samp_rate_out.get()); set_decim(decim.get(), chan); } // If decim is dirty, it will trigger the decim resolver. diff --git a/host/lib/rfnoc/device_id.cpp b/host/lib/rfnoc/device_id.cpp index 6bd287dce..ade4a3b8f 100644 --- a/host/lib/rfnoc/device_id.cpp +++ b/host/lib/rfnoc/device_id.cpp @@ -14,4 +14,3 @@ device_id_t uhd::rfnoc::allocate_device_id() static std::atomic<device_id_t> counter{1}; return counter++; } - diff --git a/host/lib/rfnoc/fft_block_control.cpp b/host/lib/rfnoc/fft_block_control.cpp index 266eb3e7f..c002d49bb 100644 --- a/host/lib/rfnoc/fft_block_control.cpp +++ b/host/lib/rfnoc/fft_block_control.cpp @@ -8,7 +8,6 @@ #include <uhd/rfnoc/defaults.hpp> #include <uhd/rfnoc/fft_block_control.hpp> #include <uhd/rfnoc/registry.hpp> - #include <string> using namespace uhd::rfnoc; @@ -57,7 +56,6 @@ public: private: - /************************************************************************** * Initialization *************************************************************************/ @@ -80,18 +78,17 @@ private: this->regs().poke32(SR_MAGNITUDE_OUT, uint32_t(this->_shift.get())); }); - //register edge properties + // register edge properties register_property(&_type_in); register_property(&_type_out); - //add resolvers for type (keeps it constant) + // add resolvers for type (keeps it constant) add_property_resolver({&_type_in}, {&_type_in}, [& type_in = _type_in]() { type_in.set(IO_TYPE_SC16); }); add_property_resolver({&_type_out}, {&_type_out}, [& type_out = _type_out]() { type_out.set(IO_TYPE_SC16); }); - } property_t<int> _size{PROP_KEY_FFT_LEN, DEFAULT_SIZE, {res_source_info::USER}}; diff --git a/host/lib/rfnoc/graph.cpp b/host/lib/rfnoc/graph.cpp index f3977f79e..56ebba5b8 100644 --- a/host/lib/rfnoc/graph.cpp +++ b/host/lib/rfnoc/graph.cpp @@ -18,7 +18,7 @@ using namespace uhd::rfnoc::detail; namespace { -const std::string LOG_ID = "RFNOC::GRAPH::DETAIL"; +const std::string LOG_ID = "RFNOC::GRAPH::DETAIL"; constexpr unsigned MAX_ACTION_ITERATIONS = 200; /*! Helper function to pretty-print edge info @@ -275,8 +275,8 @@ void graph_t::resolve_all_properties( } // Start iterating over nodes - bool forward_dir = true; - int num_iterations = 0; + bool forward_dir = true; + int num_iterations = 0; // If all edge properties were known at the beginning, a single iteration // would suffice. However, usually during the first time the property // propagation is run, blocks create new (dynamic) edge properties that @@ -425,10 +425,10 @@ void graph_t::enqueue_action( } // Unpack next action - auto& next_action = _action_queue.front(); - node_ref_t action_src_node = std::get<0>(next_action); - res_source_info action_src_port = std::get<1>(next_action); - action_info::sptr next_action_sptr = std::get<2>(next_action); + auto& next_action = _action_queue.front(); + node_ref_t action_src_node = std::get<0>(next_action); + res_source_info action_src_port = std::get<1>(next_action); + action_info::sptr next_action_sptr = std::get<2>(next_action); _action_queue.pop_front(); // Find the node that is supposed to receive this action, and if we find @@ -592,7 +592,7 @@ bool graph_t::_assert_edge_props_consistent(rfnoc_graph_t::edge_descriptor edge) void graph_t::_check_topology() { node_accessor_t node_accessor{}; - bool topo_ok = true; + bool topo_ok = true; auto v_iterators = boost::vertices(_graph); for (auto it = v_iterators.first; it != v_iterators.second; ++it) { node_ref_t node = boost::get(vertex_property_t(), _graph, *it); @@ -654,4 +654,3 @@ std::pair<graph_t::node_ref_t, graph_t::graph_edge_t> graph_t::_find_neighbour( UHD_THROW_INVALID_CODE_PATH(); } - diff --git a/host/lib/rfnoc/graph_stream_manager.cpp b/host/lib/rfnoc/graph_stream_manager.cpp index f8acab9f2..be2dff3ce 100644 --- a/host/lib/rfnoc/graph_stream_manager.cpp +++ b/host/lib/rfnoc/graph_stream_manager.cpp @@ -10,8 +10,8 @@ #include <uhdlib/rfnoc/link_stream_manager.hpp> #include <uhdlib/transport/links.hpp> #include <boost/format.hpp> -#include <memory> #include <map> +#include <memory> #include <set> using namespace uhd; diff --git a/host/lib/rfnoc/mb_controller.cpp b/host/lib/rfnoc/mb_controller.cpp index 62ec1f886..356224f83 100644 --- a/host/lib/rfnoc/mb_controller.cpp +++ b/host/lib/rfnoc/mb_controller.cpp @@ -127,12 +127,12 @@ uhd::time_spec_t mb_controller::timekeeper::get_time_last_pps() return time_spec_t::from_ticks(get_ticks_last_pps(), _tick_rate); } -void mb_controller::timekeeper::set_time_now(const uhd::time_spec_t &time) +void mb_controller::timekeeper::set_time_now(const uhd::time_spec_t& time) { set_ticks_now(time.to_ticks(_tick_rate)); } -void mb_controller::timekeeper::set_time_next_pps(const uhd::time_spec_t &time) +void mb_controller::timekeeper::set_time_next_pps(const uhd::time_spec_t& time) { set_ticks_next_pps(time.to_ticks(_tick_rate)); } @@ -146,7 +146,8 @@ void mb_controller::timekeeper::set_tick_rate(const double tick_rate) // The period is the inverse of the tick rate, normalized by nanoseconds, // and represented as Q32 (e.g., period == 1ns means period_ns == 1<<32) - const uint64_t period_ns = static_cast<uint64_t>(1e9 / tick_rate * (uint64_t(1) << 32)); + const uint64_t period_ns = + static_cast<uint64_t>(1e9 / tick_rate * (uint64_t(1) << 32)); set_period(period_ns); } diff --git a/host/lib/rfnoc/mock_block.cpp b/host/lib/rfnoc/mock_block.cpp index 867311097..ee35eae7e 100644 --- a/host/lib/rfnoc/mock_block.cpp +++ b/host/lib/rfnoc/mock_block.cpp @@ -49,4 +49,3 @@ uhd::rfnoc::mock_block_container uhd::rfnoc::get_mock_block(const noc_id_t noc_i // Make block and return return ret_val; } - diff --git a/host/lib/rfnoc/noc_block_base.cpp b/host/lib/rfnoc/noc_block_base.cpp index 8f76ac1d1..98466d8eb 100644 --- a/host/lib/rfnoc/noc_block_base.cpp +++ b/host/lib/rfnoc/noc_block_base.cpp @@ -29,9 +29,9 @@ noc_block_base::noc_block_base(make_args_ptr make_args) , _block_args(make_args->args) , _tree(make_args->tree) { - RFNOC_LOG_TRACE( - "Using timebase clock: `" << _tb_clock_iface->get_name() << "'. Current frequency: " - << (_tb_clock_iface->get_freq() / 1e6) << " MHz"); + RFNOC_LOG_TRACE("Using timebase clock: `" + << _tb_clock_iface->get_name() << "'. Current frequency: " + << (_tb_clock_iface->get_freq() / 1e6) << " MHz"); RFNOC_LOG_TRACE("Using ctrlport clock: `" << _ctrlport_clock_iface->get_name() << "'. Current frequency: " << (_ctrlport_clock_iface->get_freq() / 1e6) << " MHz"); @@ -171,7 +171,7 @@ void noc_block_base::set_tick_rate(const double tick_rate) return; } // Update this node - RFNOC_LOG_TRACE("Setting tb clock freq to " << tick_rate/1e6 << " MHz"); + RFNOC_LOG_TRACE("Setting tb clock freq to " << tick_rate / 1e6 << " MHz"); _tb_clock_iface->set_freq(tick_rate); // Now trigger property propagation if (!_tick_rate_props.empty()) { diff --git a/host/lib/rfnoc/node.cpp b/host/lib/rfnoc/node.cpp index 23d5a340d..ff3df7b76 100644 --- a/host/lib/rfnoc/node.cpp +++ b/host/lib/rfnoc/node.cpp @@ -91,7 +91,7 @@ void node_t::clear_command_time(const size_t instance) void node_t::register_property(property_base_t* prop, resolve_callback_t&& clean_callback) { std::lock_guard<std::mutex> _l(_prop_mutex); - const auto src_type = prop->get_src_info().type; + const auto src_type = prop->get_src_info().type; // If the map is empty for this source type, create an empty vector if (_props.count(src_type) == 0) { @@ -99,9 +99,9 @@ void node_t::register_property(property_base_t* prop, resolve_callback_t&& clean } auto prop_already_registered = [prop](const property_base_t* existing_prop) { - return (prop == existing_prop) || - (prop->get_src_info() == existing_prop->get_src_info() - && prop->get_id() == existing_prop->get_id()); + return (prop == existing_prop) + || (prop->get_src_info() == existing_prop->get_src_info() + && prop->get_id() == existing_prop->get_id()); }; if (!filter_props(prop_already_registered).empty()) { throw uhd::runtime_error(std::string("Attempting to double-register property: ") @@ -168,9 +168,7 @@ void node_t::set_action_forwarding_policy( _action_fwd_policies[action_key] = policy; } -void node_t::post_action( - const res_source_info& edge_info, - action_info::sptr action) +void node_t::post_action(const res_source_info& edge_info, action_info::sptr action) { _post_action_cb(edge_info, action); } @@ -230,7 +228,7 @@ property_base_t* node_t::inject_edge_property( // We need to create a new property and stash it away: new_prop = [&]() -> property_base_t* { auto prop = blueprint->clone(new_src_info); - auto ptr = prop.get(); + auto ptr = prop.get(); _dynamic_props.emplace(std::move(prop)); return ptr; }(); @@ -269,12 +267,11 @@ property_base_t* node_t::inject_edge_property( } if (fwd_policy == forwarding_policy_t::ONE_TO_FAN) { const auto opposite_port_type = res_source_info::invert_edge(port_type); - const size_t num_ports = opposite_port_type == res_source_info::INPUT_EDGE + const size_t num_ports = opposite_port_type == res_source_info::INPUT_EDGE ? get_num_input_ports() : get_num_output_ports(); for (size_t i = 0; i < num_ports; i++) { - auto opposite_prop = - inject_edge_property(new_prop, {opposite_port_type, i}); + auto opposite_prop = inject_edge_property(new_prop, {opposite_port_type, i}); // Now add a resolver that will always forward the value from this // property to the other one. add_property_resolver( @@ -302,9 +299,8 @@ property_base_t* node_t::inject_edge_property( if (other_port_idx == port_idx) { continue; } - auto prop = - _find_property({res_source_info::INPUT_EDGE, other_port_idx}, - new_prop->get_id()); + auto prop = _find_property( + {res_source_info::INPUT_EDGE, other_port_idx}, new_prop->get_id()); if (prop) { prop_accessor_t{}.forward<false>(new_prop, prop); } @@ -319,7 +315,8 @@ property_base_t* node_t::inject_edge_property( if (port_type == res_source_info::OUTPUT_EDGE && other_port_idx == port_idx) { continue; } - inject_edge_property(new_prop, {res_source_info::OUTPUT_EDGE, other_port_idx}); + inject_edge_property( + new_prop, {res_source_info::OUTPUT_EDGE, other_port_idx}); } // Now add a dynamic resolver that will update all input properties. // In order to keep this code simple, we bypass the write list and @@ -330,9 +327,8 @@ property_base_t* node_t::inject_edge_property( if (other_port_idx == port_idx) { continue; } - auto prop = - _find_property({res_source_info::OUTPUT_EDGE, other_port_idx}, - new_prop->get_id()); + auto prop = _find_property( + {res_source_info::OUTPUT_EDGE, other_port_idx}, new_prop->get_id()); if (prop) { prop_accessor_t{}.forward<false>(new_prop, prop); } @@ -365,7 +361,8 @@ void node_t::init_props() << "Failed to initialize node. Most likely cause: Inconsistent default " "values. Resolver threw this error: " << ex.what(); - //throw uhd::runtime_error(std::string("Failed to initialize node ") + get_unique_id()); + // throw uhd::runtime_error(std::string("Failed to initialize node ") + + // get_unique_id()); } // 3) Set outputs back to RO @@ -482,12 +479,12 @@ void node_t::forward_edge_property( // Set of local properties that match incoming_prop. It can be an empty set, // or, if the node is misconfigured, a set with more than one entry. Or, if // all is as expected, it's a set with a single entry. - auto local_prop_set = filter_props([prop_src_type, incoming_prop, incoming_port]( - property_base_t* prop) -> bool { - return prop->get_src_info().type == prop_src_type - && prop->get_src_info().instance == incoming_port - && prop->get_id() == incoming_prop->get_id(); - }); + auto local_prop_set = filter_props( + [prop_src_type, incoming_prop, incoming_port](property_base_t* prop) -> bool { + return prop->get_src_info().type == prop_src_type + && prop->get_src_info().instance == incoming_port + && prop->get_id() == incoming_prop->get_id(); + }); // If there is no such property, we're forwarding a new property if (local_prop_set.empty()) { @@ -530,8 +527,7 @@ void node_t::receive_action(const res_source_info& src_info, action_info::sptr a // Now implement custom forwarding for all forwarding policies: if (fwd_policy == forwarding_policy_t::DROP) { - UHD_LOG_TRACE( - get_unique_id(), "Dropping action " << action->key); + UHD_LOG_TRACE(get_unique_id(), "Dropping action " << action->key); } if (fwd_policy == forwarding_policy_t::ONE_TO_ONE) { UHD_LOG_TRACE( @@ -589,4 +585,3 @@ bool node_t::_has_port(const res_source_info& port_info) const || (port_info.type == res_source_info::OUTPUT_EDGE && port_info.instance <= get_num_output_ports()); } - diff --git a/host/lib/rfnoc/null_block_control.cpp b/host/lib/rfnoc/null_block_control.cpp index 443c2f3d7..8a5ab56a5 100644 --- a/host/lib/rfnoc/null_block_control.cpp +++ b/host/lib/rfnoc/null_block_control.cpp @@ -4,9 +4,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include <uhd/rfnoc/defaults.hpp> #include <uhd/rfnoc/null_block_control.hpp> #include <uhd/rfnoc/registry.hpp> -#include <uhd/rfnoc/defaults.hpp> #include <atomic> namespace { @@ -41,9 +41,9 @@ public: RFNOC_BLOCK_CONSTRUCTOR(null_block_control) { uint32_t initial_state = regs().peek32(REG_CTRL_STATUS); - _streaming = initial_state & 0x2; - _nipc = (initial_state >> 24) & 0xFF; - _item_width = (initial_state >> 16) & 0xFF; + _streaming = initial_state & 0x2; + _nipc = (initial_state >> 24) & 0xFF; + _item_width = (initial_state >> 16) & 0xFF; reset_counters(); register_issue_stream_cmd(); } @@ -121,17 +121,17 @@ public: return regs().peek32(REG_SRC_THROTTLE_CYC); } - uint64_t get_count( - const port_type_t port_type, const count_type_t count_type) + uint64_t get_count(const port_type_t port_type, const count_type_t count_type) { - const uint32_t count_addr_lo = [&](){ + const uint32_t count_addr_lo = [&]() { switch (port_type) { case SOURCE: return count_type == LINES ? REG_SRC_LINE_CNT_LO : REG_SRC_PKT_CNT_LO; case SINK: return count_type == LINES ? REG_SNK_LINE_CNT_LO : REG_SNK_PKT_CNT_LO; case LOOP: - return count_type == LINES ? REG_LOOP_LINE_CNT_LO : REG_LOOP_PKT_CNT_LO; + return count_type == LINES ? REG_LOOP_LINE_CNT_LO + : REG_LOOP_PKT_CNT_LO; default: UHD_THROW_INVALID_CODE_PATH(); } @@ -140,7 +140,6 @@ public: } private: - /*! Action API: Register a handler for stream commands */ void register_issue_stream_cmd() diff --git a/host/lib/rfnoc/radio_control_impl.cpp b/host/lib/rfnoc/radio_control_impl.cpp index ea67d891e..faa6a01a6 100644 --- a/host/lib/rfnoc/radio_control_impl.cpp +++ b/host/lib/rfnoc/radio_control_impl.cpp @@ -5,8 +5,8 @@ // #include <uhd/exception.hpp> -#include <uhd/utils/log.hpp> #include <uhd/rfnoc/mb_controller.hpp> +#include <uhd/utils/log.hpp> #include <uhdlib/rfnoc/radio_control_impl.hpp> #include <uhdlib/utils/compat_check.hpp> #include <map> @@ -26,7 +26,7 @@ const std::string DEFAULT_GAIN_PROFILE("default"); } // namespace -const std::string radio_control::ALL_LOS = "all"; +const std::string radio_control::ALL_LOS = "all"; const std::string radio_control::ALL_GAINS = ""; const size_t radio_control::ALL_CHANS = size_t(~0); @@ -125,8 +125,8 @@ radio_control_impl::radio_control_impl(make_args_ptr make_args) uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); stream_cmd_action->stream_cmd.stream_now = false; stream_cmd_action->stream_cmd.time_spec = - get_mb_controller()->get_timekeeper(0)->get_time_now() + - uhd::time_spec_t(OVERRUN_RESTART_DELAY); + get_mb_controller()->get_timekeeper(0)->get_time_now() + + uhd::time_spec_t(OVERRUN_RESTART_DELAY); const size_t port = src.instance; if (port > get_num_output_ports()) { RFNOC_LOG_WARNING("Received stream command to invalid output port!"); @@ -141,8 +141,8 @@ radio_control_impl::radio_control_impl(make_args_ptr make_args) _type_in.reserve(get_num_input_ports()); _type_out.reserve(get_num_output_ports()); for (size_t chan = 0; chan < get_num_output_ports(); ++chan) { - _spp_prop.push_back(property_t<int>( - PROP_KEY_SPP, DEFAULT_SPP, {res_source_info::USER, chan})); + _spp_prop.push_back( + property_t<int>(PROP_KEY_SPP, DEFAULT_SPP, {res_source_info::USER, chan})); _samp_rate_in.push_back(property_t<double>( PROP_KEY_SAMP_RATE, get_tick_rate(), {res_source_info::INPUT_EDGE, chan})); _samp_rate_out.push_back(property_t<double>( @@ -196,7 +196,8 @@ radio_control_impl::radio_control_impl(make_args_ptr make_args) // At run time, it will use the implementation by the child class. add_property_resolver({&_samp_rate_in.back(), &_samp_rate_out.back()}, {&_samp_rate_in.back(), &_samp_rate_out.back()}, - [this, chan, + [this, + chan, &samp_rate_in = _samp_rate_in.at(chan), &samp_rate_out = _samp_rate_out.at(chan)]() { RFNOC_LOG_TRACE("Calling resolver for samp_rate@" << chan); @@ -358,7 +359,8 @@ uhd::gain_range_t radio_control_impl::get_rx_gain_range(const size_t chan) const return result; } -uhd::gain_range_t radio_control_impl::get_rx_gain_range(const std::string& name, const size_t chan) const +uhd::gain_range_t radio_control_impl::get_rx_gain_range( + const std::string& name, const size_t chan) const { if (name != ALL_GAINS) { throw uhd::value_error( @@ -374,7 +376,8 @@ double radio_control_impl::set_tx_gain(const double gain, const size_t chan) return gain; } -double radio_control_impl::set_tx_gain(const double gain, const std::string& name, const size_t chan) +double radio_control_impl::set_tx_gain( + const double gain, const std::string& name, const size_t chan) { if (name != ALL_GAINS) { throw uhd::key_error( @@ -390,7 +393,8 @@ double radio_control_impl::set_rx_gain(const double gain, const size_t chan) return gain; } -double radio_control_impl::set_rx_gain(const double gain, const std::string& name, const size_t chan) +double radio_control_impl::set_rx_gain( + const double gain, const std::string& name, const size_t chan) { if (name != ALL_GAINS) { throw uhd::key_error( @@ -525,7 +529,8 @@ double radio_control_impl::get_rx_gain(const size_t chan) double radio_control_impl::get_tx_gain(const std::string& name, const size_t chan) { if (name != ALL_GAINS) { - throw uhd::value_error(std::string("get_tx_gain(): Unknown gain name `") + name + "'"); + throw uhd::value_error( + std::string("get_tx_gain(): Unknown gain name `") + name + "'"); } return get_tx_gain(chan); } @@ -533,7 +538,8 @@ double radio_control_impl::get_tx_gain(const std::string& name, const size_t cha double radio_control_impl::get_rx_gain(const std::string& name, const size_t chan) { if (name != ALL_GAINS) { - throw uhd::value_error(std::string("get_rx_gain(): Unknown gain name `") + name + "'"); + throw uhd::value_error( + std::string("get_rx_gain(): Unknown gain name `") + name + "'"); } return get_rx_gain(chan); } @@ -624,12 +630,14 @@ std::vector<std::string> radio_control_impl::get_tx_lo_names(const size_t) const return {}; } -std::vector<std::string> radio_control_impl::get_tx_lo_sources(const std::string&, const size_t) +std::vector<std::string> radio_control_impl::get_tx_lo_sources( + const std::string&, const size_t) { return {"internal"}; } -uhd::freq_range_t radio_control_impl::get_tx_lo_freq_range(const std::string&, const size_t) +uhd::freq_range_t radio_control_impl::get_tx_lo_freq_range( + const std::string&, const size_t) { return uhd::freq_range_t(); } @@ -905,7 +913,7 @@ void radio_control_impl::async_message_handler( // BASE == 0x0000 for RX, 0x1000 for TX const uint32_t addr_base = (addr >= regmap::SWREG_RX_ERR) ? regmap::SWREG_RX_ERR : regmap::SWREG_TX_ERR; - const uint32_t chan = (addr - addr_base) / regmap::SWREG_CHAN_OFFSET; + const uint32_t chan = (addr - addr_base) / regmap::SWREG_CHAN_OFFSET; // Note: addr_offset is always going to be zero for now, because we only // have one "register" that gets hit for either RX or TX, but we'll keep it // in case we add other regs in the future diff --git a/host/lib/rfnoc/registry_factory.cpp b/host/lib/rfnoc/registry_factory.cpp index b251410bf..debe59133 100644 --- a/host/lib/rfnoc/registry_factory.cpp +++ b/host/lib/rfnoc/registry_factory.cpp @@ -58,10 +58,10 @@ void registry::register_block_direct(noc_id_t noc_id, { block_device_pair_t key{noc_id, device_id}; if (get_direct_block_registry().count(key)) { - std::cerr - << "[REGISTRY] WARNING: Attempting to overwrite previously " - "registered RFNoC block with noc_id,device_id: " << std::hex - << "0x" << noc_id << ", 0x" << device_id <<std::dec << std::endl; + std::cerr << "[REGISTRY] WARNING: Attempting to overwrite previously " + "registered RFNoC block with noc_id,device_id: " + << std::hex << "0x" << noc_id << ", 0x" << device_id << std::dec + << std::endl; return; } get_direct_block_registry().emplace(key, @@ -76,10 +76,9 @@ void registry::register_block_descriptor( const std::string& block_key, factory_t factory_fn) { if (get_descriptor_block_registry().count(block_key)) { - std::cerr - << "[REGISTRY] WARNING: Attempting to overwrite previously " - "registered RFNoC block with block key" - << block_key << std::endl; + std::cerr << "[REGISTRY] WARNING: Attempting to overwrite previously " + "registered RFNoC block with block key" + << block_key << std::endl; return; } get_descriptor_block_registry().emplace(block_key, std::move(factory_fn)); @@ -107,4 +106,3 @@ block_factory_info_t factory::get_block_factory(noc_id_t noc_id, device_type_t d } return get_direct_block_registry().at(key); } - diff --git a/host/lib/rfnoc/rfnoc_graph.cpp b/host/lib/rfnoc/rfnoc_graph.cpp index 9cb9edfe8..f5a462bad 100644 --- a/host/lib/rfnoc/rfnoc_graph.cpp +++ b/host/lib/rfnoc/rfnoc_graph.cpp @@ -35,7 +35,7 @@ struct block_xbar_info noc_id_t noc_id; size_t inst_num; }; -} +} // namespace class rfnoc_graph_impl : public rfnoc_graph { @@ -43,8 +43,9 @@ public: /************************************************************************** * Structors *************************************************************************/ - rfnoc_graph_impl(detail::rfnoc_device::sptr dev, const uhd::device_addr_t& dev_addr) - try : _device(dev), + rfnoc_graph_impl( + detail::rfnoc_device::sptr dev, const uhd::device_addr_t& dev_addr) try + : _device(dev), _tree(_device->get_tree()), _num_mboards(_tree->list("/mboards").size()), _block_registry(std::make_unique<detail::block_container_t>()), @@ -492,7 +493,7 @@ private: + std::to_string(chdr_w_to_bits(chdr_w)) + " but device " + std::to_string(mb_idx) + " has CHDR width of " + std::to_string( - chdr_w_to_bits(_device->get_mb_iface(mb_idx).get_chdr_w())) + chdr_w_to_bits(_device->get_mb_iface(mb_idx).get_chdr_w())) + " bits!"); } if (_device->get_mb_iface(mb_idx).get_endianness() != endianness) { diff --git a/host/lib/rfnoc/rfnoc_rx_streamer.cpp b/host/lib/rfnoc/rfnoc_rx_streamer.cpp index d6778267f..081682a94 100644 --- a/host/lib/rfnoc/rfnoc_rx_streamer.cpp +++ b/host/lib/rfnoc/rfnoc_rx_streamer.cpp @@ -68,11 +68,13 @@ rfnoc_rx_streamer::rfnoc_rx_streamer( mtu_resolver_out.insert(&mtu_prop); } - add_property_resolver({&_mtu_in[i]}, std::move(mtu_resolver_out), - [&mtu_in = _mtu_in[i], i, this]() { + add_property_resolver({&_mtu_in[i]}, + std::move(mtu_resolver_out), + [& mtu_in = _mtu_in[i], i, this]() { RFNOC_LOG_TRACE("Calling resolver for `mtu_in'@" << i); if (mtu_in.is_valid()) { - const size_t mtu = std::min(mtu_in.get(), rx_streamer_impl::get_mtu()); + const size_t mtu = + std::min(mtu_in.get(), rx_streamer_impl::get_mtu()); // Set the same MTU value for all chans for (auto& prop : this->_mtu_in) { prop.set(mtu); @@ -112,7 +114,7 @@ void rfnoc_rx_streamer::issue_stream_cmd(const stream_cmd_t& stream_cmd) "single streamer will fail to time align."); } - auto cmd = stream_cmd_action_info::make(stream_cmd.stream_mode); + auto cmd = stream_cmd_action_info::make(stream_cmd.stream_mode); cmd->stream_cmd = stream_cmd; for (size_t i = 0; i < get_num_channels(); i++) { @@ -126,8 +128,7 @@ const uhd::stream_args_t& rfnoc_rx_streamer::get_stream_args() const return _stream_args; } -bool rfnoc_rx_streamer::check_topology( - const std::vector<size_t>& connected_inputs, +bool rfnoc_rx_streamer::check_topology(const std::vector<size_t>& connected_inputs, const std::vector<size_t>& connected_outputs) { // Check that all channels are connected @@ -160,27 +161,26 @@ void rfnoc_rx_streamer::connect_channel( rx_streamer_impl<chdr_rx_data_xport>::connect_channel(channel, std::move(xport)); } -void rfnoc_rx_streamer::_register_props(const size_t chan, - const std::string& otw_format) +void rfnoc_rx_streamer::_register_props(const size_t chan, const std::string& otw_format) { // Create actual properties and store them - _scaling_in.push_back(property_t<double>( - PROP_KEY_SCALING, {res_source_info::INPUT_EDGE, chan})); + _scaling_in.push_back( + property_t<double>(PROP_KEY_SCALING, {res_source_info::INPUT_EDGE, chan})); _samp_rate_in.push_back( property_t<double>(PROP_KEY_SAMP_RATE, {res_source_info::INPUT_EDGE, chan})); - _tick_rate_in.push_back(property_t<double>( - PROP_KEY_TICK_RATE, {res_source_info::INPUT_EDGE, chan})); + _tick_rate_in.push_back( + property_t<double>(PROP_KEY_TICK_RATE, {res_source_info::INPUT_EDGE, chan})); _type_in.emplace_back(property_t<std::string>( PROP_KEY_TYPE, otw_format, {res_source_info::INPUT_EDGE, chan})); - _mtu_in.emplace_back(property_t<size_t>( - PROP_KEY_MTU, get_mtu(), {res_source_info::INPUT_EDGE, chan})); + _mtu_in.emplace_back( + property_t<size_t>(PROP_KEY_MTU, get_mtu(), {res_source_info::INPUT_EDGE, chan})); // Give us some shorthands for the rest of this function property_t<double>* scaling_in = &_scaling_in.back(); property_t<double>* samp_rate_in = &_samp_rate_in.back(); property_t<double>* tick_rate_in = &_tick_rate_in.back(); property_t<std::string>* type_in = &_type_in.back(); - property_t<size_t>* mtu_in = &_mtu_in.back(); + property_t<size_t>* mtu_in = &_mtu_in.back(); // Register them register_property(scaling_in); @@ -190,24 +190,23 @@ void rfnoc_rx_streamer::_register_props(const size_t chan, register_property(mtu_in); // Add resolvers - add_property_resolver({scaling_in}, {}, - [&scaling_in = *scaling_in, chan, this]() { - RFNOC_LOG_TRACE("Calling resolver for `scaling_in'@" << chan); - if (scaling_in.is_valid()) { - this->set_scale_factor(chan, scaling_in.get() / 32767.0); - } - }); + add_property_resolver({scaling_in}, {}, [& scaling_in = *scaling_in, chan, this]() { + RFNOC_LOG_TRACE("Calling resolver for `scaling_in'@" << chan); + if (scaling_in.is_valid()) { + this->set_scale_factor(chan, scaling_in.get() / 32767.0); + } + }); - add_property_resolver({samp_rate_in}, {}, - [&samp_rate_in = *samp_rate_in, chan, this]() { + add_property_resolver( + {samp_rate_in}, {}, [& samp_rate_in = *samp_rate_in, chan, this]() { RFNOC_LOG_TRACE("Calling resolver for `samp_rate_in'@" << chan); if (samp_rate_in.is_valid()) { this->set_samp_rate(samp_rate_in.get()); } }); - add_property_resolver({tick_rate_in}, {}, - [&tick_rate_in = *tick_rate_in, chan, this]() { + add_property_resolver( + {tick_rate_in}, {}, [& tick_rate_in = *tick_rate_in, chan, this]() { RFNOC_LOG_TRACE("Calling resolver for `tick_rate_in'@" << chan); if (tick_rate_in.is_valid()) { this->set_tick_rate(tick_rate_in.get()); diff --git a/host/lib/rfnoc/rfnoc_tx_streamer.cpp b/host/lib/rfnoc/rfnoc_tx_streamer.cpp index d4aa267af..9b511818e 100644 --- a/host/lib/rfnoc/rfnoc_tx_streamer.cpp +++ b/host/lib/rfnoc/rfnoc_tx_streamer.cpp @@ -16,8 +16,8 @@ const std::string STREAMER_ID = "TxStreamer"; static std::atomic<uint64_t> streamer_inst_ctr; static constexpr size_t ASYNC_MSG_QUEUE_SIZE = 1000; -rfnoc_tx_streamer::rfnoc_tx_streamer(const size_t num_chans, - const uhd::stream_args_t stream_args) +rfnoc_tx_streamer::rfnoc_tx_streamer( + const size_t num_chans, const uhd::stream_args_t stream_args) : tx_streamer_impl<chdr_tx_data_xport>(num_chans, stream_args) , _unique_id(STREAMER_ID + "#" + std::to_string(streamer_inst_ctr++)) , _stream_args(stream_args) @@ -56,11 +56,13 @@ rfnoc_tx_streamer::rfnoc_tx_streamer(const size_t num_chans, mtu_resolver_out.insert(&mtu_prop); } - add_property_resolver({&_mtu_out[i]}, std::move(mtu_resolver_out), - [&mtu_out = _mtu_out[i], i, this]() { + add_property_resolver({&_mtu_out[i]}, + std::move(mtu_resolver_out), + [& mtu_out = _mtu_out[i], i, this]() { RFNOC_LOG_TRACE("Calling resolver for `mtu_out'@" << i); if (mtu_out.is_valid()) { - const size_t mtu = std::min(mtu_out.get(), tx_streamer_impl::get_mtu()); + const size_t mtu = + std::min(mtu_out.get(), tx_streamer_impl::get_mtu()); // Set the same MTU value for all chans for (auto& prop : this->_mtu_out) { prop.set(mtu); @@ -96,8 +98,7 @@ const uhd::stream_args_t& rfnoc_tx_streamer::get_stream_args() const return _stream_args; } -bool rfnoc_tx_streamer::check_topology( - const std::vector<size_t>& connected_inputs, +bool rfnoc_tx_streamer::check_topology(const std::vector<size_t>& connected_inputs, const std::vector<size_t>& connected_outputs) { // Check that all channels are connected @@ -119,7 +120,8 @@ void rfnoc_tx_streamer::connect_channel( set_property<size_t>(PROP_KEY_MTU, mtu, {res_source_info::OUTPUT_EDGE, channel}); xport->set_enqueue_async_msg_fn( - [this, channel](async_metadata_t::event_code_t event_code, bool has_tsf, uint64_t tsf) { + [this, channel]( + async_metadata_t::event_code_t event_code, bool has_tsf, uint64_t tsf) { async_metadata_t md; md.channel = channel; md.event_code = event_code; @@ -135,23 +137,22 @@ void rfnoc_tx_streamer::connect_channel( tx_streamer_impl<chdr_tx_data_xport>::connect_channel(channel, std::move(xport)); } -bool rfnoc_tx_streamer::recv_async_msg(uhd::async_metadata_t& async_metadata, - double timeout) +bool rfnoc_tx_streamer::recv_async_msg( + uhd::async_metadata_t& async_metadata, double timeout) { const auto timeout_ms = static_cast<uint64_t>(timeout * 1000); return _async_msg_queue->recv_async_msg(async_metadata, timeout_ms); } -void rfnoc_tx_streamer::_register_props(const size_t chan, - const std::string& otw_format) +void rfnoc_tx_streamer::_register_props(const size_t chan, const std::string& otw_format) { // Create actual properties and store them - _scaling_out.push_back(property_t<double>( - PROP_KEY_SCALING, {res_source_info::OUTPUT_EDGE, chan})); - _samp_rate_out.push_back(property_t<double>( - PROP_KEY_SAMP_RATE, {res_source_info::OUTPUT_EDGE, chan})); - _tick_rate_out.push_back(property_t<double>( - PROP_KEY_TICK_RATE, {res_source_info::OUTPUT_EDGE, chan})); + _scaling_out.push_back( + property_t<double>(PROP_KEY_SCALING, {res_source_info::OUTPUT_EDGE, chan})); + _samp_rate_out.push_back( + property_t<double>(PROP_KEY_SAMP_RATE, {res_source_info::OUTPUT_EDGE, chan})); + _tick_rate_out.push_back( + property_t<double>(PROP_KEY_TICK_RATE, {res_source_info::OUTPUT_EDGE, chan})); _type_out.emplace_back(property_t<std::string>( PROP_KEY_TYPE, otw_format, {res_source_info::OUTPUT_EDGE, chan})); _mtu_out.push_back(property_t<size_t>( diff --git a/host/lib/rfnoc/tx_async_msg_queue.cpp b/host/lib/rfnoc/tx_async_msg_queue.cpp index 71a05074f..52c268dc9 100644 --- a/host/lib/rfnoc/tx_async_msg_queue.cpp +++ b/host/lib/rfnoc/tx_async_msg_queue.cpp @@ -11,13 +11,10 @@ using namespace uhd; using namespace uhd::rfnoc; -tx_async_msg_queue::tx_async_msg_queue(size_t capacity) - : _queue(capacity) -{ -} +tx_async_msg_queue::tx_async_msg_queue(size_t capacity) : _queue(capacity) {} -bool tx_async_msg_queue::recv_async_msg(uhd::async_metadata_t& async_metadata, - int32_t timeout_ms) +bool tx_async_msg_queue::recv_async_msg( + uhd::async_metadata_t& async_metadata, int32_t timeout_ms) { using namespace std::chrono; diff --git a/host/lib/stream.cpp b/host/lib/stream.cpp index 8e603552c..dc7b33721 100644 --- a/host/lib/stream.cpp +++ b/host/lib/stream.cpp @@ -11,10 +11,10 @@ using namespace uhd; rx_streamer::~rx_streamer(void) { - //empty + // empty } tx_streamer::~tx_streamer(void) { - //empty + // empty } diff --git a/host/lib/stream_python.hpp b/host/lib/stream_python.hpp index 1cb922b52..25966ee00 100644 --- a/host/lib/stream_python.hpp +++ b/host/lib/stream_python.hpp @@ -12,50 +12,48 @@ #include <uhd/types/metadata.hpp> #include <boost/format.hpp> -static size_t wrap_recv(uhd::rx_streamer *rx_stream, - py::object &np_array, - uhd::rx_metadata_t &metadata, - const double timeout = 0.1) +static size_t wrap_recv(uhd::rx_streamer* rx_stream, + py::object& np_array, + uhd::rx_metadata_t& metadata, + const double timeout = 0.1) { // Get a numpy array object from given python object // No sanity checking possible! - PyObject* array_obj = PyArray_FROM_OF(np_array.ptr(), NPY_ARRAY_CARRAY); + PyObject* array_obj = PyArray_FROM_OF(np_array.ptr(), NPY_ARRAY_CARRAY); PyArrayObject* array_type_obj = reinterpret_cast<PyArrayObject*>(array_obj); // Get dimensions of the numpy array - const size_t dims = PyArray_NDIM(array_type_obj); + const size_t dims = PyArray_NDIM(array_type_obj); const npy_intp* shape = PyArray_SHAPE(array_type_obj); // How many bytes to jump to get to the next element of this stride // (next row) const npy_intp* strides = PyArray_STRIDES(array_type_obj); - const size_t channels = rx_stream->get_num_channels(); + const size_t channels = rx_stream->get_num_channels(); // Check if numpy array sizes are okay - if (((channels > 1) && (dims != 2)) - or ((size_t) shape[0] < channels)) - { + if (((channels > 1) && (dims != 2)) or ((size_t)shape[0] < channels)) { // Manually decrement the ref count Py_DECREF(array_obj); // If we don't have a 2D NumPy array, assume we have a 1D array size_t input_channels = (dims != 2) ? 1 : shape[0]; - throw uhd::runtime_error(str(boost::format( - "Number of RX channels (%d) does not match the dimensions of the data array (%d)") - % channels % input_channels)); + throw uhd::runtime_error( + str(boost::format("Number of RX channels (%d) does not match the dimensions " + "of the data array (%d)") + % channels % input_channels)); } // Get a pointer to the storage std::vector<void*> channel_storage; char* data = PyArray_BYTES(array_type_obj); - for (size_t i = 0; i < channels; ++i) - { + for (size_t i = 0; i < channels; ++i) { channel_storage.push_back((void*)(data + i * strides[0])); } // Get data buffer and size of the array size_t nsamps_per_buff; if (dims > 1) { - nsamps_per_buff = (size_t) shape[1]; + nsamps_per_buff = (size_t)shape[1]; } else { nsamps_per_buff = PyArray_SIZE(array_type_obj); } @@ -64,12 +62,7 @@ static size_t wrap_recv(uhd::rx_streamer *rx_stream, const size_t result = [&]() { py::gil_scoped_release release; // Call the real recv() - return rx_stream->recv( - channel_storage, - nsamps_per_buff, - metadata, - timeout - ); + return rx_stream->recv(channel_storage, nsamps_per_buff, metadata, timeout); }(); // Manually decrement the ref count @@ -77,60 +70,54 @@ static size_t wrap_recv(uhd::rx_streamer *rx_stream, return result; } -static size_t wrap_send(uhd::tx_streamer *tx_stream, - py::object &np_array, - uhd::tx_metadata_t& metadata, - const double timeout = 0.1) +static size_t wrap_send(uhd::tx_streamer* tx_stream, + py::object& np_array, + uhd::tx_metadata_t& metadata, + const double timeout = 0.1) { // Get a numpy array object from given python object // No sanity checking possible! - // Note: this increases the ref count, which we'll need to manually decrease at the end - PyObject* array_obj = PyArray_FROM_OF(np_array.ptr(),NPY_ARRAY_CARRAY); + // Note: this increases the ref count, which we'll need to manually decrease at the + // end + PyObject* array_obj = PyArray_FROM_OF(np_array.ptr(), NPY_ARRAY_CARRAY); PyArrayObject* array_type_obj = reinterpret_cast<PyArrayObject*>(array_obj); // Get dimensions of the numpy array - const size_t dims = PyArray_NDIM(array_type_obj); + const size_t dims = PyArray_NDIM(array_type_obj); const npy_intp* shape = PyArray_SHAPE(array_type_obj); // How many bytes to jump to get to the next element of the stride // (next row) const npy_intp* strides = PyArray_STRIDES(array_type_obj); - const size_t channels = tx_stream->get_num_channels(); + const size_t channels = tx_stream->get_num_channels(); // Check if numpy array sizes are ok - if (((channels > 1) && (dims != 2)) - or ((size_t) shape[0] < channels)) - { + if (((channels > 1) && (dims != 2)) or ((size_t)shape[0] < channels)) { // Manually decrement the ref count Py_DECREF(array_obj); // If we don't have a 2D NumPy array, assume we have a 1D array size_t input_channels = (dims != 2) ? 1 : shape[0]; - throw uhd::runtime_error(str(boost::format( - "Number of TX channels (%d) does not match the dimensions of the data array (%d)") - % channels % input_channels)); + throw uhd::runtime_error( + str(boost::format("Number of TX channels (%d) does not match the dimensions " + "of the data array (%d)") + % channels % input_channels)); } // Get a pointer to the storage std::vector<void*> channel_storage; char* data = PyArray_BYTES(array_type_obj); - for (size_t i = 0; i < channels; ++i) - { + for (size_t i = 0; i < channels; ++i) { channel_storage.push_back((void*)(data + i * strides[0])); } // Get data buffer and size of the array - size_t nsamps_per_buff = (dims > 1) ? (size_t) shape[1] : PyArray_SIZE(array_type_obj); + size_t nsamps_per_buff = (dims > 1) ? (size_t)shape[1] : PyArray_SIZE(array_type_obj); // Release the GIL only for the send() call const size_t result = [&]() { py::gil_scoped_release release; // Call the real send() - return tx_stream->send( - channel_storage, - nsamps_per_buff, - metadata, - timeout - ); + return tx_stream->send(channel_storage, nsamps_per_buff, metadata, timeout); }(); // Manually decrement the ref count @@ -138,9 +125,9 @@ static size_t wrap_send(uhd::tx_streamer *tx_stream, return result; } -static bool wrap_recv_async_msg(uhd::tx_streamer *tx_stream, - uhd::async_metadata_t &async_metadata, - double timeout = 0.1) +static bool wrap_recv_async_msg(uhd::tx_streamer* tx_stream, + uhd::async_metadata_t& async_metadata, + double timeout = 0.1) { // Release the GIL py::gil_scoped_release release; @@ -153,39 +140,38 @@ void export_stream(py::module& m) using rx_streamer = uhd::rx_streamer; using tx_streamer = uhd::tx_streamer; - py::class_<stream_args_t> - (m, "stream_args") + py::class_<stream_args_t>(m, "stream_args") .def(py::init<const std::string&, const std::string&>()) // Properties .def_readwrite("cpu_format", &stream_args_t::cpu_format) .def_readwrite("otw_format", &stream_args_t::otw_format) - .def_readwrite("args" , &stream_args_t::args ) - .def_readwrite("channels" , &stream_args_t::channels ) - ; + .def_readwrite("args", &stream_args_t::args) + .def_readwrite("channels", &stream_args_t::channels); py::class_<rx_streamer, rx_streamer::sptr>(m, "rx_streamer", "See: uhd::rx_streamer") // Methods - .def("recv" , &wrap_recv, - py::arg("np_array"), - py::arg("metadata"), - py::arg("timeout") = 0.1) - .def("get_num_channels" , &uhd::rx_streamer::get_num_channels ) + .def("recv", + &wrap_recv, + py::arg("np_array"), + py::arg("metadata"), + py::arg("timeout") = 0.1) + .def("get_num_channels", &uhd::rx_streamer::get_num_channels) .def("get_max_num_samps", &uhd::rx_streamer::get_max_num_samps) - .def("issue_stream_cmd" , &uhd::rx_streamer::issue_stream_cmd ) - ; + .def("issue_stream_cmd", &uhd::rx_streamer::issue_stream_cmd); py::class_<tx_streamer, tx_streamer::sptr>(m, "tx_streamer", "See: uhd::tx_streamer") // Methods - .def("send" , &wrap_send, - py::arg("np_array"), - py::arg("metadata"), - py::arg("timeout") = 0.1) - .def("get_num_channels" , &tx_streamer::get_num_channels ) - .def("get_max_num_samps", &tx_streamer::get_max_num_samps ) - .def("recv_async_msg" , &wrap_recv_async_msg, - py::arg("async_metadata"), - py::arg("timeout") = 0.1) - ; + .def("send", + &wrap_send, + py::arg("np_array"), + py::arg("metadata"), + py::arg("timeout") = 0.1) + .def("get_num_channels", &tx_streamer::get_num_channels) + .def("get_max_num_samps", &tx_streamer::get_max_num_samps) + .def("recv_async_msg", + &wrap_recv_async_msg, + py::arg("async_metadata"), + py::arg("timeout") = 0.1); } #endif /* INCLUDED_UHD_STREAM_PYTHON_HPP */ diff --git a/host/lib/transport/adapter.cpp b/host/lib/transport/adapter.cpp index 247b33868..f5717c954 100644 --- a/host/lib/transport/adapter.cpp +++ b/host/lib/transport/adapter.cpp @@ -21,4 +21,3 @@ adapter_id_t adapter_ctx::register_adapter(adapter_info& info) return id; } } - diff --git a/host/lib/transport/dpdk_simple.cpp b/host/lib/transport/dpdk_simple.cpp index 50855f36a..d93d73b56 100644 --- a/host/lib/transport/dpdk_simple.cpp +++ b/host/lib/transport/dpdk_simple.cpp @@ -21,13 +21,13 @@ namespace { constexpr double SEND_TIMEOUT_MS = 500; // seconds } -class dpdk_simple_impl : public dpdk_simple { +class dpdk_simple_impl : public dpdk_simple +{ public: dpdk_simple_impl(const std::string& addr, const std::string& port) { link_params_t link_params = _get_default_link_params(); - _link = - uhd::transport::udp_dpdk_link::make(addr, port, link_params); + _link = uhd::transport::udp_dpdk_link::make(addr, port, link_params); UHD_LOG_TRACE("DPDK::SIMPLE", "Creating simple UDP object for " << addr << ":" << port << ", DPDK port index " @@ -37,7 +37,7 @@ public: UHD_ASSERT_THROW(ctx->is_init_done()); // Init I/O service - _port_id = _link->get_port()->get_port_id(); + _port_id = _link->get_port()->get_port_id(); _io_service = ctx->get_io_service(_port_id); // This is normally done by the I/O service manager, but with DPDK, this // is all it does so we skip that step @@ -120,7 +120,7 @@ public: size_t recv(const boost::asio::mutable_buffer& user_buff, double timeout) { size_t user_buff_size = boost::asio::buffer_size(user_buff); - uint8_t* user_data = boost::asio::buffer_cast<uint8_t*>(user_buff); + uint8_t* user_data = boost::asio::buffer_cast<uint8_t*>(user_buff); auto buff = _recv_io->get_recv_buff(static_cast<int32_t>(timeout * 1e3)); if (!buff) { @@ -218,4 +218,3 @@ udp_simple::sptr dpdk_simple::make_broadcast( return udp_simple::sptr(new dpdk_simple_impl(addr, port)); } }} // namespace uhd::transport - diff --git a/host/lib/transport/inline_io_service.cpp b/host/lib/transport/inline_io_service.cpp index 1438699b7..8206c145f 100644 --- a/host/lib/transport/inline_io_service.cpp +++ b/host/lib/transport/inline_io_service.cpp @@ -387,8 +387,14 @@ send_io_if::sptr inline_io_service::make_send_client(send_link_if::sptr send_lin UHD_ASSERT_THROW(send_cb); connect_sender(send_link.get(), num_send_frames); sptr io_srv = shared_from_this(); - auto send_io = std::make_shared<inline_send_io>( - io_srv, send_link, num_send_frames, send_cb, recv_link, num_recv_frames, recv_cb, fc_cb); + auto send_io = std::make_shared<inline_send_io>(io_srv, + send_link, + num_send_frames, + send_cb, + recv_link, + num_recv_frames, + recv_cb, + fc_cb); if (recv_link) { UHD_ASSERT_THROW(recv_cb); UHD_ASSERT_THROW(fc_cb); diff --git a/host/lib/transport/libusb1_base.cpp b/host/lib/transport/libusb1_base.cpp index 3362de712..60481bc6a 100644 --- a/host/lib/transport/libusb1_base.cpp +++ b/host/lib/transport/libusb1_base.cpp @@ -15,8 +15,8 @@ #include <cstdlib> #include <functional> #include <iostream> -#include <mutex> #include <memory> +#include <mutex> using namespace uhd; using namespace uhd::transport; diff --git a/host/lib/transport/libusb1_base.hpp b/host/lib/transport/libusb1_base.hpp index 5d909a664..7c70ab5d0 100644 --- a/host/lib/transport/libusb1_base.hpp +++ b/host/lib/transport/libusb1_base.hpp @@ -10,9 +10,9 @@ #include <uhd/config.hpp> #include <uhd/transport/usb_device_handle.hpp> +#include <uhd/utils/noncopyable.hpp> #include <libusb.h> #include <memory> -#include <uhd/utils/noncopyable.hpp> //! Define LIBUSB_CALL when its missing (non-windows) #ifndef LIBUSB_CALL diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp index d02f90217..f918912d0 100644 --- a/host/lib/transport/libusb1_zero_copy.cpp +++ b/host/lib/transport/libusb1_zero_copy.cpp @@ -252,7 +252,9 @@ public: _mb_pool.push_back(std::make_shared<libusb_zero_copy_mb>(lut, this->get_frame_size(), - std::bind(&libusb_zero_copy_single::enqueue_buffer, this, std::placeholders::_1), + std::bind(&libusb_zero_copy_single::enqueue_buffer, + this, + std::placeholders::_1), is_recv, name)); diff --git a/host/lib/transport/muxed_zero_copy_if.cpp b/host/lib/transport/muxed_zero_copy_if.cpp index 054d74e0c..2602d8596 100644 --- a/host/lib/transport/muxed_zero_copy_if.cpp +++ b/host/lib/transport/muxed_zero_copy_if.cpp @@ -67,12 +67,11 @@ public: } // Only allocate a portion of the base transport's frames to each stream // to prevent all streams from attempting to use all the frames. - stream_impl::sptr stream = - std::make_shared<stream_impl>(this->shared_from_this(), - stream_num, - _base_xport->get_num_send_frames(), - _base_xport->get_num_recv_frames()); - _streams[stream_num] = stream; + stream_impl::sptr stream = std::make_shared<stream_impl>(this->shared_from_this(), + stream_num, + _base_xport->get_num_send_frames(), + _base_xport->get_num_recv_frames()); + _streams[stream_num] = stream; return stream; } diff --git a/host/lib/transport/nirio/lvbitx/process-lvbitx.py b/host/lib/transport/nirio/lvbitx/process-lvbitx.py index dfa94bb59..dbf9ff654 100755 --- a/host/lib/transport/nirio/lvbitx/process-lvbitx.py +++ b/host/lib/transport/nirio/lvbitx/process-lvbitx.py @@ -1,7 +1,7 @@ -#!/usr/bin/python -# +#!/usr/bin/pyBrand # Copyright 2013-2015 Ettus Research LLC # Copyright 2018 Ettus Research, a National Instruments Company +# Copyright 2020 Ettus Research, a National Instruments Brand # # SPDX-License-Identifier: GPL-3.0-or-later # diff --git a/host/lib/transport/nirio/nifpga_lvbitx.cpp b/host/lib/transport/nirio/nifpga_lvbitx.cpp index 015344710..ed7c3f852 100644 --- a/host/lib/transport/nirio/nifpga_lvbitx.cpp +++ b/host/lib/transport/nirio/nifpga_lvbitx.cpp @@ -6,20 +6,19 @@ // #include <uhd/transport/nirio/nifpga_lvbitx.h> +#include <boost/algorithm/string.hpp> #include <cstdlib> -#include <string> #include <fstream> -#include <streambuf> -#include <boost/algorithm/string.hpp> #include <regex> +#include <streambuf> +#include <string> namespace uhd { namespace niusrprio { std::string nifpga_lvbitx::_get_bitstream_checksum(const std::string& file_path) { const std::regex md5_regex( - "<BitstreamMD5>([a-fA-F0-9]{32})<\\/BitstreamMD5>", - std::regex::icase); + "<BitstreamMD5>([a-fA-F0-9]{32})<\\/BitstreamMD5>", std::regex::icase); std::ifstream lvbitx_stream(file_path.c_str()); if (!lvbitx_stream.is_open()) { @@ -27,25 +26,21 @@ std::string nifpga_lvbitx::_get_bitstream_checksum(const std::string& file_path) } std::string checksum, line; - while (std::getline(lvbitx_stream, line)) - { + while (std::getline(lvbitx_stream, line)) { try { // short-circuiting the regex search with a simple find is faster // for cases where the tag doesn't exist std::smatch md5_match; - if (line.find("<BitstreamMD5>") != std::string::npos && - std::regex_search(line, md5_match, md5_regex)) - { + if (line.find("<BitstreamMD5>") != std::string::npos + && std::regex_search(line, md5_match, md5_regex)) { checksum = std::string(md5_match[1].first, md5_match[1].second); break; } - } - catch (boost::exception&) { - + } catch (boost::exception&) { } } boost::to_upper(checksum); return checksum; } -}} +}} // namespace uhd::niusrprio diff --git a/host/lib/transport/nirio/nirio_driver_iface_linux.cpp b/host/lib/transport/nirio/nirio_driver_iface_linux.cpp index b66f6413e..40dc8b199 100644 --- a/host/lib/transport/nirio/nirio_driver_iface_linux.cpp +++ b/host/lib/transport/nirio/nirio_driver_iface_linux.cpp @@ -6,18 +6,16 @@ // #include <uhd/transport/nirio/nirio_driver_iface.h> -#include <stdio.h> #include <errno.h> #include <fcntl.h> -#include <unistd.h> +#include <stdio.h> #include <sys/ioctl.h> #include <sys/mman.h> +#include <unistd.h> namespace nirio_driver_iface { -nirio_status rio_open( - const std::string& device_path, - rio_dev_handle_t& device_handle) +nirio_status rio_open(const std::string& device_path, rio_dev_handle_t& device_handle) { device_handle = ::open(device_path.c_str(), O_RDWR | O_CLOEXEC); return (device_handle < 0) ? NiRio_Status_InvalidParameter : NiRio_Status_Success; @@ -34,59 +32,69 @@ bool rio_isopen(rio_dev_handle_t device_handle) return (device_handle >= 0); } -nirio_status rio_ioctl( - rio_dev_handle_t device_handle, +nirio_status rio_ioctl(rio_dev_handle_t device_handle, uint32_t ioctl_code, - const void *write_buf, + const void* write_buf, size_t write_buf_len, - void *read_buf, + void* read_buf, size_t read_buf_len) { - nirio_ioctl_block_t ioctl_block = {0,0,0,0,0,0}; + nirio_ioctl_block_t ioctl_block = {0, 0, 0, 0, 0, 0}; // two-casts necessary to prevent pointer sign-extension - ioctl_block.in_buf = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(write_buf)); - ioctl_block.in_buf_len = write_buf_len; - ioctl_block.out_buf = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(read_buf)); + ioctl_block.in_buf = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(write_buf)); + ioctl_block.in_buf_len = write_buf_len; + ioctl_block.out_buf = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(read_buf)); ioctl_block.out_buf_len = read_buf_len; int status = ::ioctl(device_handle, ioctl_code, &ioctl_block); if (status == -1) { switch (errno) { - case EINVAL: return NiRio_Status_InvalidParameter; - case EFAULT: return NiRio_Status_MemoryFull; - default: return NiRio_Status_SoftwareFault; + case EINVAL: + return NiRio_Status_InvalidParameter; + case EFAULT: + return NiRio_Status_MemoryFull; + default: + return NiRio_Status_SoftwareFault; } } else { return NiRio_Status_Success; } } -nirio_status rio_mmap( - rio_dev_handle_t device_handle, +nirio_status rio_mmap(rio_dev_handle_t device_handle, uint16_t memory_type, size_t size, bool writable, - rio_mmap_t &map) + rio_mmap_t& map) { - int access_mode = PROT_READ; //Write-only mode not supported - if (writable) access_mode |= PROT_WRITE; - map.addr = ::mmap(NULL, size, access_mode, MAP_SHARED, device_handle, (off_t) memory_type * sysconf(_SC_PAGESIZE)); + int access_mode = PROT_READ; // Write-only mode not supported + if (writable) + access_mode |= PROT_WRITE; + map.addr = ::mmap(NULL, + size, + access_mode, + MAP_SHARED, + device_handle, + (off_t)memory_type * sysconf(_SC_PAGESIZE)); map.size = size; - if (map.addr == MAP_FAILED) { + if (map.addr == MAP_FAILED) { map.addr = NULL; map.size = 0; switch (errno) { - case EINVAL: return NiRio_Status_InvalidParameter; - case EFAULT: return NiRio_Status_MemoryFull; - default: return NiRio_Status_SoftwareFault; + case EINVAL: + return NiRio_Status_InvalidParameter; + case EFAULT: + return NiRio_Status_MemoryFull; + default: + return NiRio_Status_SoftwareFault; } } return NiRio_Status_Success; } -nirio_status rio_munmap(rio_mmap_t &map) +nirio_status rio_munmap(rio_mmap_t& map) { nirio_status status = 0; if (map.addr != NULL) { @@ -98,4 +106,4 @@ nirio_status rio_munmap(rio_mmap_t &map) return status; } -} +} // namespace nirio_driver_iface diff --git a/host/lib/transport/nirio/nirio_driver_iface_unsupported.cpp b/host/lib/transport/nirio/nirio_driver_iface_unsupported.cpp index 548f3b7f4..855301147 100644 --- a/host/lib/transport/nirio/nirio_driver_iface_unsupported.cpp +++ b/host/lib/transport/nirio/nirio_driver_iface_unsupported.cpp @@ -8,46 +8,41 @@ namespace nirio_driver_iface { -nirio_status rio_open( - UHD_UNUSED(const std::string& device_path), +nirio_status rio_open(UHD_UNUSED(const std::string& device_path), UHD_UNUSED(rio_dev_handle_t& device_handle)) { return NiRio_Status_FeatureNotSupported; } -void rio_close(UHD_UNUSED(rio_dev_handle_t& device_handle)) -{ -} +void rio_close(UHD_UNUSED(rio_dev_handle_t& device_handle)) {} bool rio_isopen(UHD_UNUSED(rio_dev_handle_t device_handle)) { return false; } -nirio_status rio_ioctl( - UHD_UNUSED(rio_dev_handle_t device_handle), +nirio_status rio_ioctl(UHD_UNUSED(rio_dev_handle_t device_handle), UHD_UNUSED(uint32_t ioctl_code), - UHD_UNUSED(const void *write_buf), + UHD_UNUSED(const void* write_buf), UHD_UNUSED(size_t write_buf_len), - UHD_UNUSED(void *read_buf), + UHD_UNUSED(void* read_buf), UHD_UNUSED(size_t read_buf_len)) { return NiRio_Status_FeatureNotSupported; } -nirio_status rio_mmap( - UHD_UNUSED(rio_dev_handle_t device_handle), +nirio_status rio_mmap(UHD_UNUSED(rio_dev_handle_t device_handle), UHD_UNUSED(uint16_t memory_type), UHD_UNUSED(size_t size), UHD_UNUSED(bool writable), - UHD_UNUSED(rio_mmap_t &map)) + UHD_UNUSED(rio_mmap_t& map)) { return NiRio_Status_FeatureNotSupported; } -nirio_status rio_munmap(UHD_UNUSED(rio_mmap_t &map)) +nirio_status rio_munmap(UHD_UNUSED(rio_mmap_t& map)) { return NiRio_Status_FeatureNotSupported; } -} +} // namespace nirio_driver_iface diff --git a/host/lib/transport/nirio/nirio_driver_iface_win.cpp b/host/lib/transport/nirio/nirio_driver_iface_win.cpp index 6a5513ebe..e50473e99 100644 --- a/host/lib/transport/nirio/nirio_driver_iface_win.cpp +++ b/host/lib/transport/nirio/nirio_driver_iface_win.cpp @@ -8,20 +8,31 @@ #include <uhd/transport/nirio/nirio_driver_iface.h> #include <process.h> -#define NIRIO_IOCTL_MAP_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 0xF00, METHOD_BUFFERED, (FILE_READ_ACCESS | FILE_WRITE_ACCESS)) -#define NIRIO_IOCTL_UNMAP_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 0xF01, METHOD_BUFFERED, (FILE_READ_ACCESS | FILE_WRITE_ACCESS)) +#define NIRIO_IOCTL_MAP_MEMORY \ + CTL_CODE(FILE_DEVICE_UNKNOWN, \ + 0xF00, \ + METHOD_BUFFERED, \ + (FILE_READ_ACCESS | FILE_WRITE_ACCESS)) +#define NIRIO_IOCTL_UNMAP_MEMORY \ + CTL_CODE(FILE_DEVICE_UNKNOWN, \ + 0xF01, \ + METHOD_BUFFERED, \ + (FILE_READ_ACCESS | FILE_WRITE_ACCESS)) namespace nirio_driver_iface { -nirio_status rio_open( - const std::string& device_path, - rio_dev_handle_t& device_handle) +nirio_status rio_open(const std::string& device_path, rio_dev_handle_t& device_handle) { - device_handle = CreateFileA(device_path.c_str(), GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, /* default security */ - OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL /* template file */); - - return (device_handle == INVALID_HANDLE_VALUE) ? NiRio_Status_InvalidParameter : NiRio_Status_Success; + device_handle = CreateFileA(device_path.c_str(), + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, /* default security */ + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL /* template file */); + + return (device_handle == INVALID_HANDLE_VALUE) ? NiRio_Status_InvalidParameter + : NiRio_Status_Success; } void rio_close(rio_dev_handle_t& device_handle) @@ -35,27 +46,30 @@ bool rio_isopen(rio_dev_handle_t device_handle) return (device_handle != INVALID_HANDLE_VALUE); } -nirio_status rio_ioctl( - rio_dev_handle_t device_handle, +nirio_status rio_ioctl(rio_dev_handle_t device_handle, uint32_t ioctl_code, - const void *write_buf, + const void* write_buf, size_t write_buf_len, - void *read_buf, + void* read_buf, size_t read_buf_len) { - if (!rio_isopen(device_handle)) return NiRio_Status_ResourceNotInitialized; + if (!rio_isopen(device_handle)) + return NiRio_Status_ResourceNotInitialized; /* Note, if the file handle was opened with the OVERLAPPED flag, you must - * supply an OVERLAPPED structure to ReadFile, WriteFile, and - * DeviceIoControl, even when doing synchronous IO. */ + * supply an OVERLAPPED structure to ReadFile, WriteFile, and + * DeviceIoControl, even when doing synchronous IO. */ OVERLAPPED zeroedOverlapped = {0}; - DWORD outLen = 0; - - if (!(DeviceIoControl(device_handle, ioctl_code, - const_cast<void*>(write_buf), static_cast<DWORD>(write_buf_len), - read_buf, static_cast<DWORD>(read_buf_len), - &outLen, &zeroedOverlapped ))) - { + DWORD outLen = 0; + + if (!(DeviceIoControl(device_handle, + ioctl_code, + const_cast<void*>(write_buf), + static_cast<DWORD>(write_buf_len), + read_buf, + static_cast<DWORD>(read_buf_len), + &outLen, + &zeroedOverlapped))) { UHD_UNUSED(int_fast32_t lastError) = GetLastError(); return NiRio_Status_SoftwareFault; } @@ -63,42 +77,48 @@ nirio_status rio_ioctl( return NiRio_Status_Success; } -unsigned int __stdcall memory_map_thread_routine(void *context) +unsigned int __stdcall memory_map_thread_routine(void* context) { - rio_mmap_threadargs_t *args = (rio_mmap_threadargs_t*)context; - args->status = rio_ioctl(args->device_handle, NIRIO_IOCTL_MAP_MEMORY, &(args->params), sizeof(args->params), NULL, 0); - if (nirio_status_fatal(args->status)) - { + rio_mmap_threadargs_t* args = (rio_mmap_threadargs_t*)context; + args->status = rio_ioctl(args->device_handle, + NIRIO_IOCTL_MAP_MEMORY, + &(args->params), + sizeof(args->params), + NULL, + 0); + if (nirio_status_fatal(args->status)) { SetEvent(reinterpret_cast<HANDLE>(args->params.map_ready_event_handle)); } return 0; } -nirio_status rio_mmap( - rio_dev_handle_t device_handle, +nirio_status rio_mmap(rio_dev_handle_t device_handle, uint16_t memory_type, size_t size, bool writable, - rio_mmap_t &map) + rio_mmap_t& map) { - if (!rio_isopen(device_handle)) return NiRio_Status_ResourceNotInitialized; + if (!rio_isopen(device_handle)) + return NiRio_Status_ResourceNotInitialized; access_mode_t access_mode = writable ? ACCESS_MODE_WRITE : ACCESS_MODE_READ; - uint64_t mapped_addr = 0; - map.map_thread_args.device_handle = device_handle; - map.map_thread_args.status = NiRio_Status_Success; - map.map_thread_args.params.memoryType = memory_type; - map.map_thread_args.params.size = (uint32_t)size; + uint64_t mapped_addr = 0; + map.map_thread_args.device_handle = device_handle; + map.map_thread_args.status = NiRio_Status_Success; + map.map_thread_args.params.memoryType = memory_type; + map.map_thread_args.params.size = (uint32_t)size; map.map_thread_args.params.mapped_va_ptr = reinterpret_cast<uintptr_t>(&mapped_addr); - map.map_thread_args.params.access_mode = (uint8_t)access_mode; - HANDLE map_ready_event_handle = CreateEventA(NULL, TRUE, FALSE, NULL); + map.map_thread_args.params.access_mode = (uint8_t)access_mode; + HANDLE map_ready_event_handle = CreateEventA(NULL, TRUE, FALSE, NULL); if (map_ready_event_handle == NULL) { map.addr = NULL; return NiRio_Status_SoftwareFault; } - map.map_thread_args.params.map_ready_event_handle = reinterpret_cast<uint64_t>(map_ready_event_handle); - map.map_thread_handle = (HANDLE) _beginthreadex(NULL, 0, memory_map_thread_routine, &(map.map_thread_args), 0, NULL); + map.map_thread_args.params.map_ready_event_handle = + reinterpret_cast<uint64_t>(map_ready_event_handle); + map.map_thread_handle = (HANDLE)_beginthreadex( + NULL, 0, memory_map_thread_routine, &(map.map_thread_args), 0, NULL); nirio_status status = NiRio_Status_Success; if (map.map_thread_handle == NULL) { @@ -117,14 +137,20 @@ nirio_status rio_mmap( return status; } -nirio_status rio_munmap(rio_mmap_t &map) +nirio_status rio_munmap(rio_mmap_t& map) { - if (!rio_isopen(map.map_thread_args.device_handle)) return NiRio_Status_ResourceNotInitialized; + if (!rio_isopen(map.map_thread_args.device_handle)) + return NiRio_Status_ResourceNotInitialized; nirio_status status = NiRio_Status_Success; if (map.addr != NULL) { uint64_t mapped_addr = reinterpret_cast<uintptr_t>(map.addr); - status = rio_ioctl(map.map_thread_args.device_handle, NIRIO_IOCTL_UNMAP_MEMORY, &mapped_addr, sizeof(mapped_addr), NULL, 0); + status = rio_ioctl(map.map_thread_args.device_handle, + NIRIO_IOCTL_UNMAP_MEMORY, + &mapped_addr, + sizeof(mapped_addr), + NULL, + 0); if (nirio_status_not_fatal(status)) { WaitForSingleObject(map.map_thread_handle, INFINITE); } @@ -134,4 +160,4 @@ nirio_status rio_munmap(rio_mmap_t &map) return status; } -} +} // namespace nirio_driver_iface diff --git a/host/lib/transport/nirio/nirio_resource_manager.cpp b/host/lib/transport/nirio/nirio_resource_manager.cpp index 42e85d7c1..4650e83a2 100644 --- a/host/lib/transport/nirio/nirio_resource_manager.cpp +++ b/host/lib/transport/nirio/nirio_resource_manager.cpp @@ -9,22 +9,19 @@ // "push" and "pop" introduced in GCC 4.6; works with all clang #if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 5) - #pragma GCC diagnostic push +# pragma GCC diagnostic push #endif #if defined(__clang__) || defined(__GNUC__) - #pragma GCC diagnostic ignored "-Wmissing-field-initializers" +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" #endif -namespace uhd { namespace niusrprio -{ +namespace uhd { namespace niusrprio { -nirio_resource_manager::nirio_resource_manager():_fifo_info_map(), _reg_info_map() -{ -} +nirio_resource_manager::nirio_resource_manager() : _fifo_info_map(), _reg_info_map() {} void nirio_resource_manager::set_proxy(niriok_proxy::sptr proxy) { - _kernel_proxy = proxy; + _kernel_proxy = proxy; } @@ -34,18 +31,22 @@ nirio_resource_manager::~nirio_resource_manager() } nirio_status nirio_resource_manager::initialize( - const nirio_register_info_vtr& reg_info_vtr, - const nirio_fifo_info_vtr& fifo_info_vtr) + const nirio_register_info_vtr& reg_info_vtr, const nirio_fifo_info_vtr& fifo_info_vtr) { nirio_status status = 0; - for (nirio_fifo_info_vtr::const_iterator it = fifo_info_vtr.begin(); it != fifo_info_vtr.end(); it++) { + for (nirio_fifo_info_vtr::const_iterator it = fifo_info_vtr.begin(); + it != fifo_info_vtr.end(); + it++) { const nirio_fifo_info_t& fifo_info = *it; - status = _add_fifo_resource(fifo_info); - if (nirio_status_fatal(status)) return status; + status = _add_fifo_resource(fifo_info); + if (nirio_status_fatal(status)) + return status; _fifo_info_map.insert(fifo_info_map_t::value_type(fifo_info.name, fifo_info)); } - for (nirio_register_info_vtr::const_iterator it = reg_info_vtr.begin(); it != reg_info_vtr.end(); it++) { + for (nirio_register_info_vtr::const_iterator it = reg_info_vtr.begin(); + it != reg_info_vtr.end(); + it++) { const nirio_register_info_t& reg_info = *it; _reg_info_map.insert(register_info_map_t::value_type(reg_info.name, reg_info)); @@ -59,11 +60,12 @@ void nirio_resource_manager::finalize() } nirio_status nirio_resource_manager::get_register_offset( - const char* register_name, - uint32_t& offset) + const char* register_name, uint32_t& offset) { - register_info_map_t::const_iterator it = _reg_info_map.find(fifo_info_map_t::key_type(register_name)); - if (it == _reg_info_map.end()) return NiRio_Status_InvalidParameter; + register_info_map_t::const_iterator it = + _reg_info_map.find(fifo_info_map_t::key_type(register_name)); + if (it == _reg_info_map.end()) + return NiRio_Status_InvalidParameter; offset = (*it).second.offset; @@ -82,15 +84,18 @@ nirio_status nirio_resource_manager::_set_driver_config() return _kernel_proxy->set_device_config(); } -nirio_fifo_info_t* nirio_resource_manager::_lookup_fifo_info(const char* fifo_name) { - fifo_info_map_t::iterator it = _fifo_info_map.find(fifo_info_map_t::key_type(fifo_name)); - if (it == _fifo_info_map.end()) return NULL; +nirio_fifo_info_t* nirio_resource_manager::_lookup_fifo_info(const char* fifo_name) +{ + fifo_info_map_t::iterator it = + _fifo_info_map.find(fifo_info_map_t::key_type(fifo_name)); + if (it == _fifo_info_map.end()) + return NULL; return &((*it).second); } -}} +}} // namespace uhd::niusrprio #if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 5) - #pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif diff --git a/host/lib/transport/nirio/niriok_proxy.cpp b/host/lib/transport/nirio/niriok_proxy.cpp index ee177c371..4d413bedb 100644 --- a/host/lib/transport/nirio/niriok_proxy.cpp +++ b/host/lib/transport/nirio/niriok_proxy.cpp @@ -12,59 +12,54 @@ // "push" and "pop" introduced in GCC 4.6; works with all clang #if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 5) - #pragma GCC diagnostic push +# pragma GCC diagnostic push #endif #if defined(__clang__) || defined(__GNUC__) - #pragma GCC diagnostic ignored "-Wmissing-field-initializers" +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" #endif -namespace uhd { namespace niusrprio -{ - // initialization of static members - boost::shared_mutex niriok_proxy::_synchronization; +namespace uhd { namespace niusrprio { +// initialization of static members +boost::shared_mutex niriok_proxy::_synchronization; + +//------------------------------------------------------- +// niriok_proxy +//------------------------------------------------------- +niriok_proxy::niriok_proxy() : _device_handle(nirio_driver_iface::INVALID_RIO_HANDLE) {} - //------------------------------------------------------- - // niriok_proxy - //------------------------------------------------------- - niriok_proxy::niriok_proxy(): _device_handle(nirio_driver_iface::INVALID_RIO_HANDLE) - { - } +niriok_proxy::~niriok_proxy() {} + +niriok_proxy::sptr niriok_proxy::make_and_open(const std::string& interface_path) +{ + nirio_status status; - niriok_proxy::~niriok_proxy() - { - } - - niriok_proxy::sptr niriok_proxy::make_and_open(const std::string& interface_path) - { - nirio_status status; - - /* - niriok_proxy_impl_v1 supports NI-RIO 13.0 - niriok_proxy_impl_v2 supports NI-RIO 14.0 and later + /* + niriok_proxy_impl_v1 supports NI-RIO 13.0 + niriok_proxy_impl_v2 supports NI-RIO 14.0 and later - We must dynamically determine which version of the RIO kernel we are - interfacing to. Opening the interface will fail if there is a version - incompatibility, so we try to open successively newer interface - proxies until it succeeds. - */ + We must dynamically determine which version of the RIO kernel we are + interfacing to. Opening the interface will fail if there is a version + incompatibility, so we try to open successively newer interface + proxies until it succeeds. + */ - sptr proxy_v1(new niriok_proxy_impl_v1); - status = proxy_v1->open(interface_path); + sptr proxy_v1(new niriok_proxy_impl_v1); + status = proxy_v1->open(interface_path); - if (nirio_status_not_fatal(status)) - return proxy_v1; + if (nirio_status_not_fatal(status)) + return proxy_v1; - sptr proxy_v2(new niriok_proxy_impl_v2); - status = proxy_v2->open(interface_path); + sptr proxy_v2(new niriok_proxy_impl_v2); + status = proxy_v2->open(interface_path); - if (nirio_status_not_fatal(status)) - return proxy_v2; + if (nirio_status_not_fatal(status)) + return proxy_v2; - throw uhd::runtime_error("Unable to detect a supported version of the NI-RIO kernel interface."); - - } -}} + throw uhd::runtime_error( + "Unable to detect a supported version of the NI-RIO kernel interface."); +} +}} // namespace uhd::niusrprio #if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 5) - #pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif diff --git a/host/lib/transport/nirio/niriok_proxy_impl_v1.cpp b/host/lib/transport/nirio/niriok_proxy_impl_v1.cpp index ae69cb470..673b5f98b 100644 --- a/host/lib/transport/nirio/niriok_proxy_impl_v1.cpp +++ b/host/lib/transport/nirio/niriok_proxy_impl_v1.cpp @@ -10,854 +10,840 @@ // "push" and "pop" introduced in GCC 4.6; works with all clang #if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 5) - #pragma GCC diagnostic push +# pragma GCC diagnostic push #endif #if defined(__clang__) || defined(__GNUC__) - #pragma GCC diagnostic ignored "-Wmissing-field-initializers" +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" #endif // CTL_CODE macro for non-win OSes #ifndef UHD_PLATFORM_WIN32 - #define CTL_CODE(a,controlCode,b,c) (controlCode) +# define CTL_CODE(a, controlCode, b, c) (controlCode) #endif const uint32_t NIRIO_IOCTL_BASE = 0x800; -const uint32_t NIRIO_IOCTL_SYNCOP = - CTL_CODE(FILE_DEVICE_UNKNOWN, - NIRIO_IOCTL_BASE + 4, - METHOD_OUT_DIRECT, - FILE_READ_DATA | FILE_WRITE_DATA); - ///< The synchronous operation code. Note: We - /// must use METHOD_OUT_DIRECT on the syncOp() - /// IOCTL to ensure the contents of the output - /// block are available in the kernel. - -const uint32_t NIRIO_IOCTL_GET_IFACE_NUM = - CTL_CODE(FILE_DEVICE_UNKNOWN, - NIRIO_IOCTL_BASE + 6, - METHOD_BUFFERED, - FILE_READ_DATA); ///< Get the interface number for a device - -//const uint32_t NIRIO_IOCTL_GET_SESSION = - //CTL_CODE(FILE_DEVICE_UNKNOWN, - //NIRIO_IOCTL_BASE + 8, - //METHOD_BUFFERED, - //FILE_READ_ACCESS); ///< Gets a previously opened session to a device - -const uint32_t NIRIO_IOCTL_POST_OPEN = - CTL_CODE(FILE_DEVICE_UNKNOWN, - NIRIO_IOCTL_BASE + 9, - METHOD_BUFFERED, - FILE_READ_ACCESS); ///< Called after opening a session - -const uint32_t NIRIO_IOCTL_PRE_CLOSE = - CTL_CODE(FILE_DEVICE_UNKNOWN, - NIRIO_IOCTL_BASE + 10, - METHOD_BUFFERED, - FILE_READ_ACCESS); ///< Called before closing a session - -namespace uhd { namespace niusrprio -{ - // ------------------------------- - // Function Codes: defined as integers rather than enums because they - // are going to be carried accross boundaries so size matters - - struct NIRIO_FUNC - { - static const uint32_t GET32 = 0x00000001; - static const uint32_t SET32 = 0x00000002; - static const uint32_t SET_DRIVER_CONFIG = 0x00000007; - static const uint32_t FIFO = 0x00000008; - static const uint32_t IO = 0x0000000A; - static const uint32_t FIFO_STOP_ALL = 0x0000000C; - static const uint32_t ADD_RESOURCE = 0x0000000D; - static const uint32_t GET_STRING = 0x0000000E; - static const uint32_t SET_STRING = 0x0000000F; - static const uint32_t DOWNLOAD = 0x00000013; - static const uint32_t RESET = 0x00000014; - }; +const uint32_t NIRIO_IOCTL_SYNCOP = CTL_CODE(FILE_DEVICE_UNKNOWN, + NIRIO_IOCTL_BASE + 4, + METHOD_OUT_DIRECT, + FILE_READ_DATA | FILE_WRITE_DATA); +///< The synchronous operation code. Note: We +/// must use METHOD_OUT_DIRECT on the syncOp() +/// IOCTL to ensure the contents of the output +/// block are available in the kernel. + +const uint32_t NIRIO_IOCTL_GET_IFACE_NUM = CTL_CODE(FILE_DEVICE_UNKNOWN, + NIRIO_IOCTL_BASE + 6, + METHOD_BUFFERED, + FILE_READ_DATA); ///< Get the interface number for a device + +// const uint32_t NIRIO_IOCTL_GET_SESSION = +// CTL_CODE(FILE_DEVICE_UNKNOWN, +// NIRIO_IOCTL_BASE + 8, +// METHOD_BUFFERED, +// FILE_READ_ACCESS); ///< Gets a previously opened session to a device + +const uint32_t NIRIO_IOCTL_POST_OPEN = CTL_CODE(FILE_DEVICE_UNKNOWN, + NIRIO_IOCTL_BASE + 9, + METHOD_BUFFERED, + FILE_READ_ACCESS); ///< Called after opening a session + +const uint32_t NIRIO_IOCTL_PRE_CLOSE = CTL_CODE(FILE_DEVICE_UNKNOWN, + NIRIO_IOCTL_BASE + 10, + METHOD_BUFFERED, + FILE_READ_ACCESS); ///< Called before closing a session + +namespace uhd { namespace niusrprio { +// ------------------------------- +// Function Codes: defined as integers rather than enums because they +// are going to be carried accross boundaries so size matters + +struct NIRIO_FUNC +{ + static const uint32_t GET32 = 0x00000001; + static const uint32_t SET32 = 0x00000002; + static const uint32_t SET_DRIVER_CONFIG = 0x00000007; + static const uint32_t FIFO = 0x00000008; + static const uint32_t IO = 0x0000000A; + static const uint32_t FIFO_STOP_ALL = 0x0000000C; + static const uint32_t ADD_RESOURCE = 0x0000000D; + static const uint32_t GET_STRING = 0x0000000E; + static const uint32_t SET_STRING = 0x0000000F; + static const uint32_t DOWNLOAD = 0x00000013; + static const uint32_t RESET = 0x00000014; +}; + +struct NIRIO_RESOURCE +{ + static const uint32_t INPUT_FIFO = 0xD0000001; + static const uint32_t OUTPUT_FIFO = 0xD0000002; +}; - struct NIRIO_RESOURCE +struct NIRIO_FIFO +{ + static const uint32_t CONFIGURE = 0x80000001; + static const uint32_t START = 0x80000002; + static const uint32_t STOP = 0x80000003; + static const uint32_t READ = 0x80000004; + static const uint32_t WRITE = 0x80000005; + static const uint32_t WAIT = 0x80000006; + static const uint32_t GRANT = 0x80000007; +}; + +struct NIRIO_IO +{ + static const uint32_t POKE64 = 0xA0000005; + static const uint32_t POKE32 = 0xA0000006; + static const uint32_t POKE16 = 0xA0000007; + static const uint32_t POKE8 = 0xA0000008; + static const uint32_t PEEK64 = 0xA0000009; + static const uint32_t PEEK32 = 0xA000000A; + static const uint32_t PEEK16 = 0xA000000B; + static const uint32_t PEEK8 = 0xA000000C; + static const uint32_t READ_BLOCK = 0xA000000D; + static const uint32_t WRITE_BLOCK = 0xA000000E; + static const uint32_t GET_IO_WINDOW = 0xA000000F; + static const uint32_t GET_IO_WINDOW_SIZE = 0xA0000010; +}; + +struct nirio_ioctl_packet_t +{ + nirio_ioctl_packet_t( + void* const _outBuf, const uint32_t _outSize, const int32_t _statusCode) { - static const uint32_t INPUT_FIFO = 0xD0000001; - static const uint32_t OUTPUT_FIFO = 0xD0000002; + outBuf._64BitField = 0; + outBuf.pointer = _outBuf; + outSize = _outSize; + statusCode = _statusCode; }; - struct NIRIO_FIFO - { - static const uint32_t CONFIGURE = 0x80000001; - static const uint32_t START = 0x80000002; - static const uint32_t STOP = 0x80000003; - static const uint32_t READ = 0x80000004; - static const uint32_t WRITE = 0x80000005; - static const uint32_t WAIT = 0x80000006; - static const uint32_t GRANT = 0x80000007; - }; + union { + void* pointer; + uint64_t _64BitField; + } outBuf; - struct NIRIO_IO - { - static const uint32_t POKE64 = 0xA0000005; - static const uint32_t POKE32 = 0xA0000006; - static const uint32_t POKE16 = 0xA0000007; - static const uint32_t POKE8 = 0xA0000008; - static const uint32_t PEEK64 = 0xA0000009; - static const uint32_t PEEK32 = 0xA000000A; - static const uint32_t PEEK16 = 0xA000000B; - static const uint32_t PEEK8 = 0xA000000C; - static const uint32_t READ_BLOCK = 0xA000000D; - static const uint32_t WRITE_BLOCK = 0xA000000E; - static const uint32_t GET_IO_WINDOW = 0xA000000F; - static const uint32_t GET_IO_WINDOW_SIZE = 0xA0000010; - }; + uint32_t outSize; + int32_t statusCode; +}; + +struct nirio_syncop_in_params_t +{ + uint32_t function; + uint32_t subfunction; - struct nirio_ioctl_packet_t { - nirio_ioctl_packet_t(void* const _outBuf, const uint32_t _outSize, const int32_t _statusCode) + union { + struct { - outBuf._64BitField = 0; - outBuf.pointer = _outBuf; - outSize = _outSize; - statusCode = _statusCode; - }; + uint32_t attribute; + uint32_t value; + } attribute32; - union { - void* pointer; - uint64_t _64BitField; - } outBuf; + struct + { + uint32_t attribute; + uint64_t value; + } attribute64; - uint32_t outSize; - int32_t statusCode; - }; + struct + { + uint32_t attribute; + } attributeStr; - struct nirio_syncop_in_params_t - { - uint32_t function; - uint32_t subfunction; - - union - { - struct - { - uint32_t attribute; - uint32_t value; - } attribute32; - - struct - { - uint32_t attribute; - uint64_t value; - } attribute64; - - struct - { - uint32_t attribute; - } attributeStr; - - struct - { - uint32_t attribute; - } download; - - union - { - struct - { + struct + { + uint32_t attribute; + } download; + + union { + struct + { uint32_t reserved_field_0_0_0; - } reserved_field_0_0; - struct - { + } reserved_field_0_0; + struct + { uint32_t reserved_field_0_1_0; uint32_t reserved_field_0_1_1; - } reserved_field_0_1; - struct - { + } reserved_field_0_1; + struct + { uint32_t reserved_field_0_2_0; - } reserved_field_0_2; - } reserved_field_0; + } reserved_field_0_2; + } reserved_field_0; - union - { - struct - { + union { + struct + { uint32_t channel; uint32_t baseAddress; uint32_t depthInSamples; uint32_t version; - } fifo; - struct - { + } fifo; + struct + { uint32_t channel; uint32_t baseAddress; uint32_t depthInSamples; uint32_t version; uint32_t scalarType; uint32_t bitWidth; - } fifoWithDataType; - struct - { + } fifoWithDataType; + struct + { uint64_t rangeBaseAddress; uint32_t rangeSizeInBytes; uint32_t rangeAttribute; - } atomic; // obsolete - } add; + } atomic; // obsolete + } add; - struct - { - uint32_t channel; + struct + { + uint32_t channel; - union - { + union { struct { - uint32_t requestedDepth; - uint8_t requiresActuals; + uint32_t requestedDepth; + uint8_t requiresActuals; } config; struct { - uint32_t timeout; + uint32_t timeout; } read; struct { - uint32_t timeout; - uint32_t scalarType; - uint32_t bitWidth; + uint32_t timeout; + uint32_t scalarType; + uint32_t bitWidth; } readWithDataType; struct { - uint32_t timeout; + uint32_t timeout; } write; struct { - uint32_t timeout; - uint32_t scalarType; - uint32_t bitWidth; + uint32_t timeout; + uint32_t scalarType; + uint32_t bitWidth; } writeWithDataType; struct { - uint32_t elementsRequested; - uint32_t scalarType; - uint32_t bitWidth; - uint32_t timeout; - uint8_t output; + uint32_t elementsRequested; + uint32_t scalarType; + uint32_t bitWidth; + uint32_t timeout; + uint8_t output; } wait; struct { - uint32_t elements; + uint32_t elements; } grant; - } op; - } fifo; - - struct - { - uint64_t reserved_field_1_0; - uint32_t reserved_field_1_1; - uint32_t reserved_field_1_2; - } reserved_field_1; // Obsolete - - struct - { - uint32_t offset; - union - { + } op; + } fifo; + + struct + { + uint64_t reserved_field_1_0; + uint32_t reserved_field_1_1; + uint32_t reserved_field_1_2; + } reserved_field_1; // Obsolete + + struct + { + uint32_t offset; + union { uint64_t value64; uint32_t value32; uint16_t value16; - uint8_t value8; - } value; - union - { - uint32_t sizeToMap; - } memoryMappedIoWindow; - } io; - - struct - { - uint32_t reserved_field_2_0; - uint32_t reserved_field_2_1; - } reserved_field_2; - - struct - { - uint32_t reserved_field_3_0; - } reserved_field_3; - - union - { - struct - { + uint8_t value8; + } value; + union { + uint32_t sizeToMap; + } memoryMappedIoWindow; + } io; + + struct + { + uint32_t reserved_field_2_0; + uint32_t reserved_field_2_1; + } reserved_field_2; + + struct + { + uint32_t reserved_field_3_0; + } reserved_field_3; + + union { + struct + { uint32_t reserved_field_4_0; - int32_t reserved_field_4_1; - } wait; - } reserved_field_4; + int32_t reserved_field_4_1; + } wait; + } reserved_field_4; - } params; + } params; - uint32_t inbufByteLen; + uint32_t inbufByteLen; - union - { - const void* pointer; - uint64_t _64BitField; - } inbuf; - }; + union { + const void* pointer; + uint64_t _64BitField; + } inbuf; +}; - static inline void init_syncop_in_params(nirio_syncop_in_params_t& param, const void* const buf, const uint32_t len) - { - param.inbuf._64BitField = 0; - param.inbuf.pointer = buf; - param.inbufByteLen = len; - } +static inline void init_syncop_in_params( + nirio_syncop_in_params_t& param, const void* const buf, const uint32_t len) +{ + param.inbuf._64BitField = 0; + param.inbuf.pointer = buf; + param.inbufByteLen = len; +} - struct nirio_syncop_out_params_t - { - union - { - struct - { - uint32_t value; - } attribute32; - - struct - { - uint64_t value; - } attribute64; - - union - { - struct - { +struct nirio_syncop_out_params_t +{ + union { + struct + { + uint32_t value; + } attribute32; + + struct + { + uint64_t value; + } attribute64; + + union { + struct + { uint32_t reserved_field_0_0; - } enable; - } reserved_field_0; + } enable; + } reserved_field_0; - struct - { - union - { + struct + { + union { struct { - uint32_t actualDepth; - uint32_t actualSize; + uint32_t actualDepth; + uint32_t actualSize; } config; struct { - uint32_t numberRead; - uint32_t numberRemaining; + uint32_t numberRead; + uint32_t numberRemaining; } read; struct { - uint32_t numberRemaining; + uint32_t numberRemaining; } write; struct { - union - { - void* pointer; - uint64_t _64BitField; - } elements; + union { + void* pointer; + uint64_t _64BitField; + } elements; } wait; - } op; - } fifo; - - struct - { - union - { - union - { - uint64_t value64; - uint32_t value32; - uint16_t value16; - uint8_t value8; + } op; + } fifo; + + struct + { + union { + union { + uint64_t value64; + uint32_t value32; + uint16_t value16; + uint8_t value8; } value; - union - { - void* memoryMappedAddress; - uint64_t _64BitField; + union { + void* memoryMappedAddress; + uint64_t _64BitField; } memoryMappedIoWindow; - union - { - uint32_t size; + union { + uint32_t size; } memoryMappedIoWindowSize; - }; - } io; - - uint32_t stringLength; - - struct - { - uint32_t reserved_field_1_0; - } reserved_field_1; - - } params; + }; + } io; - uint32_t outbufByteLen; + uint32_t stringLength; - union - { - void* pointer; - uint64_t _64BitField; - } outbuf; - }; - - static inline void init_syncop_out_params(nirio_syncop_out_params_t& param, void* buf, uint32_t len) - { - param.outbuf._64BitField = 0; - param.outbuf.pointer = buf; - param.outbufByteLen = len; - } + struct + { + uint32_t reserved_field_1_0; + } reserved_field_1; - //------------------------------------------------------- - // niriok_proxy_impl_v1 - //------------------------------------------------------- - niriok_proxy_impl_v1::niriok_proxy_impl_v1() - { - } + } params; - niriok_proxy_impl_v1::~niriok_proxy_impl_v1() - { - close(); - } + uint32_t outbufByteLen; - nirio_status niriok_proxy_impl_v1::open(const std::string& interface_path) - { - WRITER_LOCK - - if (interface_path.empty()) return NiRio_Status_ResourceNotFound; - - //close if already open. - // use non-locking _close since we already have the lock - _close(); - - nirio_status status = NiRio_Status_Success; - nirio_status_chain(nirio_driver_iface::rio_open( - interface_path, _device_handle), status); - if (nirio_status_not_fatal(status)) { - nirio_status_chain(nirio_driver_iface::rio_ioctl(_device_handle, - NIRIO_IOCTL_POST_OPEN, - NULL, 0, NULL, 0), status); - nirio_ioctl_packet_t out(&_interface_num, sizeof(_interface_num), 0); - nirio_status_chain(nirio_driver_iface::rio_ioctl(_device_handle, - NIRIO_IOCTL_GET_IFACE_NUM, - NULL, 0, - &out, sizeof(out)), status); - - if (nirio_status_fatal(status)) _close(); - } - return status; - } + union { + void* pointer; + uint64_t _64BitField; + } outbuf; +}; - void niriok_proxy_impl_v1::close(void) - { - WRITER_LOCK +static inline void init_syncop_out_params( + nirio_syncop_out_params_t& param, void* buf, uint32_t len) +{ + param.outbuf._64BitField = 0; + param.outbuf.pointer = buf; + param.outbufByteLen = len; +} - _close(); - } +//------------------------------------------------------- +// niriok_proxy_impl_v1 +//------------------------------------------------------- +niriok_proxy_impl_v1::niriok_proxy_impl_v1() {} - // this protected _close doesn't acquire the lock, so it can be used in methods - // that already have the lock - void niriok_proxy_impl_v1::_close() - { +niriok_proxy_impl_v1::~niriok_proxy_impl_v1() +{ + close(); +} - if(nirio_driver_iface::rio_isopen(_device_handle)) - { +nirio_status niriok_proxy_impl_v1::open(const std::string& interface_path) +{ + WRITER_LOCK + + if (interface_path.empty()) + return NiRio_Status_ResourceNotFound; + + // close if already open. + // use non-locking _close since we already have the lock + _close(); + + nirio_status status = NiRio_Status_Success; + nirio_status_chain( + nirio_driver_iface::rio_open(interface_path, _device_handle), status); + if (nirio_status_not_fatal(status)) { + nirio_status_chain(nirio_driver_iface::rio_ioctl( + _device_handle, NIRIO_IOCTL_POST_OPEN, NULL, 0, NULL, 0), + status); + nirio_ioctl_packet_t out(&_interface_num, sizeof(_interface_num), 0); + nirio_status_chain( nirio_driver_iface::rio_ioctl( - _device_handle, NIRIO_IOCTL_PRE_CLOSE, NULL, 0, NULL, 0); - nirio_driver_iface::rio_close(_device_handle); - } - } + _device_handle, NIRIO_IOCTL_GET_IFACE_NUM, NULL, 0, &out, sizeof(out)), + status); - nirio_status niriok_proxy_impl_v1::reset() - { - READER_LOCK + if (nirio_status_fatal(status)) + _close(); + } + return status; +} - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; +void niriok_proxy_impl_v1::close(void) +{ + WRITER_LOCK - in.function = NIRIO_FUNC::RESET; + _close(); +} - return sync_operation(&in, sizeof(in), &out, sizeof(out)); +// this protected _close doesn't acquire the lock, so it can be used in methods +// that already have the lock +void niriok_proxy_impl_v1::_close() +{ + if (nirio_driver_iface::rio_isopen(_device_handle)) { + nirio_driver_iface::rio_ioctl( + _device_handle, NIRIO_IOCTL_PRE_CLOSE, NULL, 0, NULL, 0); + nirio_driver_iface::rio_close(_device_handle); } +} - nirio_status niriok_proxy_impl_v1::get_version( - nirio_version_t type, - uint32_t& major, - uint32_t& upgrade, - uint32_t& maintenance, - char& phase, - uint32_t& build) - { - nirio_device_attribute32_t version_attr = (type==CURRENT)?RIO_CURRENT_VERSION:RIO_OLDEST_COMPATIBLE_VERSION; - uint32_t raw_version = 0; - nirio_status status = get_attribute(version_attr, raw_version); - - major = (raw_version & VERSION_MAJOR_MASK) >> VERSION_MAJOR_SHIFT; - upgrade = (raw_version & VERSION_UPGRD_MASK) >> VERSION_UPGRD_SHIFT; - maintenance = (raw_version & VERSION_MAINT_MASK) >> VERSION_MAINT_SHIFT; - build = (raw_version & VERSION_BUILD_MASK) >> VERSION_BUILD_SHIFT; - - uint32_t phase_num = (raw_version & VERSION_PHASE_MASK) >> VERSION_PHASE_SHIFT; - switch (phase_num) { - case 0: phase = 'd'; break; - case 1: phase = 'a'; break; - case 2: phase = 'b'; break; - case 3: phase = 'f'; break; - } +nirio_status niriok_proxy_impl_v1::reset() +{ + READER_LOCK - return status; - } + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; - nirio_status niriok_proxy_impl_v1::sync_operation( - const void *writeBuffer, - size_t writeBufferLength, - void *readBuffer, - size_t readBufferLength) - { - READER_LOCK + in.function = NIRIO_FUNC::RESET; - nirio_ioctl_packet_t out(readBuffer, readBufferLength, 0); - nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, - NIRIO_IOCTL_SYNCOP, - writeBuffer, writeBufferLength, - &out, sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; + return sync_operation(&in, sizeof(in), &out, sizeof(out)); +} - return out.statusCode; +nirio_status niriok_proxy_impl_v1::get_version(nirio_version_t type, + uint32_t& major, + uint32_t& upgrade, + uint32_t& maintenance, + char& phase, + uint32_t& build) +{ + nirio_device_attribute32_t version_attr = + (type == CURRENT) ? RIO_CURRENT_VERSION : RIO_OLDEST_COMPATIBLE_VERSION; + uint32_t raw_version = 0; + nirio_status status = get_attribute(version_attr, raw_version); + + major = (raw_version & VERSION_MAJOR_MASK) >> VERSION_MAJOR_SHIFT; + upgrade = (raw_version & VERSION_UPGRD_MASK) >> VERSION_UPGRD_SHIFT; + maintenance = (raw_version & VERSION_MAINT_MASK) >> VERSION_MAINT_SHIFT; + build = (raw_version & VERSION_BUILD_MASK) >> VERSION_BUILD_SHIFT; + + uint32_t phase_num = (raw_version & VERSION_PHASE_MASK) >> VERSION_PHASE_SHIFT; + switch (phase_num) { + case 0: + phase = 'd'; + break; + case 1: + phase = 'a'; + break; + case 2: + phase = 'b'; + break; + case 3: + phase = 'f'; + break; } - nirio_status niriok_proxy_impl_v1::get_attribute( - const nirio_device_attribute32_t attribute, - uint32_t& attrValue) - { - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; + return status; +} - in.function = NIRIO_FUNC::GET32; - in.params.attribute32.attribute = static_cast <uint32_t> (attribute); +nirio_status niriok_proxy_impl_v1::sync_operation(const void* writeBuffer, + size_t writeBufferLength, + void* readBuffer, + size_t readBufferLength) +{ + READER_LOCK + + nirio_ioctl_packet_t out(readBuffer, readBufferLength, 0); + nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, + NIRIO_IOCTL_SYNCOP, + writeBuffer, + writeBufferLength, + &out, + sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; + + return out.statusCode; +} + +nirio_status niriok_proxy_impl_v1::get_attribute( + const nirio_device_attribute32_t attribute, uint32_t& attrValue) +{ + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; - nirio_status status = sync_operation(&in, sizeof(in), &out, sizeof(out)); + in.function = NIRIO_FUNC::GET32; + in.params.attribute32.attribute = static_cast<uint32_t>(attribute); - attrValue = out.params.attribute32.value; - return status; - } + nirio_status status = sync_operation(&in, sizeof(in), &out, sizeof(out)); - nirio_status niriok_proxy_impl_v1::set_attribute( - const nirio_device_attribute32_t attribute, - const uint32_t value) - { - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; + attrValue = out.params.attribute32.value; + return status; +} - in.function = NIRIO_FUNC::SET32; - in.params.attribute32.attribute = static_cast <uint32_t> (attribute); - in.params.attribute32.value = value; +nirio_status niriok_proxy_impl_v1::set_attribute( + const nirio_device_attribute32_t attribute, const uint32_t value) +{ + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; - return sync_operation(&in, sizeof(in), &out, sizeof(out)); - } + in.function = NIRIO_FUNC::SET32; + in.params.attribute32.attribute = static_cast<uint32_t>(attribute); + in.params.attribute32.value = value; - nirio_status niriok_proxy_impl_v1::peek(uint32_t offset, uint32_t& value) - { - if (offset % 4 != 0) return NiRio_Status_MisalignedAccess; + return sync_operation(&in, sizeof(in), &out, sizeof(out)); +} - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; +nirio_status niriok_proxy_impl_v1::peek(uint32_t offset, uint32_t& value) +{ + if (offset % 4 != 0) + return NiRio_Status_MisalignedAccess; - in.function = NIRIO_FUNC::IO; - in.subfunction = NIRIO_IO::PEEK32; - in.params.io.offset = offset; + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; - nirio_status status = sync_operation(&in, sizeof(in), &out, sizeof(out)); - value = out.params.io.value.value32; - return status; - } + in.function = NIRIO_FUNC::IO; + in.subfunction = NIRIO_IO::PEEK32; + in.params.io.offset = offset; - nirio_status niriok_proxy_impl_v1::peek(uint32_t offset, uint64_t& value) - { - if (offset % 8 != 0) return NiRio_Status_MisalignedAccess; + nirio_status status = sync_operation(&in, sizeof(in), &out, sizeof(out)); + value = out.params.io.value.value32; + return status; +} - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; +nirio_status niriok_proxy_impl_v1::peek(uint32_t offset, uint64_t& value) +{ + if (offset % 8 != 0) + return NiRio_Status_MisalignedAccess; - in.function = NIRIO_FUNC::IO; - in.subfunction = NIRIO_IO::PEEK64; - in.params.io.offset = offset; + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; - nirio_status status = sync_operation(&in, sizeof(in), &out, sizeof(out)); - value = out.params.io.value.value64; - return status; - } - - nirio_status niriok_proxy_impl_v1::poke(uint32_t offset, const uint32_t& value) - { - if (offset % 4 != 0) return NiRio_Status_MisalignedAccess; + in.function = NIRIO_FUNC::IO; + in.subfunction = NIRIO_IO::PEEK64; + in.params.io.offset = offset; - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; + nirio_status status = sync_operation(&in, sizeof(in), &out, sizeof(out)); + value = out.params.io.value.value64; + return status; +} - in.function = NIRIO_FUNC::IO; - in.subfunction = NIRIO_IO::POKE32; - in.params.io.offset = offset; - in.params.io.value.value32 = value; +nirio_status niriok_proxy_impl_v1::poke(uint32_t offset, const uint32_t& value) +{ + if (offset % 4 != 0) + return NiRio_Status_MisalignedAccess; - return sync_operation(&in, sizeof(in), &out, sizeof(out)); - } + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; - nirio_status niriok_proxy_impl_v1::poke(uint32_t offset, const uint64_t& value) - { - if (offset % 8 != 0) return NiRio_Status_MisalignedAccess; + in.function = NIRIO_FUNC::IO; + in.subfunction = NIRIO_IO::POKE32; + in.params.io.offset = offset; + in.params.io.value.value32 = value; - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; + return sync_operation(&in, sizeof(in), &out, sizeof(out)); +} - in.function = NIRIO_FUNC::IO; - in.subfunction = NIRIO_IO::POKE64; - in.params.io.offset = offset; - in.params.io.value.value64 = value; +nirio_status niriok_proxy_impl_v1::poke(uint32_t offset, const uint64_t& value) +{ + if (offset % 8 != 0) + return NiRio_Status_MisalignedAccess; - return sync_operation(&in, sizeof(in), &out, sizeof(out)); - } + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; - nirio_status niriok_proxy_impl_v1::map_fifo_memory( - uint32_t fifo_instance, - size_t size, - nirio_driver_iface::rio_mmap_t& map) - { - READER_LOCK + in.function = NIRIO_FUNC::IO; + in.subfunction = NIRIO_IO::POKE64; + in.params.io.offset = offset; + in.params.io.value.value64 = value; - return nirio_driver_iface::rio_mmap(_device_handle, - GET_FIFO_MEMORY_TYPE(fifo_instance), - size, true, map); - } + return sync_operation(&in, sizeof(in), &out, sizeof(out)); +} - nirio_status niriok_proxy_impl_v1::unmap_fifo_memory( - nirio_driver_iface::rio_mmap_t& map) - { - READER_LOCK +nirio_status niriok_proxy_impl_v1::map_fifo_memory( + uint32_t fifo_instance, size_t size, nirio_driver_iface::rio_mmap_t& map) +{ + READER_LOCK - return nirio_driver_iface::rio_munmap(map); - } + return nirio_driver_iface::rio_mmap( + _device_handle, GET_FIFO_MEMORY_TYPE(fifo_instance), size, true, map); +} - nirio_status niriok_proxy_impl_v1::stop_all_fifos() - { - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; +nirio_status niriok_proxy_impl_v1::unmap_fifo_memory(nirio_driver_iface::rio_mmap_t& map) +{ + READER_LOCK - in.function = NIRIO_FUNC::FIFO_STOP_ALL; + return nirio_driver_iface::rio_munmap(map); +} - return sync_operation(&in, sizeof(in), &out, sizeof(out)); - } - - nirio_status niriok_proxy_impl_v1::add_fifo_resource(const nirio_fifo_info_t& fifo_info) - { - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; - - in.function = NIRIO_FUNC::ADD_RESOURCE; - if (fifo_info.direction == OUTPUT_FIFO) - in.subfunction = NIRIO_RESOURCE::OUTPUT_FIFO; - else - in.subfunction = NIRIO_RESOURCE::INPUT_FIFO; - - in.params.add.fifoWithDataType.channel = fifo_info.channel; - in.params.add.fifoWithDataType.baseAddress = fifo_info.base_addr; - in.params.add.fifoWithDataType.depthInSamples = fifo_info.depth; - in.params.add.fifoWithDataType.scalarType = static_cast <uint32_t> (fifo_info.scalar_type); - in.params.add.fifoWithDataType.bitWidth = fifo_info.bitWidth; - in.params.add.fifoWithDataType.version = fifo_info.version; - //fifo_info.integerWordLength is not needed by the v1 kernel interface - - return sync_operation(&in, sizeof(in), &out, sizeof(out)); - } +nirio_status niriok_proxy_impl_v1::stop_all_fifos() +{ + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; - nirio_status niriok_proxy_impl_v1::set_device_config() - { - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; + in.function = NIRIO_FUNC::FIFO_STOP_ALL; - in.function = NIRIO_FUNC::SET_DRIVER_CONFIG; - in.subfunction = 0; + return sync_operation(&in, sizeof(in), &out, sizeof(out)); +} - return sync_operation(&in, sizeof(in), &out, sizeof(out)); - } +nirio_status niriok_proxy_impl_v1::add_fifo_resource(const nirio_fifo_info_t& fifo_info) +{ + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; + + in.function = NIRIO_FUNC::ADD_RESOURCE; + if (fifo_info.direction == OUTPUT_FIFO) + in.subfunction = NIRIO_RESOURCE::OUTPUT_FIFO; + else + in.subfunction = NIRIO_RESOURCE::INPUT_FIFO; + + in.params.add.fifoWithDataType.channel = fifo_info.channel; + in.params.add.fifoWithDataType.baseAddress = fifo_info.base_addr; + in.params.add.fifoWithDataType.depthInSamples = fifo_info.depth; + in.params.add.fifoWithDataType.scalarType = + static_cast<uint32_t>(fifo_info.scalar_type); + in.params.add.fifoWithDataType.bitWidth = fifo_info.bitWidth; + in.params.add.fifoWithDataType.version = fifo_info.version; + // fifo_info.integerWordLength is not needed by the v1 kernel interface + + return sync_operation(&in, sizeof(in), &out, sizeof(out)); +} + +nirio_status niriok_proxy_impl_v1::set_device_config() +{ + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; - nirio_status niriok_proxy_impl_v1::start_fifo( - uint32_t channel) - { - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; + in.function = NIRIO_FUNC::SET_DRIVER_CONFIG; + in.subfunction = 0; - in.function = NIRIO_FUNC::FIFO; - in.subfunction = NIRIO_FIFO::START; + return sync_operation(&in, sizeof(in), &out, sizeof(out)); +} - in.params.fifo.channel = channel; +nirio_status niriok_proxy_impl_v1::start_fifo(uint32_t channel) +{ + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; - return sync_operation(&in, sizeof(in), &out, sizeof(out)); - } + in.function = NIRIO_FUNC::FIFO; + in.subfunction = NIRIO_FIFO::START; - nirio_status niriok_proxy_impl_v1::stop_fifo( - uint32_t channel) - { - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; + in.params.fifo.channel = channel; - in.function = NIRIO_FUNC::FIFO; - in.subfunction = NIRIO_FIFO::STOP; + return sync_operation(&in, sizeof(in), &out, sizeof(out)); +} - in.params.fifo.channel = channel; +nirio_status niriok_proxy_impl_v1::stop_fifo(uint32_t channel) +{ + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; - return sync_operation(&in, sizeof(in), &out, sizeof(out)); - } + in.function = NIRIO_FUNC::FIFO; + in.subfunction = NIRIO_FIFO::STOP; - nirio_status niriok_proxy_impl_v1::configure_fifo( - uint32_t channel, - uint32_t requested_depth, - uint8_t requires_actuals, - uint32_t& actual_depth, - uint32_t& actual_size) - { - nirio_status status = NiRio_Status_Success; + in.params.fifo.channel = channel; - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; + return sync_operation(&in, sizeof(in), &out, sizeof(out)); +} - in.function = NIRIO_FUNC::FIFO; - in.subfunction = NIRIO_FIFO::CONFIGURE; +nirio_status niriok_proxy_impl_v1::configure_fifo(uint32_t channel, + uint32_t requested_depth, + uint8_t requires_actuals, + uint32_t& actual_depth, + uint32_t& actual_size) +{ + nirio_status status = NiRio_Status_Success; - in.params.fifo.channel = channel; - in.params.fifo.op.config.requestedDepth = requested_depth; - in.params.fifo.op.config.requiresActuals = requires_actuals; + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; - status = sync_operation(&in, sizeof(in), &out, sizeof(out)); - if (nirio_status_fatal(status)) return status; + in.function = NIRIO_FUNC::FIFO; + in.subfunction = NIRIO_FIFO::CONFIGURE; - actual_depth = out.params.fifo.op.config.actualDepth; - actual_size = out.params.fifo.op.config.actualSize; + in.params.fifo.channel = channel; + in.params.fifo.op.config.requestedDepth = requested_depth; + in.params.fifo.op.config.requiresActuals = requires_actuals; + status = sync_operation(&in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(status)) return status; - } - - nirio_status niriok_proxy_impl_v1::wait_on_fifo( - uint32_t channel, - uint32_t elements_requested, - uint32_t scalar_type, - uint32_t bit_width, - uint32_t timeout, - uint8_t output, - void*& data_pointer, - uint32_t& elements_acquired, - uint32_t& elements_remaining) - { - nirio_status status = NiRio_Status_Success; - nirio_syncop_in_params_t in = {}; - uint32_t stuffed[2]; - nirio_syncop_out_params_t out = {}; - init_syncop_out_params(out, stuffed, sizeof(stuffed)); - - in.function = NIRIO_FUNC::FIFO; - in.subfunction = NIRIO_FIFO::WAIT; + actual_depth = out.params.fifo.op.config.actualDepth; + actual_size = out.params.fifo.op.config.actualSize; + + return status; +} + +nirio_status niriok_proxy_impl_v1::wait_on_fifo(uint32_t channel, + uint32_t elements_requested, + uint32_t scalar_type, + uint32_t bit_width, + uint32_t timeout, + uint8_t output, + void*& data_pointer, + uint32_t& elements_acquired, + uint32_t& elements_remaining) +{ + nirio_status status = NiRio_Status_Success; - in.params.fifo.channel = channel; - in.params.fifo.op.wait.elementsRequested = elements_requested; - in.params.fifo.op.wait.scalarType = scalar_type; - in.params.fifo.op.wait.bitWidth = bit_width; - in.params.fifo.op.wait.output = output; - in.params.fifo.op.wait.timeout = timeout; + nirio_syncop_in_params_t in = {}; + uint32_t stuffed[2]; + nirio_syncop_out_params_t out = {}; + init_syncop_out_params(out, stuffed, sizeof(stuffed)); - status = sync_operation(&in, sizeof(in), &out, sizeof(out)); - if (nirio_status_fatal(status)) return status; + in.function = NIRIO_FUNC::FIFO; + in.subfunction = NIRIO_FIFO::WAIT; - data_pointer = out.params.fifo.op.wait.elements.pointer; - elements_acquired = stuffed[0]; - elements_remaining = stuffed[1]; + in.params.fifo.channel = channel; + in.params.fifo.op.wait.elementsRequested = elements_requested; + in.params.fifo.op.wait.scalarType = scalar_type; + in.params.fifo.op.wait.bitWidth = bit_width; + in.params.fifo.op.wait.output = output; + in.params.fifo.op.wait.timeout = timeout; + status = sync_operation(&in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(status)) return status; - } - - nirio_status niriok_proxy_impl_v1::grant_fifo( - uint32_t channel, - uint32_t elements_to_grant) - { - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; - - in.function = NIRIO_FUNC::FIFO; - in.subfunction = NIRIO_FIFO::GRANT; - - in.params.fifo.channel = channel; - in.params.fifo.op.grant.elements = elements_to_grant; - - return sync_operation(&in, sizeof(in), &out, sizeof(out)); - } - nirio_status niriok_proxy_impl_v1::read_fifo( - uint32_t channel, - uint32_t elements_to_read, - void* buffer, - uint32_t buffer_datatype_width, - uint32_t scalar_type, - uint32_t bit_width, - uint32_t timeout, - uint32_t& number_read, - uint32_t& number_remaining) - { - nirio_status status = NiRio_Status_Success; + data_pointer = out.params.fifo.op.wait.elements.pointer; + elements_acquired = stuffed[0]; + elements_remaining = stuffed[1]; - nirio_syncop_in_params_t in = {}; - nirio_syncop_out_params_t out = {}; - init_syncop_out_params(out, buffer, elements_to_read * buffer_datatype_width); + return status; +} - in.function = NIRIO_FUNC::FIFO; - in.subfunction = NIRIO_FIFO::READ; +nirio_status niriok_proxy_impl_v1::grant_fifo( + uint32_t channel, uint32_t elements_to_grant) +{ + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; + + in.function = NIRIO_FUNC::FIFO; + in.subfunction = NIRIO_FIFO::GRANT; + + in.params.fifo.channel = channel; + in.params.fifo.op.grant.elements = elements_to_grant; + + return sync_operation(&in, sizeof(in), &out, sizeof(out)); +} + +nirio_status niriok_proxy_impl_v1::read_fifo(uint32_t channel, + uint32_t elements_to_read, + void* buffer, + uint32_t buffer_datatype_width, + uint32_t scalar_type, + uint32_t bit_width, + uint32_t timeout, + uint32_t& number_read, + uint32_t& number_remaining) +{ + nirio_status status = NiRio_Status_Success; - in.params.fifo.channel = channel; - in.params.fifo.op.readWithDataType.timeout = timeout; - in.params.fifo.op.readWithDataType.scalarType = scalar_type; - in.params.fifo.op.readWithDataType.bitWidth = bit_width; + nirio_syncop_in_params_t in = {}; + nirio_syncop_out_params_t out = {}; + init_syncop_out_params(out, buffer, elements_to_read * buffer_datatype_width); - status = sync_operation(&in, sizeof(in), &out, sizeof(out)); - if (nirio_status_fatal(status) && (status != NiRio_Status_FifoTimeout)) return status; + in.function = NIRIO_FUNC::FIFO; + in.subfunction = NIRIO_FIFO::READ; - number_read = out.params.fifo.op.read.numberRead; - number_remaining = out.params.fifo.op.read.numberRemaining; + in.params.fifo.channel = channel; + in.params.fifo.op.readWithDataType.timeout = timeout; + in.params.fifo.op.readWithDataType.scalarType = scalar_type; + in.params.fifo.op.readWithDataType.bitWidth = bit_width; + status = sync_operation(&in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(status) && (status != NiRio_Status_FifoTimeout)) return status; - } - nirio_status niriok_proxy_impl_v1::write_fifo( - uint32_t channel, - uint32_t elements_to_write, - void* buffer, - uint32_t buffer_datatype_width, - uint32_t scalar_type, - uint32_t bit_width, - uint32_t timeout, - uint32_t& number_remaining) - { - nirio_status status = NiRio_Status_Success; + number_read = out.params.fifo.op.read.numberRead; + number_remaining = out.params.fifo.op.read.numberRemaining; - nirio_syncop_in_params_t in = {}; - init_syncop_in_params(in, buffer, elements_to_write * buffer_datatype_width); - nirio_syncop_out_params_t out = {}; + return status; +} - in.function = NIRIO_FUNC::FIFO; - in.subfunction = NIRIO_FIFO::WRITE; +nirio_status niriok_proxy_impl_v1::write_fifo(uint32_t channel, + uint32_t elements_to_write, + void* buffer, + uint32_t buffer_datatype_width, + uint32_t scalar_type, + uint32_t bit_width, + uint32_t timeout, + uint32_t& number_remaining) +{ + nirio_status status = NiRio_Status_Success; - in.params.fifo.channel = channel; - in.params.fifo.op.writeWithDataType.timeout = timeout; - in.params.fifo.op.writeWithDataType.scalarType = scalar_type; - in.params.fifo.op.writeWithDataType.bitWidth = bit_width; + nirio_syncop_in_params_t in = {}; + init_syncop_in_params(in, buffer, elements_to_write * buffer_datatype_width); + nirio_syncop_out_params_t out = {}; - status = sync_operation(&in, sizeof(in), &out, sizeof(out)); - if (nirio_status_fatal(status) && (status != NiRio_Status_FifoTimeout)) return status; + in.function = NIRIO_FUNC::FIFO; + in.subfunction = NIRIO_FIFO::WRITE; - number_remaining = out.params.fifo.op.write.numberRemaining; + in.params.fifo.channel = channel; + in.params.fifo.op.writeWithDataType.timeout = timeout; + in.params.fifo.op.writeWithDataType.scalarType = scalar_type; + in.params.fifo.op.writeWithDataType.bitWidth = bit_width; + status = sync_operation(&in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(status) && (status != NiRio_Status_FifoTimeout)) return status; - } -}} + number_remaining = out.params.fifo.op.write.numberRemaining; + + return status; +} + +}} // namespace uhd::niusrprio #if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 5) - #pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif diff --git a/host/lib/transport/nirio/niriok_proxy_impl_v2.cpp b/host/lib/transport/nirio/niriok_proxy_impl_v2.cpp index 7e442eef1..cbc264dfc 100644 --- a/host/lib/transport/nirio/niriok_proxy_impl_v2.cpp +++ b/host/lib/transport/nirio/niriok_proxy_impl_v2.cpp @@ -11,871 +11,840 @@ // "push" and "pop" introduced in GCC 4.6; works with all clang #if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 5) - #pragma GCC diagnostic push +# pragma GCC diagnostic push #endif #if defined(__clang__) || defined(__GNUC__) - #pragma GCC diagnostic ignored "-Wmissing-field-initializers" +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" #endif -#define IOCTL_TRANSPORT_GET32 IOCTL(0, 0, IOCTL_ACCESS_READ) -#define IOCTL_TRANSPORT_SET32 IOCTL(0, 1, IOCTL_ACCESS_WRITE) -#define IOCTL_TRANSPORT_GET_STRING IOCTL(0, 2, IOCTL_ACCESS_READ) -#define IOCTL_TRANSPORT_SET_STRING IOCTL(0, 3, IOCTL_ACCESS_WRITE) -#define IOCTL_TRANSPORT_RESET IOCTL(1, 1, IOCTL_ACCESS_WRITE) -#define IOCTL_TRANSPORT_ADD_INPUT_FIFO_RESOURCE IOCTL(2, 0, IOCTL_ACCESS_ANY) -#define IOCTL_TRANSPORT_ADD_OUTPUT_FIFO_RESOURCE IOCTL(2, 1, IOCTL_ACCESS_ANY) -#define IOCTL_TRANSPORT_SET_DEVICE_CONFIG IOCTL(2, 3, IOCTL_ACCESS_WRITE) -#define IOCTL_TRANSPORT_FIFO_CONFIG IOCTL(4, 0, IOCTL_ACCESS_ANY) -#define IOCTL_TRANSPORT_FIFO_START IOCTL(4, 1, IOCTL_ACCESS_ANY) -#define IOCTL_TRANSPORT_FIFO_STOP IOCTL(4, 2, IOCTL_ACCESS_ANY) -#define IOCTL_TRANSPORT_FIFO_READ IOCTL(4, 3, IOCTL_ACCESS_READ) -#define IOCTL_TRANSPORT_FIFO_WRITE IOCTL(4, 4, IOCTL_ACCESS_WRITE) -#define IOCTL_TRANSPORT_FIFO_WAIT IOCTL(4, 5, IOCTL_ACCESS_ANY) -#define IOCTL_TRANSPORT_FIFO_GRANT IOCTL(4, 6, IOCTL_ACCESS_ANY) -#define IOCTL_TRANSPORT_FIFO_STOP_ALL IOCTL(4, 7, IOCTL_ACCESS_ANY) -#define IOCTL_TRANSPORT_PEEK64 IOCTL(5, 2, IOCTL_ACCESS_READ) -#define IOCTL_TRANSPORT_PEEK32 IOCTL(5, 3, IOCTL_ACCESS_READ) -#define IOCTL_TRANSPORT_POKE64 IOCTL(5, 6, IOCTL_ACCESS_WRITE) -#define IOCTL_TRANSPORT_POKE32 IOCTL(5, 7, IOCTL_ACCESS_WRITE) -#define IOCTL_TRANSPORT_POST_OPEN IOCTL(8, 0, IOCTL_ACCESS_ANY) -#define IOCTL_TRANSPORT_PRE_CLOSE IOCTL(8, 1, IOCTL_ACCESS_ANY) - -namespace uhd { namespace niusrprio -{ - //------------------------------------------------------- - // ioctl param typedefs - //------------------------------------------------------- - typedef struct { - nirio_scalar_type_t scalarType; - nirio_u32_t bitWidth; - nirio_i32_t integerWordLength; - } nirio_fifo_data_type_t; - - typedef struct in_transport_get32 - { - nirio_device_attribute32_t attribute; - int32_t status; - } in_transport_get32_t; - typedef struct out_transport_get32 - { - uint32_t retVal__; - int32_t status; - } out_transport_get32_t; - typedef struct in_transport_set32 - { - nirio_device_attribute32_t attribute; - uint32_t value; - int32_t status; - } in_transport_set32_t; - typedef struct out_transport_set32 - { - int32_t status; - } out_transport_set32_t; - typedef struct out_transport_get_string - { - uint32_t stringLen; - int32_t status; - } out_transport_get_string_t; - typedef struct out_transport_set_string - { - int32_t status; - } out_transport_set_string_t; - typedef struct in_transport_reset - { - int32_t status; - } in_transport_reset_t; - typedef struct out_transport_reset - { - int32_t status; - } out_transport_reset_t; - typedef struct in_transport_add_input_fifo_resource - { - uint32_t channel; - uint32_t baseAddress; - uint32_t depthInSamples; - nirio_fifo_data_type_t dataType; - uint32_t version; - int32_t status; - } in_transport_add_input_fifo_resource_t; - typedef struct out_transport_addInputFifo_resource - { - int32_t status; - } out_transport_add_input_fifo_resource_t; - typedef struct in_transport_addOutputFifo_resource - { - uint32_t channel; - uint32_t baseAddress; - uint32_t depthInSamples; - nirio_fifo_data_type_t dataType; - uint32_t version; - int32_t status; - } in_transport_add_output_fifo_resource_t; - typedef struct out_transport_addOutputFifo_resource - { - int32_t status; - } out_transport_add_output_fifo_resource_t; - typedef struct in_transport_setDevice_config - { - uint32_t attribute; - int32_t status; - } in_transport_set_device_config_t; - typedef struct out_transport_setDevice_config - { - int32_t status; - } out_transport_set_device_config_t; - typedef struct in_transport_fifo_config - { - uint32_t channel; - aligned_uint64_t requestedDepth; - int32_t status; - } in_transport_fifo_config_t; - typedef struct out_transport_fifo_config - { - aligned_uint64_t actualDepth; - aligned_uint64_t actualSize; - int32_t status; - } out_transport_fifo_config_t; - typedef struct in_transport_fifo_start - { - uint32_t channel; - int32_t status; - } in_transport_fifo_start_t; - typedef struct out_transport_fifo_start - { - int32_t status; - } out_transport_fifo_start_t; - typedef struct in_transport_fifo_stop - { - uint32_t channel; - int32_t status; - } in_transport_fifo_stop_t; - typedef struct out_transport_fifo_stop - { - int32_t status; - } out_transport_fifo_stop_t; - typedef struct in_transport_fifo_read - { - uint32_t channel; - aligned_uint64_t buf; - uint32_t numberElements; - nirio_fifo_data_type_t dataType; - uint32_t timeout; - int32_t status; - } in_transport_fifo_read_t; - typedef struct out_transport_fifo_read - { - uint32_t read; - uint32_t remaining; - int32_t status; - } out_transport_fifo_read_t; - typedef struct in_transport_fifo_write - { - uint32_t channel; - aligned_uint64_t buf; - uint32_t numberElements; - nirio_fifo_data_type_t dataType; - uint32_t timeout; - int32_t status; - } in_transport_fifo_write_t; - typedef struct out_transport_fifo_write - { - uint32_t remaining; - int32_t status; - } out_transport_fifo_write_t; - typedef struct in_transport_fifo_wait - { - uint32_t channel; - aligned_uint64_t elementsRequested; - nirio_fifo_data_type_t dataType; - bool output; - uint32_t timeout; - int32_t status; - } in_transport_fifo_wait_t; - typedef struct out_transport_fifo_wait - { - aligned_uint64_t elements; - aligned_uint64_t elementsAcquired; - aligned_uint64_t elementsRemaining; - int32_t status; - } out_transport_fifo_wait_t; - typedef struct in_transport_fifo_grant - { - uint32_t channel; - aligned_uint64_t elements; - int32_t status; - } in_transport_fifo_grant_t; - typedef struct out_transport_fifo_grant - { - int32_t status; - } out_transport_fifo_grant_t; - typedef struct in_transport_fifoStop_all - { - int32_t status; - } in_transport_fifo_stop_all_t; - typedef struct out_transport_fifoStop_all - { - int32_t status; - } out_transport_fifo_stop_all_t; - typedef struct in_transport_peek64 - { - uint32_t offset; - int32_t status; - } in_transport_peek64_t; - typedef struct out_transport_peek64 - { - aligned_uint64_t retVal__; - int32_t status; - } out_transport_peek64_t; - typedef struct in_transport_peek32 - { - uint32_t offset; - int32_t status; - } in_transport_peek32_t; - typedef struct out_transport_peek32 - { - uint32_t retVal__; - int32_t status; - } out_transport_peek32_t; - typedef struct in_transport_poke64 - { - uint32_t offset; - aligned_uint64_t value; - int32_t status; - } in_transport_poke64_t; - typedef struct out_transport_poke64 - { - int32_t status; - } out_transport_poke64_t; - typedef struct in_transport_poke32 - { - uint32_t offset; - uint32_t value; - int32_t status; - } in_transport_poke32_t; - typedef struct out_transport_poke32 - { - int32_t status; - } out_transport_poke32_t; - typedef struct in_transport_post_open - { - int32_t status; - } in_transport_post_open_t; - typedef struct out_transport_post_open - { - int32_t status; - } out_transport_post_open_t; - typedef struct in_transport_pre_close - { - int32_t status; - } in_transport_pre_close_t; - typedef struct out_transport_pre_close - { - int32_t status; - } out_transport_pre_close_t; - - //------------------------------------------------------- - // niriok_proxy_impl_v2 - //------------------------------------------------------- - niriok_proxy_impl_v2::niriok_proxy_impl_v2() - { - } +#define IOCTL_TRANSPORT_GET32 IOCTL(0, 0, IOCTL_ACCESS_READ) +#define IOCTL_TRANSPORT_SET32 IOCTL(0, 1, IOCTL_ACCESS_WRITE) +#define IOCTL_TRANSPORT_GET_STRING IOCTL(0, 2, IOCTL_ACCESS_READ) +#define IOCTL_TRANSPORT_SET_STRING IOCTL(0, 3, IOCTL_ACCESS_WRITE) +#define IOCTL_TRANSPORT_RESET IOCTL(1, 1, IOCTL_ACCESS_WRITE) +#define IOCTL_TRANSPORT_ADD_INPUT_FIFO_RESOURCE IOCTL(2, 0, IOCTL_ACCESS_ANY) +#define IOCTL_TRANSPORT_ADD_OUTPUT_FIFO_RESOURCE IOCTL(2, 1, IOCTL_ACCESS_ANY) +#define IOCTL_TRANSPORT_SET_DEVICE_CONFIG IOCTL(2, 3, IOCTL_ACCESS_WRITE) +#define IOCTL_TRANSPORT_FIFO_CONFIG IOCTL(4, 0, IOCTL_ACCESS_ANY) +#define IOCTL_TRANSPORT_FIFO_START IOCTL(4, 1, IOCTL_ACCESS_ANY) +#define IOCTL_TRANSPORT_FIFO_STOP IOCTL(4, 2, IOCTL_ACCESS_ANY) +#define IOCTL_TRANSPORT_FIFO_READ IOCTL(4, 3, IOCTL_ACCESS_READ) +#define IOCTL_TRANSPORT_FIFO_WRITE IOCTL(4, 4, IOCTL_ACCESS_WRITE) +#define IOCTL_TRANSPORT_FIFO_WAIT IOCTL(4, 5, IOCTL_ACCESS_ANY) +#define IOCTL_TRANSPORT_FIFO_GRANT IOCTL(4, 6, IOCTL_ACCESS_ANY) +#define IOCTL_TRANSPORT_FIFO_STOP_ALL IOCTL(4, 7, IOCTL_ACCESS_ANY) +#define IOCTL_TRANSPORT_PEEK64 IOCTL(5, 2, IOCTL_ACCESS_READ) +#define IOCTL_TRANSPORT_PEEK32 IOCTL(5, 3, IOCTL_ACCESS_READ) +#define IOCTL_TRANSPORT_POKE64 IOCTL(5, 6, IOCTL_ACCESS_WRITE) +#define IOCTL_TRANSPORT_POKE32 IOCTL(5, 7, IOCTL_ACCESS_WRITE) +#define IOCTL_TRANSPORT_POST_OPEN IOCTL(8, 0, IOCTL_ACCESS_ANY) +#define IOCTL_TRANSPORT_PRE_CLOSE IOCTL(8, 1, IOCTL_ACCESS_ANY) + +namespace uhd { namespace niusrprio { +//------------------------------------------------------- +// ioctl param typedefs +//------------------------------------------------------- +typedef struct +{ + nirio_scalar_type_t scalarType; + nirio_u32_t bitWidth; + nirio_i32_t integerWordLength; +} nirio_fifo_data_type_t; - niriok_proxy_impl_v2::~niriok_proxy_impl_v2() - { - close(); - } +typedef struct in_transport_get32 +{ + nirio_device_attribute32_t attribute; + int32_t status; +} in_transport_get32_t; +typedef struct out_transport_get32 +{ + uint32_t retVal__; + int32_t status; +} out_transport_get32_t; +typedef struct in_transport_set32 +{ + nirio_device_attribute32_t attribute; + uint32_t value; + int32_t status; +} in_transport_set32_t; +typedef struct out_transport_set32 +{ + int32_t status; +} out_transport_set32_t; +typedef struct out_transport_get_string +{ + uint32_t stringLen; + int32_t status; +} out_transport_get_string_t; +typedef struct out_transport_set_string +{ + int32_t status; +} out_transport_set_string_t; +typedef struct in_transport_reset +{ + int32_t status; +} in_transport_reset_t; +typedef struct out_transport_reset +{ + int32_t status; +} out_transport_reset_t; +typedef struct in_transport_add_input_fifo_resource +{ + uint32_t channel; + uint32_t baseAddress; + uint32_t depthInSamples; + nirio_fifo_data_type_t dataType; + uint32_t version; + int32_t status; +} in_transport_add_input_fifo_resource_t; +typedef struct out_transport_addInputFifo_resource +{ + int32_t status; +} out_transport_add_input_fifo_resource_t; +typedef struct in_transport_addOutputFifo_resource +{ + uint32_t channel; + uint32_t baseAddress; + uint32_t depthInSamples; + nirio_fifo_data_type_t dataType; + uint32_t version; + int32_t status; +} in_transport_add_output_fifo_resource_t; +typedef struct out_transport_addOutputFifo_resource +{ + int32_t status; +} out_transport_add_output_fifo_resource_t; +typedef struct in_transport_setDevice_config +{ + uint32_t attribute; + int32_t status; +} in_transport_set_device_config_t; +typedef struct out_transport_setDevice_config +{ + int32_t status; +} out_transport_set_device_config_t; +typedef struct in_transport_fifo_config +{ + uint32_t channel; + aligned_uint64_t requestedDepth; + int32_t status; +} in_transport_fifo_config_t; +typedef struct out_transport_fifo_config +{ + aligned_uint64_t actualDepth; + aligned_uint64_t actualSize; + int32_t status; +} out_transport_fifo_config_t; +typedef struct in_transport_fifo_start +{ + uint32_t channel; + int32_t status; +} in_transport_fifo_start_t; +typedef struct out_transport_fifo_start +{ + int32_t status; +} out_transport_fifo_start_t; +typedef struct in_transport_fifo_stop +{ + uint32_t channel; + int32_t status; +} in_transport_fifo_stop_t; +typedef struct out_transport_fifo_stop +{ + int32_t status; +} out_transport_fifo_stop_t; +typedef struct in_transport_fifo_read +{ + uint32_t channel; + aligned_uint64_t buf; + uint32_t numberElements; + nirio_fifo_data_type_t dataType; + uint32_t timeout; + int32_t status; +} in_transport_fifo_read_t; +typedef struct out_transport_fifo_read +{ + uint32_t read; + uint32_t remaining; + int32_t status; +} out_transport_fifo_read_t; +typedef struct in_transport_fifo_write +{ + uint32_t channel; + aligned_uint64_t buf; + uint32_t numberElements; + nirio_fifo_data_type_t dataType; + uint32_t timeout; + int32_t status; +} in_transport_fifo_write_t; +typedef struct out_transport_fifo_write +{ + uint32_t remaining; + int32_t status; +} out_transport_fifo_write_t; +typedef struct in_transport_fifo_wait +{ + uint32_t channel; + aligned_uint64_t elementsRequested; + nirio_fifo_data_type_t dataType; + bool output; + uint32_t timeout; + int32_t status; +} in_transport_fifo_wait_t; +typedef struct out_transport_fifo_wait +{ + aligned_uint64_t elements; + aligned_uint64_t elementsAcquired; + aligned_uint64_t elementsRemaining; + int32_t status; +} out_transport_fifo_wait_t; +typedef struct in_transport_fifo_grant +{ + uint32_t channel; + aligned_uint64_t elements; + int32_t status; +} in_transport_fifo_grant_t; +typedef struct out_transport_fifo_grant +{ + int32_t status; +} out_transport_fifo_grant_t; +typedef struct in_transport_fifoStop_all +{ + int32_t status; +} in_transport_fifo_stop_all_t; +typedef struct out_transport_fifoStop_all +{ + int32_t status; +} out_transport_fifo_stop_all_t; +typedef struct in_transport_peek64 +{ + uint32_t offset; + int32_t status; +} in_transport_peek64_t; +typedef struct out_transport_peek64 +{ + aligned_uint64_t retVal__; + int32_t status; +} out_transport_peek64_t; +typedef struct in_transport_peek32 +{ + uint32_t offset; + int32_t status; +} in_transport_peek32_t; +typedef struct out_transport_peek32 +{ + uint32_t retVal__; + int32_t status; +} out_transport_peek32_t; +typedef struct in_transport_poke64 +{ + uint32_t offset; + aligned_uint64_t value; + int32_t status; +} in_transport_poke64_t; +typedef struct out_transport_poke64 +{ + int32_t status; +} out_transport_poke64_t; +typedef struct in_transport_poke32 +{ + uint32_t offset; + uint32_t value; + int32_t status; +} in_transport_poke32_t; +typedef struct out_transport_poke32 +{ + int32_t status; +} out_transport_poke32_t; +typedef struct in_transport_post_open +{ + int32_t status; +} in_transport_post_open_t; +typedef struct out_transport_post_open +{ + int32_t status; +} out_transport_post_open_t; +typedef struct in_transport_pre_close +{ + int32_t status; +} in_transport_pre_close_t; +typedef struct out_transport_pre_close +{ + int32_t status; +} out_transport_pre_close_t; - nirio_status niriok_proxy_impl_v2::open(const std::string& interface_path) - { - WRITER_LOCK +//------------------------------------------------------- +// niriok_proxy_impl_v2 +//------------------------------------------------------- +niriok_proxy_impl_v2::niriok_proxy_impl_v2() {} - if (interface_path.empty()) return NiRio_Status_ResourceNotFound; +niriok_proxy_impl_v2::~niriok_proxy_impl_v2() +{ + close(); +} - //close if already open. - // use non-locking _close since we already have the lock - _close(); +nirio_status niriok_proxy_impl_v2::open(const std::string& interface_path) +{ + WRITER_LOCK + + if (interface_path.empty()) + return NiRio_Status_ResourceNotFound; + + // close if already open. + // use non-locking _close since we already have the lock + _close(); + + in_transport_post_open_t in = {}; + out_transport_post_open_t out = {}; + + in.status = NiRio_Status_Success; + + nirio_status status = NiRio_Status_Success; + nirio_status_chain( + nirio_driver_iface::rio_open(interface_path, _device_handle), status); + if (nirio_status_not_fatal(status)) { + nirio_status_chain(nirio_driver_iface::rio_ioctl(_device_handle, + IOCTL_TRANSPORT_POST_OPEN, + &in, + sizeof(in), + &out, + sizeof(out)), + status); + if (nirio_status_fatal(status)) + _close(); + } + return status; +} - in_transport_post_open_t in = {}; - out_transport_post_open_t out = {}; +void niriok_proxy_impl_v2::close(void) +{ + WRITER_LOCK - in.status = NiRio_Status_Success; + _close(); +} - nirio_status status = NiRio_Status_Success; - nirio_status_chain(nirio_driver_iface::rio_open( - interface_path, _device_handle), status); - if (nirio_status_not_fatal(status)) - { - nirio_status_chain(nirio_driver_iface::rio_ioctl(_device_handle, - IOCTL_TRANSPORT_POST_OPEN, - &in, sizeof(in), &out, sizeof(out)), status); - if (nirio_status_fatal(status)) _close(); - } - return status; - } +// this protected _close doesn't acquire the lock, so it can be used in methods +// that already have the lock +void niriok_proxy_impl_v2::_close() +{ + if (nirio_driver_iface::rio_isopen(_device_handle)) { + in_transport_pre_close_t in = {}; + out_transport_pre_close_t out = {}; - void niriok_proxy_impl_v2::close(void) - { - WRITER_LOCK + in.status = NiRio_Status_Success; - _close(); + nirio_driver_iface::rio_ioctl(_device_handle, + IOCTL_TRANSPORT_PRE_CLOSE, + &in, + sizeof(in), + &out, + sizeof(out)); + nirio_driver_iface::rio_close(_device_handle); } +} - // this protected _close doesn't acquire the lock, so it can be used in methods - // that already have the lock - void niriok_proxy_impl_v2::_close() - { - if(nirio_driver_iface::rio_isopen(_device_handle)) - { - in_transport_pre_close_t in = {}; - out_transport_pre_close_t out = {}; - - in.status = NiRio_Status_Success; - - nirio_driver_iface::rio_ioctl( - _device_handle, IOCTL_TRANSPORT_PRE_CLOSE, &in, sizeof(in), &out, sizeof(out)); - nirio_driver_iface::rio_close(_device_handle); - } - } +nirio_status niriok_proxy_impl_v2::reset() +{ + READER_LOCK - nirio_status niriok_proxy_impl_v2::reset() - { - READER_LOCK + in_transport_reset_t in = {}; + out_transport_reset_t out = {}; - in_transport_reset_t in = {}; - out_transport_reset_t out = {}; + in.status = NiRio_Status_Success; - in.status = NiRio_Status_Success; + nirio_status ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_RESET, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; - nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, - IOCTL_TRANSPORT_RESET, - &in, sizeof(in), &out, sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; + return out.status; +} - return out.status; +nirio_status niriok_proxy_impl_v2::get_version(nirio_version_t type, + uint32_t& major, + uint32_t& upgrade, + uint32_t& maintenance, + char& phase, + uint32_t& build) +{ + nirio_device_attribute32_t version_attr = + (type == CURRENT) ? RIO_CURRENT_VERSION : RIO_OLDEST_COMPATIBLE_VERSION; + uint32_t raw_version = 0; + nirio_status status = get_attribute(version_attr, raw_version); + + major = (raw_version & VERSION_MAJOR_MASK) >> VERSION_MAJOR_SHIFT; + upgrade = (raw_version & VERSION_UPGRD_MASK) >> VERSION_UPGRD_SHIFT; + maintenance = (raw_version & VERSION_MAINT_MASK) >> VERSION_MAINT_SHIFT; + build = (raw_version & VERSION_BUILD_MASK) >> VERSION_BUILD_SHIFT; + + uint32_t phase_num = (raw_version & VERSION_PHASE_MASK) >> VERSION_PHASE_SHIFT; + switch (phase_num) { + case 0: + phase = 'd'; + break; + case 1: + phase = 'a'; + break; + case 2: + phase = 'b'; + break; + case 3: + phase = 'f'; + break; } - nirio_status niriok_proxy_impl_v2::get_version( - nirio_version_t type, - uint32_t& major, - uint32_t& upgrade, - uint32_t& maintenance, - char& phase, - uint32_t& build) - { - nirio_device_attribute32_t version_attr = (type==CURRENT)?RIO_CURRENT_VERSION:RIO_OLDEST_COMPATIBLE_VERSION; - uint32_t raw_version = 0; - nirio_status status = get_attribute(version_attr, raw_version); - - major = (raw_version & VERSION_MAJOR_MASK) >> VERSION_MAJOR_SHIFT; - upgrade = (raw_version & VERSION_UPGRD_MASK) >> VERSION_UPGRD_SHIFT; - maintenance = (raw_version & VERSION_MAINT_MASK) >> VERSION_MAINT_SHIFT; - build = (raw_version & VERSION_BUILD_MASK) >> VERSION_BUILD_SHIFT; - - uint32_t phase_num = (raw_version & VERSION_PHASE_MASK) >> VERSION_PHASE_SHIFT; - switch (phase_num) { - case 0: phase = 'd'; break; - case 1: phase = 'a'; break; - case 2: phase = 'b'; break; - case 3: phase = 'f'; break; - } + return status; +} - return status; - } +nirio_status niriok_proxy_impl_v2::get_attribute( + const nirio_device_attribute32_t attribute, uint32_t& attrValue) +{ + READER_LOCK - nirio_status niriok_proxy_impl_v2::get_attribute( - const nirio_device_attribute32_t attribute, - uint32_t& attrValue) - { - READER_LOCK + in_transport_get32_t in = {}; + out_transport_get32_t out = {}; - in_transport_get32_t in = {}; - out_transport_get32_t out = {}; + in.attribute = attribute; + in.status = NiRio_Status_Success; - in.attribute = attribute; - in.status = NiRio_Status_Success; + nirio_status ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_GET32, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; - nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, - IOCTL_TRANSPORT_GET32, - &in, sizeof(in), - &out, sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; + attrValue = out.retVal__; - attrValue = out.retVal__; + return out.status; +} - return out.status; - } +nirio_status niriok_proxy_impl_v2::set_attribute( + const nirio_device_attribute32_t attribute, const uint32_t value) +{ + READER_LOCK - nirio_status niriok_proxy_impl_v2::set_attribute( - const nirio_device_attribute32_t attribute, - const uint32_t value) - { - READER_LOCK + in_transport_set32_t in = {}; + out_transport_set32_t out = {}; - in_transport_set32_t in = {}; - out_transport_set32_t out = {}; + in.attribute = attribute; + in.value = value; + in.status = NiRio_Status_Success; - in.attribute = attribute; - in.value = value; - in.status = NiRio_Status_Success; + nirio_status ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_SET32, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; - nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, - IOCTL_TRANSPORT_SET32, - &in, sizeof(in), - &out, sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; + return out.status; +} - return out.status; - } +nirio_status niriok_proxy_impl_v2::peek(uint32_t offset, uint32_t& value) +{ + READER_LOCK - nirio_status niriok_proxy_impl_v2::peek(uint32_t offset, uint32_t& value) - { - READER_LOCK + if (offset % 4 != 0) + return NiRio_Status_MisalignedAccess; - if (offset % 4 != 0) return NiRio_Status_MisalignedAccess; - - in_transport_peek32_t in = {}; - out_transport_peek32_t out = {}; - - in.offset = offset; - in.status = NiRio_Status_Success; + in_transport_peek32_t in = {}; + out_transport_peek32_t out = {}; - nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, - IOCTL_TRANSPORT_PEEK32, - &in, sizeof(in), - &out, sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; + in.offset = offset; + in.status = NiRio_Status_Success; - value = out.retVal__; + nirio_status ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_PEEK32, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; - return out.status; - } + value = out.retVal__; - nirio_status niriok_proxy_impl_v2::peek(uint32_t offset, uint64_t& value) - { - READER_LOCK + return out.status; +} - if (offset % 8 != 0) return NiRio_Status_MisalignedAccess; - in_transport_peek64_t in = {}; - out_transport_peek64_t out = {}; +nirio_status niriok_proxy_impl_v2::peek(uint32_t offset, uint64_t& value) +{ + READER_LOCK - in.offset = offset; - in.status = NiRio_Status_Success; + if (offset % 8 != 0) + return NiRio_Status_MisalignedAccess; + in_transport_peek64_t in = {}; + out_transport_peek64_t out = {}; - nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, - IOCTL_TRANSPORT_PEEK64, - &in, sizeof(in), - &out, sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; + in.offset = offset; + in.status = NiRio_Status_Success; - value = out.retVal__; + nirio_status ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_PEEK64, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; - return out.status; - } + value = out.retVal__; - nirio_status niriok_proxy_impl_v2::poke(uint32_t offset, const uint32_t& value) - { - READER_LOCK + return out.status; +} - if (offset % 4 != 0) return NiRio_Status_MisalignedAccess; +nirio_status niriok_proxy_impl_v2::poke(uint32_t offset, const uint32_t& value) +{ + READER_LOCK - in_transport_poke32_t in = {}; - out_transport_poke32_t out = {}; + if (offset % 4 != 0) + return NiRio_Status_MisalignedAccess; - in.offset = offset; - in.value = value; - in.status = NiRio_Status_Success; + in_transport_poke32_t in = {}; + out_transport_poke32_t out = {}; - nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, - IOCTL_TRANSPORT_POKE32, - &in, sizeof(in), - &out, sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; + in.offset = offset; + in.value = value; + in.status = NiRio_Status_Success; - return out.status; - } + nirio_status ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_POKE32, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; - nirio_status niriok_proxy_impl_v2::poke(uint32_t offset, const uint64_t& value) - { - READER_LOCK + return out.status; +} - if (offset % 8 != 0) return NiRio_Status_MisalignedAccess; +nirio_status niriok_proxy_impl_v2::poke(uint32_t offset, const uint64_t& value) +{ + READER_LOCK - in_transport_poke64_t in = {}; - out_transport_poke64_t out = {}; + if (offset % 8 != 0) + return NiRio_Status_MisalignedAccess; - in.offset = offset; - in.value = value; - in.status = NiRio_Status_Success; + in_transport_poke64_t in = {}; + out_transport_poke64_t out = {}; - nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, - IOCTL_TRANSPORT_POKE64, - &in, sizeof(in), - &out, sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; + in.offset = offset; + in.value = value; + in.status = NiRio_Status_Success; - return out.status; - } + nirio_status ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_POKE64, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; - nirio_status niriok_proxy_impl_v2::map_fifo_memory( - uint32_t fifo_instance, - size_t size, - nirio_driver_iface::rio_mmap_t& map) - { - READER_LOCK + return out.status; +} - return nirio_driver_iface::rio_mmap(_device_handle, - GET_FIFO_MEMORY_TYPE(fifo_instance), - size, true, map); - } +nirio_status niriok_proxy_impl_v2::map_fifo_memory( + uint32_t fifo_instance, size_t size, nirio_driver_iface::rio_mmap_t& map) +{ + READER_LOCK - nirio_status niriok_proxy_impl_v2::unmap_fifo_memory( - nirio_driver_iface::rio_mmap_t& map) - { - READER_LOCK + return nirio_driver_iface::rio_mmap( + _device_handle, GET_FIFO_MEMORY_TYPE(fifo_instance), size, true, map); +} - return nirio_driver_iface::rio_munmap(map); - } +nirio_status niriok_proxy_impl_v2::unmap_fifo_memory(nirio_driver_iface::rio_mmap_t& map) +{ + READER_LOCK - nirio_status niriok_proxy_impl_v2::stop_all_fifos() - { - READER_LOCK + return nirio_driver_iface::rio_munmap(map); +} - nirio_status ioctl_status = NiRio_Status_Success; - in_transport_fifo_stop_all_t in = {}; - out_transport_fifo_stop_all_t out = {}; +nirio_status niriok_proxy_impl_v2::stop_all_fifos() +{ + READER_LOCK - in.status = NiRio_Status_Success; + nirio_status ioctl_status = NiRio_Status_Success; + in_transport_fifo_stop_all_t in = {}; + out_transport_fifo_stop_all_t out = {}; - ioctl_status = - nirio_driver_iface::rio_ioctl( - _device_handle, - IOCTL_TRANSPORT_FIFO_STOP_ALL, - &in, - sizeof(in), - &out, - sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; - - return out.status; - } + in.status = NiRio_Status_Success; - nirio_status niriok_proxy_impl_v2::add_fifo_resource(const nirio_fifo_info_t& fifo_info) - { - READER_LOCK + ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, + IOCTL_TRANSPORT_FIFO_STOP_ALL, + &in, + sizeof(in), + &out, + sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; + + return out.status; +} + +nirio_status niriok_proxy_impl_v2::add_fifo_resource(const nirio_fifo_info_t& fifo_info) +{ + READER_LOCK - nirio_status status = NiRio_Status_Success; - nirio_status ioctl_status = NiRio_Status_Success; + nirio_status status = NiRio_Status_Success; + nirio_status ioctl_status = NiRio_Status_Success; - switch(fifo_info.direction) - { - case INPUT_FIFO: - { - in_transport_add_input_fifo_resource_t in = {}; + switch (fifo_info.direction) { + case INPUT_FIFO: { + in_transport_add_input_fifo_resource_t in = {}; out_transport_add_input_fifo_resource_t out = {}; - in.channel = fifo_info.channel; - in.baseAddress = fifo_info.base_addr; - in.depthInSamples = fifo_info.depth; - in.dataType.scalarType = fifo_info.scalar_type; - in.dataType.bitWidth = fifo_info.bitWidth; - in.dataType.integerWordLength = fifo_info.integerWordLength; - in.version = fifo_info.version; - in.status = NiRio_Status_Success; + in.channel = fifo_info.channel; + in.baseAddress = fifo_info.base_addr; + in.depthInSamples = fifo_info.depth; + in.dataType.scalarType = fifo_info.scalar_type; + in.dataType.bitWidth = fifo_info.bitWidth; + in.dataType.integerWordLength = fifo_info.integerWordLength; + in.version = fifo_info.version; + in.status = NiRio_Status_Success; ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, - IOCTL_TRANSPORT_ADD_INPUT_FIFO_RESOURCE, - &in, sizeof(in), - &out, sizeof(out)); + IOCTL_TRANSPORT_ADD_INPUT_FIFO_RESOURCE, + &in, + sizeof(in), + &out, + sizeof(out)); status = nirio_status_fatal(ioctl_status) ? ioctl_status : out.status; break; - } - case OUTPUT_FIFO: - { - in_transport_add_output_fifo_resource_t in = {}; + } + case OUTPUT_FIFO: { + in_transport_add_output_fifo_resource_t in = {}; out_transport_add_output_fifo_resource_t out = {}; - in.channel = fifo_info.channel; - in.baseAddress = fifo_info.base_addr; - in.depthInSamples = fifo_info.depth; - in.dataType.scalarType = fifo_info.scalar_type; - in.dataType.bitWidth = fifo_info.bitWidth; + in.channel = fifo_info.channel; + in.baseAddress = fifo_info.base_addr; + in.depthInSamples = fifo_info.depth; + in.dataType.scalarType = fifo_info.scalar_type; + in.dataType.bitWidth = fifo_info.bitWidth; in.dataType.integerWordLength = fifo_info.integerWordLength; - in.version = fifo_info.version; - in.status = NiRio_Status_Success; - + in.version = fifo_info.version; + in.status = NiRio_Status_Success; + ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, - IOCTL_TRANSPORT_ADD_OUTPUT_FIFO_RESOURCE, - &in, sizeof(in), - &out, sizeof(out)); + IOCTL_TRANSPORT_ADD_OUTPUT_FIFO_RESOURCE, + &in, + sizeof(in), + &out, + sizeof(out)); status = nirio_status_fatal(ioctl_status) ? ioctl_status : out.status; break; - } - default: + } + default: status = NiRio_Status_SoftwareFault; - } - - return status; } - nirio_status niriok_proxy_impl_v2::set_device_config() - { - READER_LOCK - - nirio_status ioctl_status = NiRio_Status_Success; - - in_transport_set_device_config_t in = {}; - out_transport_set_device_config_t out = {}; - - in.attribute = 0; //this is unused in the kernel - in.status = NiRio_Status_Success; - - ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, - IOCTL_TRANSPORT_SET_DEVICE_CONFIG, - &in, sizeof(in), - &out, sizeof(out)); + return status; +} - return nirio_status_fatal(ioctl_status) ? ioctl_status : out.status; - } +nirio_status niriok_proxy_impl_v2::set_device_config() +{ + READER_LOCK - nirio_status niriok_proxy_impl_v2::start_fifo( - uint32_t channel) - { - READER_LOCK + nirio_status ioctl_status = NiRio_Status_Success; - nirio_status ioctl_status = NiRio_Status_Success; - in_transport_fifo_start_t in = {}; - out_transport_fifo_start_t out = {}; + in_transport_set_device_config_t in = {}; + out_transport_set_device_config_t out = {}; - in.channel = channel; - in.status = NiRio_Status_Success; + in.attribute = 0; // this is unused in the kernel + in.status = NiRio_Status_Success; - ioctl_status = - nirio_driver_iface::rio_ioctl( - _device_handle, - IOCTL_TRANSPORT_FIFO_START, - &in, - sizeof(in), - &out, - sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; - - return out.status; - } + ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle, + IOCTL_TRANSPORT_SET_DEVICE_CONFIG, + &in, + sizeof(in), + &out, + sizeof(out)); - nirio_status niriok_proxy_impl_v2::stop_fifo( - uint32_t channel) - { - READER_LOCK + return nirio_status_fatal(ioctl_status) ? ioctl_status : out.status; +} - nirio_status ioctl_status = NiRio_Status_Success; - in_transport_fifo_stop_t in = {}; - out_transport_fifo_stop_t out = {}; +nirio_status niriok_proxy_impl_v2::start_fifo(uint32_t channel) +{ + READER_LOCK - in.channel = channel; - in.status = NiRio_Status_Success; + nirio_status ioctl_status = NiRio_Status_Success; + in_transport_fifo_start_t in = {}; + out_transport_fifo_start_t out = {}; - ioctl_status = - nirio_driver_iface::rio_ioctl( - _device_handle, - IOCTL_TRANSPORT_FIFO_STOP, - &in, - sizeof(in), - &out, - sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; - - return out.status; - } + in.channel = channel; + in.status = NiRio_Status_Success; - nirio_status niriok_proxy_impl_v2::configure_fifo( - uint32_t channel, - uint32_t requested_depth, - uint8_t /*requires_actuals*/, //Unused - uint32_t& actual_depth, - uint32_t& actual_size) - { - READER_LOCK - - nirio_status ioctl_status = NiRio_Status_Success; - in_transport_fifo_config_t in = {}; - out_transport_fifo_config_t out = {}; - - in.channel = channel; - in.requestedDepth = requested_depth; - in.status = NiRio_Status_Success; + ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_FIFO_START, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; - ioctl_status = - nirio_driver_iface::rio_ioctl( - _device_handle, - IOCTL_TRANSPORT_FIFO_CONFIG, - &in, - sizeof(in), - &out, - sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; - - UHD_ASSERT_THROW(out.actualDepth <= std::numeric_limits<uint32_t>::max()); - actual_depth = static_cast<uint32_t>(out.actualDepth); - UHD_ASSERT_THROW(out.actualSize <= std::numeric_limits<uint32_t>::max()); - actual_size = static_cast<uint32_t>(out.actualSize); - return out.status; - } + return out.status; +} - nirio_status niriok_proxy_impl_v2::wait_on_fifo( - uint32_t channel, - uint32_t elements_requested, - uint32_t scalar_type, - uint32_t bit_width, - uint32_t timeout, - uint8_t output, - void*& data_pointer, - uint32_t& elements_acquired, - uint32_t& elements_remaining) - { - READER_LOCK - - nirio_status ioctl_status = NiRio_Status_Success; - in_transport_fifo_wait_t in = {}; - out_transport_fifo_wait_t out = {}; - - in.channel = channel; - in.elementsRequested = elements_requested; - in.dataType.scalarType = map_int_to_scalar_type(scalar_type); - in.dataType.bitWidth = bit_width; - in.dataType.integerWordLength = bit_width; // same as bit_width for all types except fixed point, which is not supported - in.output = (output != 0); - in.timeout = timeout; - in.status = NiRio_Status_Success; +nirio_status niriok_proxy_impl_v2::stop_fifo(uint32_t channel) +{ + READER_LOCK - ioctl_status = - nirio_driver_iface::rio_ioctl( - _device_handle, - IOCTL_TRANSPORT_FIFO_WAIT, - &in, - sizeof(in), - &out, - sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; - - data_pointer = reinterpret_cast<void*>(out.elements); - UHD_ASSERT_THROW(out.elementsAcquired <= std::numeric_limits<uint32_t>::max()); - elements_acquired = static_cast<uint32_t>(out.elementsAcquired); - UHD_ASSERT_THROW(out.elementsRemaining <= std::numeric_limits<uint32_t>::max()); - elements_remaining = static_cast<uint32_t>(out.elementsRemaining); - return out.status; - } + nirio_status ioctl_status = NiRio_Status_Success; + in_transport_fifo_stop_t in = {}; + out_transport_fifo_stop_t out = {}; - nirio_status niriok_proxy_impl_v2::grant_fifo( - uint32_t channel, - uint32_t elements_to_grant) - { - READER_LOCK + in.channel = channel; + in.status = NiRio_Status_Success; - nirio_status ioctl_status = NiRio_Status_Success; - in_transport_fifo_grant_t in = {}; - out_transport_fifo_grant_t out = {}; + ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_FIFO_STOP, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; - in.channel = channel; - in.elements = elements_to_grant; - in.status = NiRio_Status_Success; + return out.status; +} - ioctl_status = - nirio_driver_iface::rio_ioctl( - _device_handle, - IOCTL_TRANSPORT_FIFO_GRANT, - &in, - sizeof(in), - &out, - sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; - - return out.status; - } +nirio_status niriok_proxy_impl_v2::configure_fifo(uint32_t channel, + uint32_t requested_depth, + uint8_t /*requires_actuals*/, // Unused + uint32_t& actual_depth, + uint32_t& actual_size) +{ + READER_LOCK + + nirio_status ioctl_status = NiRio_Status_Success; + in_transport_fifo_config_t in = {}; + out_transport_fifo_config_t out = {}; + + in.channel = channel; + in.requestedDepth = requested_depth; + in.status = NiRio_Status_Success; + + ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_FIFO_CONFIG, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; + + UHD_ASSERT_THROW(out.actualDepth <= std::numeric_limits<uint32_t>::max()); + actual_depth = static_cast<uint32_t>(out.actualDepth); + UHD_ASSERT_THROW(out.actualSize <= std::numeric_limits<uint32_t>::max()); + actual_size = static_cast<uint32_t>(out.actualSize); + return out.status; +} + +nirio_status niriok_proxy_impl_v2::wait_on_fifo(uint32_t channel, + uint32_t elements_requested, + uint32_t scalar_type, + uint32_t bit_width, + uint32_t timeout, + uint8_t output, + void*& data_pointer, + uint32_t& elements_acquired, + uint32_t& elements_remaining) +{ + READER_LOCK + + nirio_status ioctl_status = NiRio_Status_Success; + in_transport_fifo_wait_t in = {}; + out_transport_fifo_wait_t out = {}; + + in.channel = channel; + in.elementsRequested = elements_requested; + in.dataType.scalarType = map_int_to_scalar_type(scalar_type); + in.dataType.bitWidth = bit_width; + in.dataType.integerWordLength = bit_width; // same as bit_width for all types except + // fixed point, which is not supported + in.output = (output != 0); + in.timeout = timeout; + in.status = NiRio_Status_Success; + + ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_FIFO_WAIT, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; + + data_pointer = reinterpret_cast<void*>(out.elements); + UHD_ASSERT_THROW(out.elementsAcquired <= std::numeric_limits<uint32_t>::max()); + elements_acquired = static_cast<uint32_t>(out.elementsAcquired); + UHD_ASSERT_THROW(out.elementsRemaining <= std::numeric_limits<uint32_t>::max()); + elements_remaining = static_cast<uint32_t>(out.elementsRemaining); + return out.status; +} + +nirio_status niriok_proxy_impl_v2::grant_fifo( + uint32_t channel, uint32_t elements_to_grant) +{ + READER_LOCK + + nirio_status ioctl_status = NiRio_Status_Success; + in_transport_fifo_grant_t in = {}; + out_transport_fifo_grant_t out = {}; + + in.channel = channel; + in.elements = elements_to_grant; + in.status = NiRio_Status_Success; + + ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_FIFO_GRANT, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; + + return out.status; +} + +nirio_status niriok_proxy_impl_v2::read_fifo(uint32_t channel, + uint32_t elements_to_read, + void* buffer, + uint32_t /*buffer_datatype_width*/, // Unused + uint32_t scalar_type, + uint32_t bit_width, + uint32_t timeout, + uint32_t& number_read, + uint32_t& number_remaining) +{ + READER_LOCK + + nirio_status ioctl_status = NiRio_Status_Success; + in_transport_fifo_read_t in = {}; + out_transport_fifo_read_t out = {}; + + in.channel = channel; + in.buf = reinterpret_cast<aligned_uint64_t>(buffer); + in.numberElements = elements_to_read; + in.dataType.scalarType = map_int_to_scalar_type(scalar_type); + in.dataType.bitWidth = bit_width; + in.dataType.integerWordLength = bit_width; // same as bit_width for all types except + // fixed point, which is not supported + in.timeout = timeout; + in.status = NiRio_Status_Success; + + ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_FIFO_READ, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; + + number_read = out.read; + number_remaining = out.remaining; + return out.status; +} + +nirio_status niriok_proxy_impl_v2::write_fifo(uint32_t channel, + uint32_t elements_to_write, + void* buffer, + uint32_t /*buffer_datatype_width*/, // Unused + uint32_t scalar_type, + uint32_t bit_width, + uint32_t timeout, + uint32_t& number_remaining) +{ + READER_LOCK - nirio_status niriok_proxy_impl_v2::read_fifo( - uint32_t channel, - uint32_t elements_to_read, - void* buffer, - uint32_t /*buffer_datatype_width*/, //Unused - uint32_t scalar_type, - uint32_t bit_width, - uint32_t timeout, - uint32_t& number_read, - uint32_t& number_remaining) - { - READER_LOCK - - nirio_status ioctl_status = NiRio_Status_Success; - in_transport_fifo_read_t in = {}; - out_transport_fifo_read_t out = {}; - - in.channel = channel; - in.buf = reinterpret_cast<aligned_uint64_t>(buffer); - in.numberElements = elements_to_read; - in.dataType.scalarType = map_int_to_scalar_type(scalar_type); - in.dataType.bitWidth = bit_width; - in.dataType.integerWordLength = bit_width; // same as bit_width for all types except fixed point, which is not supported - in.timeout = timeout; - in.status = NiRio_Status_Success; + nirio_status ioctl_status = NiRio_Status_Success; + in_transport_fifo_write_t in = {}; + out_transport_fifo_write_t out = {}; - ioctl_status = - nirio_driver_iface::rio_ioctl( - _device_handle, - IOCTL_TRANSPORT_FIFO_READ, - &in, - sizeof(in), - &out, - sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; - - number_read = out.read; - number_remaining = out.remaining; - return out.status; - } + in.channel = channel; + in.buf = reinterpret_cast<aligned_uint64_t>(buffer); + in.numberElements = elements_to_write; + in.dataType.scalarType = map_int_to_scalar_type(scalar_type); + in.dataType.bitWidth = bit_width; + in.dataType.integerWordLength = bit_width; // same as bit_width for all types except + // fixed point, which is not supported + in.timeout = timeout; + in.status = NiRio_Status_Success; - nirio_status niriok_proxy_impl_v2::write_fifo( - uint32_t channel, - uint32_t elements_to_write, - void* buffer, - uint32_t /*buffer_datatype_width*/, //Unused - uint32_t scalar_type, - uint32_t bit_width, - uint32_t timeout, - uint32_t& number_remaining) - { - READER_LOCK - - nirio_status ioctl_status = NiRio_Status_Success; - in_transport_fifo_write_t in = {}; - out_transport_fifo_write_t out = {}; - - in.channel = channel; - in.buf = reinterpret_cast<aligned_uint64_t>(buffer); - in.numberElements = elements_to_write; - in.dataType.scalarType = map_int_to_scalar_type(scalar_type); - in.dataType.bitWidth = bit_width; - in.dataType.integerWordLength = bit_width; // same as bit_width for all types except fixed point, which is not supported - in.timeout = timeout; - in.status = NiRio_Status_Success; + ioctl_status = nirio_driver_iface::rio_ioctl( + _device_handle, IOCTL_TRANSPORT_FIFO_WRITE, &in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(ioctl_status)) + return ioctl_status; - ioctl_status = - nirio_driver_iface::rio_ioctl( - _device_handle, - IOCTL_TRANSPORT_FIFO_WRITE, - &in, - sizeof(in), - &out, - sizeof(out)); - if (nirio_status_fatal(ioctl_status)) return ioctl_status; - - number_remaining = out.remaining; - return out.status; - } + number_remaining = out.remaining; + return out.status; +} -}} +}} // namespace uhd::niusrprio #if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 5) - #pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif diff --git a/host/lib/transport/nirio/rpc/rpc_client.cpp b/host/lib/transport/nirio/rpc/rpc_client.cpp index e9bf4bbb4..efc802e89 100644 --- a/host/lib/transport/nirio/rpc/rpc_client.cpp +++ b/host/lib/transport/nirio/rpc/rpc_client.cpp @@ -12,35 +12,36 @@ #include <boost/version.hpp> -#define CHAIN_BLOCKING_XFER(func, exp, status) \ - if (status) { \ - status = (static_cast<size_t>((func)) == exp); \ - } else { \ +#define CHAIN_BLOCKING_XFER(func, exp, status) \ + if (status) { \ + status = (static_cast<size_t>((func)) == exp); \ + } else { \ UHD_LOGGER_DEBUG("NIRIO") << "rpc_client operation skipped: " #func "\n"; \ - } \ + } namespace uhd { namespace usrprio_rpc { using boost::asio::ip::tcp; -rpc_client::rpc_client ( - const std::string& server, +rpc_client::rpc_client(const std::string& server, const std::string& port, uint32_t process_id, - uint32_t host_id -) : _socket(_io_service) + uint32_t host_id) + : _socket(_io_service) { - //Fill in handshake info - _hshake_args_client.version = CURRENT_VERSION; + // Fill in handshake info + _hshake_args_client.version = CURRENT_VERSION; _hshake_args_client.oldest_comp_version = OLDEST_COMPATIBLE_VERSION; - _hshake_args_client.client_id = build_client_id(host_id, process_id); - _hshake_args_client.boost_archive_version = boost_serialization_archive_utils::get_version(); + _hshake_args_client.client_id = build_client_id(host_id, process_id); + _hshake_args_client.boost_archive_version = + boost_serialization_archive_utils::get_version(); try { - //Synchronous resolve + connect + // Synchronous resolve + connect tcp::resolver resolver(_io_service); - //Create flags object with all special flags disabled. Especially the following: - //- address_configured: Only return addresses if a non-loopback address is configured for the system. + // Create flags object with all special flags disabled. Especially the following: + //- address_configured: Only return addresses if a non-loopback address is + // configured for the system. //- numeric_host: No name resolution should be attempted for host //- numeric_service: No name resolution should be attempted for service tcp::resolver::query::flags query_flags(tcp::resolver::query::passive); @@ -48,56 +49,64 @@ rpc_client::rpc_client ( tcp::resolver::iterator iterator = resolver.resolve(query); boost::asio::connect(_socket, iterator); - UHD_LOGGER_TRACE("NIRIO") << "rpc_client connected to server." ; + UHD_LOGGER_TRACE("NIRIO") << "rpc_client connected to server."; try { - //Perform handshake + // Perform handshake bool status = true; - CHAIN_BLOCKING_XFER( - boost::asio::write(_socket, boost::asio::buffer(&_hshake_args_client, sizeof(_hshake_args_client))), - sizeof(_hshake_args_client), status); - CHAIN_BLOCKING_XFER( - boost::asio::read(_socket, boost::asio::buffer(&_hshake_args_server, sizeof(_hshake_args_server))), - sizeof(_hshake_args_server), status); + CHAIN_BLOCKING_XFER(boost::asio::write(_socket, + boost::asio::buffer(&_hshake_args_client, + sizeof(_hshake_args_client))), + sizeof(_hshake_args_client), + status); + CHAIN_BLOCKING_XFER(boost::asio::read(_socket, + boost::asio::buffer(&_hshake_args_server, + sizeof(_hshake_args_server))), + sizeof(_hshake_args_server), + status); _request.header.client_id = _hshake_args_server.client_id; - if (_hshake_args_server.version >= _hshake_args_client.oldest_comp_version && - _hshake_args_client.version >= _hshake_args_server.oldest_comp_version && - status) - { - UHD_LOGGER_TRACE("NIRIO") << "rpc_client bound to server." ; + if (_hshake_args_server.version >= _hshake_args_client.oldest_comp_version + && _hshake_args_client.version >= _hshake_args_server.oldest_comp_version + && status) { + UHD_LOGGER_TRACE("NIRIO") << "rpc_client bound to server."; _wait_for_next_response_header(); - //Spawn a thread for the io_service callback handler. This thread will run until rpc_client is destroyed. - _io_service_thread.reset(new boost::thread(boost::bind(&boost::asio::io_service::run, &_io_service))); + // Spawn a thread for the io_service callback handler. This thread will + // run until rpc_client is destroyed. + _io_service_thread.reset(new boost::thread( + boost::bind(&boost::asio::io_service::run, &_io_service))); } else { - UHD_LOGGER_DEBUG("NIRIO") << "rpc_client handshake failed." ; - _exec_err.assign(boost::asio::error::connection_refused, boost::asio::error::get_system_category()); + UHD_LOGGER_DEBUG("NIRIO") << "rpc_client handshake failed."; + _exec_err.assign(boost::asio::error::connection_refused, + boost::asio::error::get_system_category()); } - UHD_LOGGER_TRACE("NIRIO") << boost::format("rpc_client archive = %d, rpc_server archive = %d\n.") % - _hshake_args_client.boost_archive_version % - _hshake_args_server.boost_archive_version; + UHD_LOGGER_TRACE("NIRIO") + << boost::format("rpc_client archive = %d, rpc_server archive = %d\n.") + % _hshake_args_client.boost_archive_version + % _hshake_args_server.boost_archive_version; } catch (boost::exception&) { - UHD_LOGGER_DEBUG("NIRIO") << "rpc_client handshake aborted." ; - _exec_err.assign(boost::asio::error::connection_refused, boost::asio::error::get_system_category()); + UHD_LOGGER_DEBUG("NIRIO") << "rpc_client handshake aborted."; + _exec_err.assign(boost::asio::error::connection_refused, + boost::asio::error::get_system_category()); } } catch (boost::exception&) { - UHD_LOGGER_TRACE("NIRIO") << "rpc_client connection request cancelled/aborted." ; - _exec_err.assign(boost::asio::error::connection_aborted, boost::asio::error::get_system_category()); + UHD_LOGGER_TRACE("NIRIO") << "rpc_client connection request cancelled/aborted."; + _exec_err.assign(boost::asio::error::connection_aborted, + boost::asio::error::get_system_category()); } } -rpc_client::~rpc_client () { +rpc_client::~rpc_client() +{ _stop_io_service(); } -const boost::system::error_code& rpc_client::call( - func_id_t func_id, +const boost::system::error_code& rpc_client::call(func_id_t func_id, const func_args_writer_t& in_args, - func_args_reader_t &out_args, - boost::posix_time::milliseconds timeout -) + func_args_reader_t& out_args, + boost::posix_time::milliseconds timeout) { boost::mutex::scoped_lock lock(_mutex); @@ -108,61 +117,70 @@ const boost::system::error_code& rpc_client::call( _exec_err.clear(); - //Send function call header and args + // Send function call header and args bool status = true; try { CHAIN_BLOCKING_XFER( - boost::asio::write(_socket, boost::asio::buffer(&_request.header, sizeof(_request.header))), - sizeof(_request.header), status); - if (not _request.data.empty()) - { - CHAIN_BLOCKING_XFER( - boost::asio::write(_socket, boost::asio::buffer(&(*_request.data.begin()), _request.data.size())), - _request.data.size(), status); + boost::asio::write(_socket, + boost::asio::buffer(&_request.header, sizeof(_request.header))), + sizeof(_request.header), + status); + if (not _request.data.empty()) { + CHAIN_BLOCKING_XFER(boost::asio::write(_socket, + boost::asio::buffer(&(*_request.data.begin()), + _request.data.size())), + _request.data.size(), + status); } } catch (boost::exception&) { status = false; } - //Wait for response using condition variable + // Wait for response using condition variable if (status) { if (!_exec_gate.timed_wait(lock, timeout)) { - UHD_LOGGER_DEBUG("NIRIO") << "rpc_client function timed out." ; - _exec_err.assign(boost::asio::error::timed_out, boost::asio::error::get_system_category()); + UHD_LOGGER_DEBUG("NIRIO") << "rpc_client function timed out."; + _exec_err.assign(boost::asio::error::timed_out, + boost::asio::error::get_system_category()); } } else { - UHD_LOGGER_DEBUG("NIRIO") << "rpc_client connection dropped." ; - _exec_err.assign(boost::asio::error::connection_aborted, boost::asio::error::get_system_category()); + UHD_LOGGER_DEBUG("NIRIO") << "rpc_client connection dropped."; + _exec_err.assign(boost::asio::error::connection_aborted, + boost::asio::error::get_system_category()); _stop_io_service(); } - //Verify that we are talking to the correct endpoint + // Verify that we are talking to the correct endpoint if ((_request.header.client_id != _response.header.client_id) && !_exec_err) { - UHD_LOGGER_DEBUG("NIRIO") << "rpc_client confused about who its talking to." ; - _exec_err.assign(boost::asio::error::operation_aborted, boost::asio::error::get_system_category()); + UHD_LOGGER_DEBUG("NIRIO") << "rpc_client confused about who its talking to."; + _exec_err.assign(boost::asio::error::operation_aborted, + boost::asio::error::get_system_category()); } - if (!_exec_err) out_args.load(_response.data); + if (!_exec_err) + out_args.load(_response.data); } return _exec_err; } -void rpc_client::_handle_response_hdr(const boost::system::error_code& err, size_t transferred, size_t expected) +void rpc_client::_handle_response_hdr( + const boost::system::error_code& err, size_t transferred, size_t expected) { boost::mutex::scoped_lock lock(_mutex); _exec_err = err; if (!_exec_err && (transferred == expected)) { - //Response header received. Verify that it is expected + // Response header received. Verify that it is expected if (func_args_header_t::match_function(_request.header, _response.header)) { - if (_response.header.func_args_size) - { + if (_response.header.func_args_size) { _response.data.resize(_response.header.func_args_size); - //Wait for response data + // Wait for response data boost::asio::async_read(_socket, - boost::asio::buffer(&(*_response.data.begin()), _response.data.size()), - boost::bind(&rpc_client::_handle_response_data, this, + boost::asio::buffer( + &(*_response.data.begin()), _response.data.size()), + boost::bind(&rpc_client::_handle_response_data, + this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, _response.data.size())); @@ -170,23 +188,27 @@ void rpc_client::_handle_response_hdr(const boost::system::error_code& err, size _handle_response_data(err, 0, 0); } } else { - //Unexpected response. Ignore it. - UHD_LOGGER_DEBUG("NIRIO") << "rpc_client received garbage responses." ; - _exec_err.assign(boost::asio::error::operation_aborted, boost::asio::error::get_system_category()); + // Unexpected response. Ignore it. + UHD_LOGGER_DEBUG("NIRIO") << "rpc_client received garbage responses."; + _exec_err.assign(boost::asio::error::operation_aborted, + boost::asio::error::get_system_category()); _wait_for_next_response_header(); } } - if (_exec_err) _exec_gate.notify_all(); + if (_exec_err) + _exec_gate.notify_all(); } -void rpc_client::_handle_response_data(const boost::system::error_code& err, size_t transferred, size_t expected) +void rpc_client::_handle_response_data( + const boost::system::error_code& err, size_t transferred, size_t expected) { boost::mutex::scoped_lock lock(_mutex); _exec_err = err; if (transferred != expected) { - _exec_err.assign(boost::asio::error::operation_aborted, boost::asio::error::get_system_category()); + _exec_err.assign(boost::asio::error::operation_aborted, + boost::asio::error::get_system_category()); } _exec_gate.notify_all(); @@ -194,15 +216,16 @@ void rpc_client::_handle_response_data(const boost::system::error_code& err, siz _wait_for_next_response_header(); } -void rpc_client::_wait_for_next_response_header() { +void rpc_client::_wait_for_next_response_header() +{ //_mutex must be locked when this call is made - boost::asio::async_read( - _socket, + boost::asio::async_read(_socket, boost::asio::buffer(&_response.header, sizeof(_response.header)), - boost::bind(&rpc_client::_handle_response_hdr, this, + boost::bind(&rpc_client::_handle_response_hdr, + this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, sizeof(_response.header))); } -}} +}} // namespace uhd::usrprio_rpc diff --git a/host/lib/transport/nirio/rpc/usrprio_rpc_client.cpp b/host/lib/transport/nirio/rpc/usrprio_rpc_client.cpp index af79cfb7c..718ff7c05 100644 --- a/host/lib/transport/nirio/rpc/usrprio_rpc_client.cpp +++ b/host/lib/transport/nirio/rpc/usrprio_rpc_client.cpp @@ -9,24 +9,21 @@ #include <uhd/utils/platform.hpp> namespace { - constexpr int64_t DEFAULT_TIMEOUT_IN_MS = 5000; +constexpr int64_t DEFAULT_TIMEOUT_IN_MS = 5000; } namespace uhd { namespace usrprio_rpc { -usrprio_rpc_client::usrprio_rpc_client( - std::string server, - std::string port -) : _rpc_client(server, port, uhd::get_process_id(), uhd::get_host_id()), - _timeout(boost::posix_time::milliseconds(long(DEFAULT_TIMEOUT_IN_MS))) +usrprio_rpc_client::usrprio_rpc_client(std::string server, std::string port) + : _rpc_client(server, port, uhd::get_process_id(), uhd::get_host_id()) + , _timeout(boost::posix_time::milliseconds(long(DEFAULT_TIMEOUT_IN_MS))) { - _ctor_status = _rpc_client.status() ? NiRio_Status_RpcConnectionError : NiRio_Status_Success; + _ctor_status = _rpc_client.status() ? NiRio_Status_RpcConnectionError + : NiRio_Status_Success; } -usrprio_rpc_client::~usrprio_rpc_client() -{ -} +usrprio_rpc_client::~usrprio_rpc_client() {} nirio_status usrprio_rpc_client::niusrprio_enumerate(NIUSRPRIO_ENUMERATE_ARGS) /* @@ -37,7 +34,7 @@ nirio_status usrprio_rpc_client::niusrprio_enumerate(NIUSRPRIO_ENUMERATE_ARGS) usrprio_rpc::func_args_writer_t in_args; usrprio_rpc::func_args_reader_t out_args; nirio_status status = NiRio_Status_Success; - uint32_t vtr_size = 0; + uint32_t vtr_size = 0; status = _boost_error_to_nirio_status( _rpc_client.call(NIUSRPRIO_ENUMERATE, in_args, out_args, _timeout)); @@ -75,10 +72,13 @@ nirio_status usrprio_rpc_client::niusrprio_open_session(NIUSRPRIO_OPEN_SESSION_A in_args << signature; in_args << download_fpga; - //Open needs a longer timeout because the FPGA download can take upto 6 secs and the NiFpga libload can take 4. + // Open needs a longer timeout because the FPGA download can take upto 6 secs and the + // NiFpga libload can take 4. static const uint32_t OPEN_TIMEOUT = 15000; - status = _boost_error_to_nirio_status( - _rpc_client.call(NIUSRPRIO_OPEN_SESSION, in_args, out_args, boost::posix_time::milliseconds(OPEN_TIMEOUT))); + status = _boost_error_to_nirio_status(_rpc_client.call(NIUSRPRIO_OPEN_SESSION, + in_args, + out_args, + boost::posix_time::milliseconds(OPEN_TIMEOUT))); if (nirio_status_not_fatal(status)) { out_args >> status; @@ -131,7 +131,8 @@ nirio_status usrprio_rpc_client::niusrprio_reset_device(NIUSRPRIO_RESET_SESSION_ return status; } -nirio_status usrprio_rpc_client::niusrprio_get_interface_path(NIUSRPRIO_GET_INTERFACE_PATH_ARGS) +nirio_status usrprio_rpc_client::niusrprio_get_interface_path( + NIUSRPRIO_GET_INTERFACE_PATH_ARGS) /* #define NIUSRPRIO_GET_INTERFACE_PATH_ARGS \ const std::string& resource, \ @@ -155,7 +156,8 @@ nirio_status usrprio_rpc_client::niusrprio_get_interface_path(NIUSRPRIO_GET_INTE return status; } -nirio_status usrprio_rpc_client::niusrprio_download_fpga_to_flash(NIUSRPRIO_DOWNLOAD_FPGA_TO_FLASH_ARGS) +nirio_status usrprio_rpc_client::niusrprio_download_fpga_to_flash( + NIUSRPRIO_DOWNLOAD_FPGA_TO_FLASH_ARGS) /* #define NIUSRPRIO_DOWNLOAD_FPGA_TO_FLASH_ARGS \ const uint32_t& interface_num, \ @@ -170,8 +172,10 @@ nirio_status usrprio_rpc_client::niusrprio_download_fpga_to_flash(NIUSRPRIO_DOWN in_args << bitstream_path; static const uint32_t DOWNLOAD_FPGA_TIMEOUT = 1200000; - status = _boost_error_to_nirio_status( - _rpc_client.call(NIUSRPRIO_DOWNLOAD_FPGA_TO_FLASH, in_args, out_args, + status = + _boost_error_to_nirio_status(_rpc_client.call(NIUSRPRIO_DOWNLOAD_FPGA_TO_FLASH, + in_args, + out_args, boost::posix_time::milliseconds(DOWNLOAD_FPGA_TIMEOUT))); if (nirio_status_not_fatal(status)) { @@ -181,7 +185,8 @@ nirio_status usrprio_rpc_client::niusrprio_download_fpga_to_flash(NIUSRPRIO_DOWN return status; } -nirio_status usrprio_rpc_client::niusrprio_download_bitstream_to_fpga(NIUSRPRIO_DOWNLOAD_BITSTREAM_TO_FPGA_ARGS) +nirio_status usrprio_rpc_client::niusrprio_download_bitstream_to_fpga( + NIUSRPRIO_DOWNLOAD_BITSTREAM_TO_FPGA_ARGS) /* #define NIUSRPRIO_DOWNLOAD_BITSTREAM_TO_FPGA_ARGS \ const std::string& resource @@ -193,8 +198,8 @@ nirio_status usrprio_rpc_client::niusrprio_download_bitstream_to_fpga(NIUSRPRIO_ in_args << resource; - status = _boost_error_to_nirio_status( - _rpc_client.call(NIUSRPRIO_DOWNLOAD_BITSTREAM_TO_FPGA, in_args, out_args, _timeout)); + status = _boost_error_to_nirio_status(_rpc_client.call( + NIUSRPRIO_DOWNLOAD_BITSTREAM_TO_FPGA, in_args, out_args, _timeout)); if (nirio_status_not_fatal(status)) { out_args >> status; @@ -203,7 +208,9 @@ nirio_status usrprio_rpc_client::niusrprio_download_bitstream_to_fpga(NIUSRPRIO_ return status; } -nirio_status usrprio_rpc_client::_boost_error_to_nirio_status(const boost::system::error_code& err) { +nirio_status usrprio_rpc_client::_boost_error_to_nirio_status( + const boost::system::error_code& err) +{ if (err) { switch (err.value()) { case boost::asio::error::connection_aborted: @@ -221,4 +228,4 @@ nirio_status usrprio_rpc_client::_boost_error_to_nirio_status(const boost::syste } } -}} +}} // namespace uhd::usrprio_rpc diff --git a/host/lib/transport/nirio/status.cpp b/host/lib/transport/nirio/status.cpp index 4dd63f5c6..9d6c020c0 100644 --- a/host/lib/transport/nirio/status.cpp +++ b/host/lib/transport/nirio/status.cpp @@ -11,35 +11,38 @@ namespace uhd { namespace niusrprio { -#define NIRIO_ERR_INFO(CONST_NAME, ERR_CODE, ERR_MSG) \ - nirio_err_info(ERR_CODE, ERR_MSG), +#define NIRIO_ERR_INFO(CONST_NAME, ERR_CODE, ERR_MSG) nirio_err_info(ERR_CODE, ERR_MSG), const nirio_err_info nirio_err_info::NIRIO_ERROR_TABLE[] = { - #include "../../../include/uhd/transport/nirio/nirio_err_template.h" +#include "../../../include/uhd/transport/nirio/nirio_err_template.h" }; #undef NIRIO_ERR_INFO -const size_t nirio_err_info::NIRIO_ERROR_TABLE_SIZE = sizeof(NIRIO_ERROR_TABLE)/sizeof(*NIRIO_ERROR_TABLE); +const size_t nirio_err_info::NIRIO_ERROR_TABLE_SIZE = + sizeof(NIRIO_ERROR_TABLE) / sizeof(*NIRIO_ERROR_TABLE); -const std::string lookup_err_msg(nirio_status code) { - std::string error_msg = (boost::format("Unknown error. (Error code %d)") % code).str(); +const std::string lookup_err_msg(nirio_status code) +{ + std::string error_msg = + (boost::format("Unknown error. (Error code %d)") % code).str(); for (size_t i = 0; i < nirio_err_info::NIRIO_ERROR_TABLE_SIZE; i++) { if (nirio_err_info::NIRIO_ERROR_TABLE[i].code == code) { - error_msg = (boost::format("%s (Error code %d)") % nirio_err_info::NIRIO_ERROR_TABLE[i].msg % code).str(); + error_msg = (boost::format("%s (Error code %d)") + % nirio_err_info::NIRIO_ERROR_TABLE[i].msg % code) + .str(); break; } } return error_msg; } -void nirio_status_to_exception(const nirio_status& status, const std::string& message) { +void nirio_status_to_exception(const nirio_status& status, const std::string& message) +{ if (nirio_status_fatal(status)) { - throw uhd::runtime_error((boost::format("%s %s") % message % lookup_err_msg(status)).str()); + throw uhd::runtime_error( + (boost::format("%s %s") % message % lookup_err_msg(status)).str()); } } -}} - - - +}} // namespace uhd::niusrprio diff --git a/host/lib/transport/nirio_link.cpp b/host/lib/transport/nirio_link.cpp index c6183001f..adef8b5a0 100644 --- a/host/lib/transport/nirio_link.cpp +++ b/host/lib/transport/nirio_link.cpp @@ -88,14 +88,12 @@ nirio_link::nirio_link(uhd::niusrprio::niusrprio_session::sptr fpga_session, static_cast<uint32_t>(_link_params.recv_frame_size / sizeof(fifo_data_t))), status); - // Config 64-bit word flipping and enable DMA streams - nirio_status_chain( - PROXY->poke(PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), - DMA_CTRL_SW_BUF_U64 | DMA_CTRL_ENABLED), + // Config 64-bit word flipping and enable DMA streams + nirio_status_chain(PROXY->poke(PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), + DMA_CTRL_SW_BUF_U64 | DMA_CTRL_ENABLED), status); - nirio_status_chain( - PROXY->poke(PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), - DMA_CTRL_SW_BUF_U64 | DMA_CTRL_ENABLED), + nirio_status_chain(PROXY->poke(PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), + DMA_CTRL_SW_BUF_U64 | DMA_CTRL_ENABLED), status); // Create FIFOs diff --git a/host/lib/transport/nirio_zero_copy.cpp b/host/lib/transport/nirio_zero_copy.cpp index f54e5a8ed..8600b10d1 100644 --- a/host/lib/transport/nirio_zero_copy.cpp +++ b/host/lib/transport/nirio_zero_copy.cpp @@ -13,9 +13,9 @@ #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/format.hpp> #include <boost/interprocess/mapped_region.hpp> //get_page_size() -#include <memory> #include <algorithm> // std::max #include <chrono> +#include <memory> #include <thread> #include <vector> diff --git a/host/lib/transport/offload_io_service.cpp b/host/lib/transport/offload_io_service.cpp index ba95c843b..b92543587 100644 --- a/host/lib/transport/offload_io_service.cpp +++ b/host/lib/transport/offload_io_service.cpp @@ -28,17 +28,16 @@ constexpr int32_t blocking_timeout_ms = 10; // Fixed-size queue that supports blocking semantics template <typename queue_item_t> -class offload_thread_queue { +class offload_thread_queue +{ public: - offload_thread_queue(size_t size) - : _buffer(new queue_item_t[size]) - , _capacity(size) + offload_thread_queue(size_t size) : _buffer(new queue_item_t[size]), _capacity(size) { } ~offload_thread_queue() { - delete [] _buffer; + delete[] _buffer; } void push(const queue_item_t& item) @@ -475,7 +474,8 @@ recv_io_if::sptr offload_io_service_impl::make_recv_client(recv_link_if::sptr re // Create a request to create a new receiver in the offload thread auto req_fn = [this, recv_link, num_recv_frames, cb, fc_link, num_send_frames, fc_cb, port]() { - frame_reservation_t frames = {recv_link, num_recv_frames, fc_link, num_send_frames}; + frame_reservation_t frames = { + recv_link, num_recv_frames, fc_link, num_send_frames}; _reservation_mgr.reserve_frames(frames); auto inline_recv_io = _io_srv->make_recv_client( @@ -529,13 +529,19 @@ send_io_if::sptr offload_io_service_impl::make_send_client(send_link_if::sptr se recv_link, num_recv_frames, recv_cb, - fc_cb, + fc_cb, port]() { - frame_reservation_t frames = {recv_link, num_recv_frames, send_link, num_send_frames}; + frame_reservation_t frames = { + recv_link, num_recv_frames, send_link, num_send_frames}; _reservation_mgr.reserve_frames(frames); - auto inline_send_io = _io_srv->make_send_client( - send_link, num_send_frames, send_cb, recv_link, num_recv_frames, recv_cb, fc_cb); + auto inline_send_io = _io_srv->make_send_client(send_link, + num_send_frames, + send_cb, + recv_link, + num_recv_frames, + recv_cb, + fc_cb); send_client_info_t client_info; client_info.inline_io = inline_send_io; @@ -599,7 +605,8 @@ void offload_io_service_impl::_get_send_buff(send_client_info_t& info) } // Release a single recv buffer and update client info -void offload_io_service_impl::_release_recv_buff(recv_client_info_t& info, frame_buff* buff) +void offload_io_service_impl::_release_recv_buff( + recv_client_info_t& info, frame_buff* buff) { info.inline_io->release_recv_buff(frame_buff::uptr(buff)); assert(info.num_frames_in_use > 0); @@ -607,7 +614,8 @@ void offload_io_service_impl::_release_recv_buff(recv_client_info_t& info, frame } // Release a single send info -void offload_io_service_impl::_release_send_buff(send_client_info_t& info, frame_buff* buff) +void offload_io_service_impl::_release_send_buff( + send_client_info_t& info, frame_buff* buff) { info.inline_io->release_send_buff(frame_buff::uptr(buff)); assert(info.num_frames_in_use > 0); @@ -728,7 +736,8 @@ void offload_io_service_impl::_do_work_blocking() if (it->num_frames_in_use == it->frames_reserved.num_recv_frames) { // If all buffers are in use, block to avoid excessive CPU usage - std::tie(buff, disconnect) = it->port->offload_thread_pop(blocking_timeout_ms); + std::tie(buff, disconnect) = + it->port->offload_thread_pop(blocking_timeout_ms); } else { // Otherwise, just check current status std::tie(buff, disconnect) = it->port->offload_thread_pop(); @@ -758,7 +767,8 @@ void offload_io_service_impl::_do_work_blocking() bool disconnect; std::tie(buff, disconnect) = it->port->offload_thread_peek(); if (buff) { - if (it->inline_io->wait_for_dest_ready(buff->packet_size(), blocking_timeout_ms)) { + if (it->inline_io->wait_for_dest_ready( + buff->packet_size(), blocking_timeout_ms)) { _release_send_buff(*it, buff); it->port->offload_thread_pop(); } diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp index b19b50b38..f428f01f1 100644 --- a/host/lib/transport/super_recv_packet_handler.hpp +++ b/host/lib/transport/super_recv_packet_handler.hpp @@ -21,8 +21,8 @@ #include <boost/dynamic_bitset.hpp> #include <boost/format.hpp> #include <functional> -#include <memory> #include <iostream> +#include <memory> #include <vector> namespace uhd { namespace transport { namespace sph { @@ -670,9 +670,9 @@ private: curr_info.metadata.time_spec = prev_info.metadata.time_spec + time_spec_t::from_ticks( - prev_info[index].ifpi.num_payload_words32 * sizeof(uint32_t) - / _bytes_per_otw_item, - _samp_rate); + prev_info[index].ifpi.num_payload_words32 * sizeof(uint32_t) + / _bytes_per_otw_item, + _samp_rate); curr_info.metadata.out_of_sequence = true; curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_OVERFLOW; UHD_LOG_FASTPATH("D"); @@ -797,7 +797,6 @@ private: const rx_streamer::buffs_type* _convert_buffs; size_t _convert_buffer_offset_bytes; size_t _convert_bytes_to_copy; - }; class recv_packet_streamer : public recv_packet_handler, public rx_streamer diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp index 21f7357c3..556530f81 100644 --- a/host/lib/transport/super_send_packet_handler.hpp +++ b/host/lib/transport/super_send_packet_handler.hpp @@ -18,8 +18,8 @@ #include <uhd/utils/byteswap.hpp> #include <uhd/utils/tasks.hpp> #include <uhd/utils/thread.hpp> -#include <functional> #include <chrono> +#include <functional> #include <iostream> #include <thread> #include <vector> diff --git a/host/lib/transport/tcp_zero_copy.cpp b/host/lib/transport/tcp_zero_copy.cpp index 555dd238e..0927a08ee 100644 --- a/host/lib/transport/tcp_zero_copy.cpp +++ b/host/lib/transport/tcp_zero_copy.cpp @@ -8,11 +8,11 @@ #include <uhd/transport/buffer_pool.hpp> #include <uhd/transport/tcp_zero_copy.hpp> #include <uhd/utils/log.hpp> -#include <uhdlib/utils/atomic.hpp> #include <uhdlib/transport/udp_common.hpp> +#include <uhdlib/utils/atomic.hpp> #include <boost/format.hpp> -#include <memory> #include <chrono> +#include <memory> #include <thread> #include <vector> diff --git a/host/lib/transport/udp_zero_copy.cpp b/host/lib/transport/udp_zero_copy.cpp index 883b2a68a..1a6f55259 100644 --- a/host/lib/transport/udp_zero_copy.cpp +++ b/host/lib/transport/udp_zero_copy.cpp @@ -11,8 +11,8 @@ #include <uhdlib/transport/udp_common.hpp> #include <uhdlib/utils/atomic.hpp> #include <boost/format.hpp> -#include <memory> #include <chrono> +#include <memory> #include <thread> #include <vector> @@ -303,10 +303,8 @@ udp_zero_copy::sptr udp_zero_copy::make(const std::string& addr, xport_params.send_frame_size = UDP_DEFAULT_FRAME_SIZE; } - UHD_LOG_TRACE("UDP", - "send_frame_size: " << xport_params.send_frame_size); - UHD_LOG_TRACE("UDP", - "recv_frame_size: " << xport_params.recv_frame_size); + UHD_LOG_TRACE("UDP", "send_frame_size: " << xport_params.send_frame_size); + UHD_LOG_TRACE("UDP", "recv_frame_size: " << xport_params.recv_frame_size); if (xport_params.recv_buff_size == 0) { UHD_LOG_TRACE("UDP", "Using default value for recv_buff_size"); diff --git a/host/lib/transport/zero_copy_flow_ctrl.cpp b/host/lib/transport/zero_copy_flow_ctrl.cpp index 610d93281..05907c209 100644 --- a/host/lib/transport/zero_copy_flow_ctrl.cpp +++ b/host/lib/transport/zero_copy_flow_ctrl.cpp @@ -10,11 +10,11 @@ #include <uhd/transport/zero_copy_flow_ctrl.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/safe_call.hpp> -#include <functional> #include <boost/format.hpp> -#include <memory> #include <boost/thread/mutex.hpp> #include <boost/thread/thread.hpp> +#include <functional> +#include <memory> using namespace uhd; using namespace uhd::transport; @@ -113,12 +113,10 @@ public: UHD_LOG_TRACE("TRANSPORT", "Created zero_copy_flow_ctrl"); for (size_t i = 0; i < transport->get_num_send_frames(); i++) { - _send_buffers[i] = - std::make_shared<zero_copy_flow_ctrl_msb>(_send_flow_ctrl); + _send_buffers[i] = std::make_shared<zero_copy_flow_ctrl_msb>(_send_flow_ctrl); } for (size_t i = 0; i < transport->get_num_recv_frames(); i++) { - _recv_buffers[i] = - std::make_shared<zero_copy_flow_ctrl_mrb>(_recv_flow_ctrl); + _recv_buffers[i] = std::make_shared<zero_copy_flow_ctrl_mrb>(_recv_flow_ctrl); } } diff --git a/host/lib/types/byte_vector.cpp b/host/lib/types/byte_vector.cpp index d3633f2f6..68908c503 100644 --- a/host/lib/types/byte_vector.cpp +++ b/host/lib/types/byte_vector.cpp @@ -8,23 +8,27 @@ #include <uhd/types/byte_vector.hpp> -namespace uhd{ +namespace uhd { -std::string bytes_to_string(const byte_vector_t &bytes){ +std::string bytes_to_string(const byte_vector_t& bytes) +{ std::string out; - for(uint8_t byte: bytes){ - if (byte < 32 or byte > 127) return out; + for (uint8_t byte : bytes) { + if (byte < 32 or byte > 127) + return out; out += byte; } return out; } -byte_vector_t string_to_bytes(const std::string &str, size_t max_length){ +byte_vector_t string_to_bytes(const std::string& str, size_t max_length) +{ byte_vector_t bytes; - for (size_t i = 0; i < std::min(str.size(), max_length); i++){ + for (size_t i = 0; i < std::min(str.size(), max_length); i++) { bytes.push_back(str[i]); } - if (bytes.size() < max_length - 1) bytes.push_back('\0'); + if (bytes.size() < max_length - 1) + bytes.push_back('\0'); return bytes; } diff --git a/host/lib/types/device_addr.cpp b/host/lib/types/device_addr.cpp index be6198356..d5e9ce0d4 100644 --- a/host/lib/types/device_addr.cpp +++ b/host/lib/types/device_addr.cpp @@ -7,92 +7,100 @@ #include <uhd/types/device_addr.hpp> #include <boost/algorithm/string.hpp> -#include <boost/tokenizer.hpp> #include <boost/format.hpp> +#include <boost/tokenizer.hpp> #include <regex> -#include <stdexcept> #include <sstream> +#include <stdexcept> using namespace uhd; -static const char* arg_delim = ","; +static const char* arg_delim = ","; static const char* pair_delim = "="; -static std::string trim(const std::string &in){ +static std::string trim(const std::string& in) +{ return boost::algorithm::trim_copy(in); } #define tokenizer(inp, sep) \ - boost::tokenizer<boost::char_separator<char> > \ - (inp, boost::char_separator<char>(sep)) + boost::tokenizer<boost::char_separator<char>>(inp, boost::char_separator<char>(sep)) -device_addr_t::device_addr_t(const std::string &args){ - for(const std::string &pair: tokenizer(args, arg_delim)){ - if (trim(pair) == "") continue; +device_addr_t::device_addr_t(const std::string& args) +{ + for (const std::string& pair : tokenizer(args, arg_delim)) { + if (trim(pair) == "") + continue; std::vector<std::string> toks; - for(const std::string &tok: tokenizer(pair, pair_delim)){ + for (const std::string& tok : tokenizer(pair, pair_delim)) { toks.push_back(tok); } - if (toks.size() == 1) toks.push_back(""); //pad empty value - if (toks.size() == 2 and not trim(toks[0]).empty()){ //only valid combination + if (toks.size() == 1) + toks.push_back(""); // pad empty value + if (toks.size() == 2 and not trim(toks[0]).empty()) { // only valid combination this->set(trim(toks[0]), trim(toks[1])); - } - else throw uhd::value_error("invalid args string: "+args); //otherwise error + } else + throw uhd::value_error("invalid args string: " + args); // otherwise error } } -device_addr_t::device_addr_t(const std::map<std::string, std::string> &info) { +device_addr_t::device_addr_t(const std::map<std::string, std::string>& info) +{ for (auto& t : info) { this->set(t.first, t.second); } } -std::string device_addr_t::to_pp_string(void) const{ - if (this->size() == 0) return "Empty Device Address"; +std::string device_addr_t::to_pp_string(void) const +{ + if (this->size() == 0) + return "Empty Device Address"; std::stringstream ss; ss << "Device Address:" << std::endl; - for(std::string key: this->keys()){ + for (std::string key : this->keys()) { ss << boost::format(" %s: %s") % key % this->get(key) << std::endl; } return ss.str(); } -std::string device_addr_t::to_string(void) const{ +std::string device_addr_t::to_string(void) const +{ std::string args_str; size_t count = 0; - for(const std::string &key: this->keys()){ - args_str += ((count++)? arg_delim : "") + key + pair_delim + this->get(key); + for (const std::string& key : this->keys()) { + args_str += ((count++) ? arg_delim : "") + key + pair_delim + this->get(key); } return args_str; } #include <uhd/utils/log.hpp> -device_addrs_t uhd::separate_device_addr(const device_addr_t &dev_addr){ +device_addrs_t uhd::separate_device_addr(const device_addr_t& dev_addr) +{ //------------ support old deprecated way and print warning -------- - if (dev_addr.has_key("addr") and not dev_addr["addr"].empty()){ - std::vector<std::string> addrs; boost::split(addrs, dev_addr["addr"], boost::is_any_of(" ")); - if (addrs.size() > 1){ + if (dev_addr.has_key("addr") and not dev_addr["addr"].empty()) { + std::vector<std::string> addrs; + boost::split(addrs, dev_addr["addr"], boost::is_any_of(" ")); + if (addrs.size() > 1) { device_addr_t fixed_dev_addr = dev_addr; fixed_dev_addr.pop("addr"); - for (size_t i = 0; i < addrs.size(); i++){ + for (size_t i = 0; i < addrs.size(); i++) { fixed_dev_addr[str(boost::format("addr%d") % i)] = addrs[i]; } - UHD_LOGGER_WARNING("UHD") << - "addr = <space separated list of ip addresses> is deprecated.\n" - "To address a multi-device, use multiple <key><index> = <val>.\n" - "See the USRP-NXXX application notes. Two device example:\n" - " addr0 = 192.168.10.2\n" - " addr1 = 192.168.10.3\n" - ; + UHD_LOGGER_WARNING("UHD") + << "addr = <space separated list of ip addresses> is deprecated.\n" + "To address a multi-device, use multiple <key><index> = <val>.\n" + "See the USRP-NXXX application notes. Two device example:\n" + " addr0 = 192.168.10.2\n" + " addr1 = 192.168.10.3\n"; return separate_device_addr(fixed_dev_addr); } } //------------------------------------------------------------------ - device_addrs_t dev_addrs(1); //must be at least one (obviously) - std::vector<std::string> global_keys; //keys that apply to all (no numerical suffix) - for(const std::string &key: dev_addr.keys()){ + device_addrs_t dev_addrs(1); // must be at least one (obviously) + std::vector<std::string> global_keys; // keys that apply to all (no numerical suffix) + for (const std::string& key : dev_addr.keys()) { std::cmatch matches; // Key must start with a non-digit, and may optionally end with a digit // that indicates the mb index. Also allow keys that have integers within @@ -103,28 +111,29 @@ device_addrs_t uhd::separate_device_addr(const device_addr_t &dev_addr){ } std::string key_part(matches[1].first, matches[1].second); std::string num_part(matches[2].first, matches[2].second); - if (num_part.empty()){ //no number? save it for later + if (num_part.empty()) { // no number? save it for later global_keys.push_back(key); continue; } const size_t num = boost::lexical_cast<size_t>(num_part); - dev_addrs.resize(std::max(num+1, dev_addrs.size())); + dev_addrs.resize(std::max(num + 1, dev_addrs.size())); dev_addrs[num][key_part] = dev_addr[key]; } - //copy the global settings across all device addresses - for(device_addr_t &my_dev_addr: dev_addrs){ - for(const std::string &global_key: global_keys){ + // copy the global settings across all device addresses + for (device_addr_t& my_dev_addr : dev_addrs) { + for (const std::string& global_key : global_keys) { my_dev_addr[global_key] = dev_addr[global_key]; } } return dev_addrs; } -device_addr_t uhd::combine_device_addrs(const device_addrs_t &dev_addrs){ +device_addr_t uhd::combine_device_addrs(const device_addrs_t& dev_addrs) +{ device_addr_t dev_addr; - for (size_t i = 0; i < dev_addrs.size(); i++){ - for(const std::string &key: dev_addrs[i].keys()){ + for (size_t i = 0; i < dev_addrs.size(); i++) { + for (const std::string& key : dev_addrs[i].keys()) { dev_addr[str(boost::format("%s%d") % key % i)] = dev_addrs[i][key]; } } diff --git a/host/lib/types/filters.cpp b/host/lib/types/filters.cpp index 5d59e4cd5..a39dd0f58 100644 --- a/host/lib/types/filters.cpp +++ b/host/lib/types/filters.cpp @@ -18,47 +18,49 @@ std::string filter_info_base::to_pp_string() { std::ostringstream os; os << "[filter_info_base]" << std::endl; - switch(_type){ + switch (_type) { case ANALOG_LOW_PASS: - os << "type: " << "Analog Low-pass" << std::endl; + os << "type: " + << "Analog Low-pass" << std::endl; break; case ANALOG_BAND_PASS: - os << "type: " << "Analog Band-pass" << std::endl; + os << "type: " + << "Analog Band-pass" << std::endl; break; case DIGITAL_I16: - os << "type: " << "Digital (i16)" << std::endl; + os << "type: " + << "Digital (i16)" << std::endl; break; case DIGITAL_FIR_I16: - os << "type: " << "Digital FIR (i16)" << std::endl; + os << "type: " + << "Digital FIR (i16)" << std::endl; break; default: - os << "type: " << "Unknown type!" << std::endl; + os << "type: " + << "Unknown type!" << std::endl; break; - } + } os << "bypass enable: " << _bypass << std::endl - <<"position index: " << _position_index << std::endl; + << "position index: " << _position_index << std::endl; - std::string str = os.str(); + std::string str = os.str(); return str; } std::string analog_filter_base::to_pp_string() { std::ostringstream os; - os << filter_info_base::to_pp_string() << - "\t[analog_filter_base]" << std::endl << - "\tdesc: " << _analog_type << std::endl; + os << filter_info_base::to_pp_string() << "\t[analog_filter_base]" << std::endl + << "\tdesc: " << _analog_type << std::endl; return std::string(os.str()); - } std::string analog_filter_lp::to_pp_string() { std::ostringstream os; - os << analog_filter_base::to_pp_string() << - "\t\t[analog_filter_lp]" << std::endl << - "\t\tcutoff: " << _cutoff << std::endl << - "\t\trolloff: " << _rolloff << std::endl; + os << analog_filter_base::to_pp_string() << "\t\t[analog_filter_lp]" << std::endl + << "\t\tcutoff: " << _cutoff << std::endl + << "\t\trolloff: " << _rolloff << std::endl; return std::string(os.str()); } diff --git a/host/lib/types/filters_python.hpp b/host/lib/types/filters_python.hpp index be02c7a98..76b2c3a49 100644 --- a/host/lib/types/filters_python.hpp +++ b/host/lib/types/filters_python.hpp @@ -18,36 +18,33 @@ void export_filters(py::module& m) using analog_filter_lp = uhd::analog_filter_lp; py::enum_<filter_info_type>(m, "filter_type") - .value("analog_low_pass" , filter_info_base::ANALOG_LOW_PASS ) + .value("analog_low_pass", filter_info_base::ANALOG_LOW_PASS) .value("analog_band_pass", filter_info_base::ANALOG_BAND_PASS) - .value("digital_i16" , filter_info_base::DIGITAL_I16 ) - .value("digital_fir_i16" , filter_info_base::DIGITAL_FIR_I16 ) - ; + .value("digital_i16", filter_info_base::DIGITAL_I16) + .value("digital_fir_i16", filter_info_base::DIGITAL_FIR_I16); py::class_<filter_info_base, filter_info_base::sptr>(m, "filter_info_base") .def(py::init<filter_info_type, bool, size_t>()) // Methods - .def("is_bypassed", &filter_info_base::is_bypassed ) - .def("get_type" , &filter_info_base::get_type ) - .def("__str__" , &filter_info_base::to_pp_string) - ; + .def("is_bypassed", &filter_info_base::is_bypassed) + .def("get_type", &filter_info_base::get_type) + .def("__str__", &filter_info_base::to_pp_string); py::class_<analog_filter_base, analog_filter_base::sptr>(m, "analog_filter_base") .def(py::init<filter_info_type, bool, size_t, std::string>()) // Methods - .def("get_analog_type", &analog_filter_base::get_analog_type) - ; + .def("get_analog_type", &analog_filter_base::get_analog_type); py::class_<analog_filter_lp, std::shared_ptr<analog_filter_lp>>(m, "analog_filter_lp") - .def(py::init<filter_info_type, bool, size_t, const std::string, double, double>()) + .def( + py::init<filter_info_type, bool, size_t, const std::string, double, double>()) // Methods - .def("get_cutoff" , &analog_filter_lp::get_cutoff ) + .def("get_cutoff", &analog_filter_lp::get_cutoff) .def("get_rolloff", &analog_filter_lp::get_rolloff) - .def("set_cutoff" , &analog_filter_lp::set_cutoff ) - ; + .def("set_cutoff", &analog_filter_lp::set_cutoff); } #endif /* INCLUDED_UHD_FILTERS_PYTHON_HPP */ diff --git a/host/lib/types/mac_addr.cpp b/host/lib/types/mac_addr.cpp index dc710c4eb..a2f3dec3a 100644 --- a/host/lib/types/mac_addr.cpp +++ b/host/lib/types/mac_addr.cpp @@ -5,60 +5,62 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/types/mac_addr.hpp> #include <uhd/exception.hpp> -#include <boost/tokenizer.hpp> -#include <boost/format.hpp> +#include <uhd/types/mac_addr.hpp> #include <stdint.h> +#include <boost/format.hpp> +#include <boost/tokenizer.hpp> #include <sstream> using namespace uhd; -mac_addr_t::mac_addr_t(const byte_vector_t &bytes) : _bytes(bytes){ +mac_addr_t::mac_addr_t(const byte_vector_t& bytes) : _bytes(bytes) +{ UHD_ASSERT_THROW(_bytes.size() == 6); } -mac_addr_t mac_addr_t::from_bytes(const byte_vector_t &bytes){ +mac_addr_t mac_addr_t::from_bytes(const byte_vector_t& bytes) +{ return mac_addr_t(bytes); } -mac_addr_t mac_addr_t::from_string(const std::string &mac_addr_str){ - +mac_addr_t mac_addr_t::from_string(const std::string& mac_addr_str) +{ byte_vector_t bytes; - try{ - if (mac_addr_str.size() != 17){ + try { + if (mac_addr_str.size() != 17) { throw uhd::value_error("expected exactly 17 characters"); } - //split the mac addr hex string at the colons - boost::tokenizer<boost::char_separator<char> > hex_num_toks( + // split the mac addr hex string at the colons + boost::tokenizer<boost::char_separator<char>> hex_num_toks( mac_addr_str, boost::char_separator<char>(":")); - for(const std::string &hex_str: hex_num_toks){ + for (const std::string& hex_str : hex_num_toks) { int hex_num; std::istringstream iss(hex_str); iss >> std::hex >> hex_num; bytes.push_back(uint8_t(hex_num)); } - } - catch(std::exception const& e){ + } catch (std::exception const& e) { throw uhd::value_error(str( - boost::format("Invalid mac address: %s\n\t%s") % mac_addr_str % e.what() - )); + boost::format("Invalid mac address: %s\n\t%s") % mac_addr_str % e.what())); } return mac_addr_t::from_bytes(bytes); } -byte_vector_t mac_addr_t::to_bytes(void) const{ +byte_vector_t mac_addr_t::to_bytes(void) const +{ return _bytes; } -std::string mac_addr_t::to_string(void) const{ +std::string mac_addr_t::to_string(void) const +{ std::string addr = ""; - for(uint8_t byte: this->to_bytes()){ - addr += str(boost::format("%s%02x") % ((addr == "")?"":":") % int(byte)); + for (uint8_t byte : this->to_bytes()) { + addr += str(boost::format("%s%02x") % ((addr == "") ? "" : ":") % int(byte)); } return addr; } diff --git a/host/lib/types/metadata.cpp b/host/lib/types/metadata.cpp index bdc432d9c..73cb00762 100644 --- a/host/lib/types/metadata.cpp +++ b/host/lib/types/metadata.cpp @@ -5,12 +5,12 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <string> -#include <sstream> -#include <boost/format.hpp> #include <uhd/exception.hpp> #include <uhd/types/metadata.hpp> #include <uhd/types/time_spec.hpp> +#include <boost/format.hpp> +#include <sstream> +#include <string> using namespace uhd; @@ -51,7 +51,7 @@ std::string rx_metadata_t::to_pp_string(bool compact) const std::string rx_metadata_t::strerror() const { std::string errstr = ""; - switch(this->error_code) { + switch (this->error_code) { case ERROR_CODE_NONE: errstr = "ERROR_CODE_NONE"; break; @@ -66,7 +66,7 @@ std::string rx_metadata_t::strerror() const break; case ERROR_CODE_OVERFLOW: errstr = "ERROR_CODE_OVERFLOW "; - errstr += (this->out_of_sequence ? "(Out of sequence error)" : "(Overflow)"); + errstr += (this->out_of_sequence ? "(Out of sequence error)" : "(Overflow)"); break; case ERROR_CODE_ALIGNMENT: errstr = "ERROR_CODE_ALIGNMENT (Multi-channel alignment failed)"; @@ -74,8 +74,9 @@ std::string rx_metadata_t::strerror() const case ERROR_CODE_BAD_PACKET: errstr = "ERROR_CODE_BAD_PACKET"; break; - default: - errstr = std::string(str(boost::format("Unknown error code: 0x%x") % error_code)); + default: + errstr = + std::string(str(boost::format("Unknown error code: 0x%x") % error_code)); } return errstr; diff --git a/host/lib/types/metadata_c.cpp b/host/lib/types/metadata_c.cpp index 35e3d76c9..40c15a8fe 100644 --- a/host/lib/types/metadata_c.cpp +++ b/host/lib/types/metadata_c.cpp @@ -6,300 +6,204 @@ // #include <uhd/types/metadata.h> - #include <uhd/types/time_spec.hpp> - #include <string.h> /* * RX metadata */ -uhd_error uhd_rx_metadata_make( - uhd_rx_metadata_handle* handle -){ - UHD_SAFE_C( - *handle = new uhd_rx_metadata_t; - ) +uhd_error uhd_rx_metadata_make(uhd_rx_metadata_handle* handle) +{ + UHD_SAFE_C(*handle = new uhd_rx_metadata_t;) } -uhd_error uhd_rx_metadata_free( - uhd_rx_metadata_handle* handle -){ - UHD_SAFE_C( - delete *handle; - *handle = NULL; - ) +uhd_error uhd_rx_metadata_free(uhd_rx_metadata_handle* handle) +{ + UHD_SAFE_C(delete *handle; *handle = NULL;) } -uhd_error uhd_rx_metadata_has_time_spec( - uhd_rx_metadata_handle h, - bool *result_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *result_out = h->rx_metadata_cpp.has_time_spec; - ) +uhd_error uhd_rx_metadata_has_time_spec(uhd_rx_metadata_handle h, bool* result_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *result_out = h->rx_metadata_cpp.has_time_spec;) } uhd_error uhd_rx_metadata_time_spec( - uhd_rx_metadata_handle h, - int64_t *full_secs_out, - double *frac_secs_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::time_spec_t time_spec_cpp = h->rx_metadata_cpp.time_spec; + uhd_rx_metadata_handle h, int64_t* full_secs_out, double* frac_secs_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, uhd::time_spec_t time_spec_cpp = h->rx_metadata_cpp.time_spec; *full_secs_out = time_spec_cpp.get_full_secs(); - *frac_secs_out = time_spec_cpp.get_frac_secs(); - ) + *frac_secs_out = time_spec_cpp.get_frac_secs();) } -uhd_error uhd_rx_metadata_more_fragments( - uhd_rx_metadata_handle h, - bool *result_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *result_out = h->rx_metadata_cpp.more_fragments; - ) +uhd_error uhd_rx_metadata_more_fragments(uhd_rx_metadata_handle h, bool* result_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *result_out = h->rx_metadata_cpp.more_fragments;) } uhd_error uhd_rx_metadata_fragment_offset( - uhd_rx_metadata_handle h, - size_t *fragment_offset_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *fragment_offset_out = h->rx_metadata_cpp.fragment_offset; - ) + uhd_rx_metadata_handle h, size_t* fragment_offset_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *fragment_offset_out = h->rx_metadata_cpp.fragment_offset;) } -uhd_error uhd_rx_metadata_start_of_burst( - uhd_rx_metadata_handle h, - bool *result_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *result_out = h->rx_metadata_cpp.start_of_burst; - ) +uhd_error uhd_rx_metadata_start_of_burst(uhd_rx_metadata_handle h, bool* result_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *result_out = h->rx_metadata_cpp.start_of_burst;) } -uhd_error uhd_rx_metadata_end_of_burst( - uhd_rx_metadata_handle h, - bool *result_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *result_out = h->rx_metadata_cpp.end_of_burst; - ) +uhd_error uhd_rx_metadata_end_of_burst(uhd_rx_metadata_handle h, bool* result_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *result_out = h->rx_metadata_cpp.end_of_burst;) } -uhd_error uhd_rx_metadata_out_of_sequence( - uhd_rx_metadata_handle h, - bool *result_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *result_out = h->rx_metadata_cpp.out_of_sequence; - ) +uhd_error uhd_rx_metadata_out_of_sequence(uhd_rx_metadata_handle h, bool* result_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *result_out = h->rx_metadata_cpp.out_of_sequence;) } uhd_error uhd_rx_metadata_to_pp_string( - uhd_rx_metadata_handle h, - char* pp_string_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string pp_string_cpp = h->rx_metadata_cpp.to_pp_string(); + uhd_rx_metadata_handle h, char* pp_string_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR( + h, std::string pp_string_cpp = h->rx_metadata_cpp.to_pp_string(); memset(pp_string_out, '\0', strbuffer_len); - strncpy(pp_string_out, pp_string_cpp.c_str(), strbuffer_len); - ) + strncpy(pp_string_out, pp_string_cpp.c_str(), strbuffer_len);) } uhd_error uhd_rx_metadata_error_code( - uhd_rx_metadata_handle h, - uhd_rx_metadata_error_code_t *error_code_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *error_code_out = uhd_rx_metadata_error_code_t(h->rx_metadata_cpp.error_code); - ) + uhd_rx_metadata_handle h, uhd_rx_metadata_error_code_t* error_code_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, *error_code_out = uhd_rx_metadata_error_code_t(h->rx_metadata_cpp.error_code);) } uhd_error uhd_rx_metadata_strerror( - uhd_rx_metadata_handle h, - char* strerror_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string strerror_cpp = h->rx_metadata_cpp.strerror(); - memset(strerror_out, '\0', strbuffer_len); - strncpy(strerror_out, strerror_cpp.c_str(), strbuffer_len); - ) + uhd_rx_metadata_handle h, char* strerror_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR(h, std::string strerror_cpp = h->rx_metadata_cpp.strerror(); + memset(strerror_out, '\0', strbuffer_len); + strncpy(strerror_out, strerror_cpp.c_str(), strbuffer_len);) } uhd_error uhd_rx_metadata_last_error( - uhd_rx_metadata_handle h, - char* error_out, - size_t strbuffer_len -){ - UHD_SAFE_C( - memset(error_out, '\0', strbuffer_len); - strncpy(error_out, h->last_error.c_str(), strbuffer_len); - ) + uhd_rx_metadata_handle h, char* error_out, size_t strbuffer_len) +{ + UHD_SAFE_C(memset(error_out, '\0', strbuffer_len); + strncpy(error_out, h->last_error.c_str(), strbuffer_len);) } /* * TX metadata */ -uhd_error uhd_tx_metadata_make( - uhd_tx_metadata_handle* handle, +uhd_error uhd_tx_metadata_make(uhd_tx_metadata_handle* handle, bool has_time_spec, int64_t full_secs, double frac_secs, bool start_of_burst, - bool end_of_burst -){ - UHD_SAFE_C( - *handle = new uhd_tx_metadata_t; - (*handle)->tx_metadata_cpp.has_time_spec = has_time_spec; - if(has_time_spec){ - (*handle)->tx_metadata_cpp.time_spec = uhd::time_spec_t(full_secs, frac_secs); - } - (*handle)->tx_metadata_cpp.start_of_burst = start_of_burst; - (*handle)->tx_metadata_cpp.end_of_burst = end_of_burst; - ) + bool end_of_burst) +{ + UHD_SAFE_C(*handle = new uhd_tx_metadata_t; + (*handle)->tx_metadata_cpp.has_time_spec = has_time_spec; + if (has_time_spec) { + (*handle)->tx_metadata_cpp.time_spec = + uhd::time_spec_t(full_secs, frac_secs); + }(*handle) + ->tx_metadata_cpp.start_of_burst = start_of_burst; + (*handle)->tx_metadata_cpp.end_of_burst = end_of_burst;) } -uhd_error uhd_tx_metadata_free( - uhd_tx_metadata_handle* handle -){ - UHD_SAFE_C( - delete *handle; - *handle = NULL; - ) +uhd_error uhd_tx_metadata_free(uhd_tx_metadata_handle* handle) +{ + UHD_SAFE_C(delete *handle; *handle = NULL;) } -uhd_error uhd_tx_metadata_has_time_spec( - uhd_tx_metadata_handle h, - bool *result_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *result_out = h->tx_metadata_cpp.has_time_spec; - ) +uhd_error uhd_tx_metadata_has_time_spec(uhd_tx_metadata_handle h, bool* result_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *result_out = h->tx_metadata_cpp.has_time_spec;) } uhd_error uhd_tx_metadata_time_spec( - uhd_tx_metadata_handle h, - int64_t *full_secs_out, - double *frac_secs_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::time_spec_t time_spec_cpp = h->tx_metadata_cpp.time_spec; + uhd_tx_metadata_handle h, int64_t* full_secs_out, double* frac_secs_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, uhd::time_spec_t time_spec_cpp = h->tx_metadata_cpp.time_spec; *full_secs_out = time_spec_cpp.get_full_secs(); - *frac_secs_out = time_spec_cpp.get_frac_secs(); - ) + *frac_secs_out = time_spec_cpp.get_frac_secs();) } -uhd_error uhd_tx_metadata_start_of_burst( - uhd_tx_metadata_handle h, - bool *result_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *result_out = h->tx_metadata_cpp.start_of_burst; - ) +uhd_error uhd_tx_metadata_start_of_burst(uhd_tx_metadata_handle h, bool* result_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *result_out = h->tx_metadata_cpp.start_of_burst;) } -uhd_error uhd_tx_metadata_end_of_burst( - uhd_tx_metadata_handle h, - bool *result_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *result_out = h->tx_metadata_cpp.end_of_burst; - ) +uhd_error uhd_tx_metadata_end_of_burst(uhd_tx_metadata_handle h, bool* result_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *result_out = h->tx_metadata_cpp.end_of_burst;) } uhd_error uhd_tx_metadata_last_error( - uhd_tx_metadata_handle h, - char* error_out, - size_t strbuffer_len -){ - UHD_SAFE_C( - memset(error_out, '\0', strbuffer_len); - strncpy(error_out, h->last_error.c_str(), strbuffer_len); - ) + uhd_tx_metadata_handle h, char* error_out, size_t strbuffer_len) +{ + UHD_SAFE_C(memset(error_out, '\0', strbuffer_len); + strncpy(error_out, h->last_error.c_str(), strbuffer_len);) } /* * Async metadata */ -uhd_error uhd_async_metadata_make( - uhd_async_metadata_handle* handle -){ - UHD_SAFE_C( - *handle = new uhd_async_metadata_t; - ) +uhd_error uhd_async_metadata_make(uhd_async_metadata_handle* handle) +{ + UHD_SAFE_C(*handle = new uhd_async_metadata_t;) } -uhd_error uhd_async_metadata_free( - uhd_async_metadata_handle* handle -){ - UHD_SAFE_C( - delete *handle; - *handle = NULL; - ) +uhd_error uhd_async_metadata_free(uhd_async_metadata_handle* handle) +{ + UHD_SAFE_C(delete *handle; *handle = NULL;) } -uhd_error uhd_async_metadata_channel( - uhd_async_metadata_handle h, - size_t *channel_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *channel_out = h->async_metadata_cpp.channel; - ) +uhd_error uhd_async_metadata_channel(uhd_async_metadata_handle h, size_t* channel_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *channel_out = h->async_metadata_cpp.channel;) } -uhd_error uhd_async_metadata_has_time_spec( - uhd_async_metadata_handle h, - bool *result_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *result_out = h->async_metadata_cpp.has_time_spec; - ) +uhd_error uhd_async_metadata_has_time_spec(uhd_async_metadata_handle h, bool* result_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *result_out = h->async_metadata_cpp.has_time_spec;) } uhd_error uhd_async_metadata_time_spec( - uhd_async_metadata_handle h, - int64_t *full_secs_out, - double *frac_secs_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::time_spec_t time_spec_cpp = h->async_metadata_cpp.time_spec; + uhd_async_metadata_handle h, int64_t* full_secs_out, double* frac_secs_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, uhd::time_spec_t time_spec_cpp = h->async_metadata_cpp.time_spec; *full_secs_out = time_spec_cpp.get_full_secs(); - *frac_secs_out = time_spec_cpp.get_frac_secs(); - ) + *frac_secs_out = time_spec_cpp.get_frac_secs();) } uhd_error uhd_async_metadata_event_code( - uhd_async_metadata_handle h, - uhd_async_metadata_event_code_t *event_code_out -){ + uhd_async_metadata_handle h, uhd_async_metadata_event_code_t* event_code_out) +{ UHD_SAFE_C_SAVE_ERROR(h, - *event_code_out = uhd_async_metadata_event_code_t(h->async_metadata_cpp.event_code); - ) + *event_code_out = uhd_async_metadata_event_code_t( + h->async_metadata_cpp.event_code);) } uhd_error uhd_async_metadata_user_payload( - uhd_async_metadata_handle h, - uint32_t user_payload_out[4] -){ - UHD_SAFE_C_SAVE_ERROR(h, - memcpy(user_payload_out, h->async_metadata_cpp.user_payload, 4*sizeof(uint32_t)); - ) + uhd_async_metadata_handle h, uint32_t user_payload_out[4]) +{ + UHD_SAFE_C_SAVE_ERROR( + h, + memcpy( + user_payload_out, h->async_metadata_cpp.user_payload, 4 * sizeof(uint32_t));) } uhd_error uhd_async_metadata_last_error( - uhd_async_metadata_handle h, - char* error_out, - size_t strbuffer_len -){ - UHD_SAFE_C( - memset(error_out, '\0', strbuffer_len); - strncpy(error_out, h->last_error.c_str(), strbuffer_len); - ) + uhd_async_metadata_handle h, char* error_out, size_t strbuffer_len) +{ + UHD_SAFE_C(memset(error_out, '\0', strbuffer_len); + strncpy(error_out, h->last_error.c_str(), strbuffer_len);) } diff --git a/host/lib/types/metadata_python.hpp b/host/lib/types/metadata_python.hpp index f57d82dc9..6f7e1b159 100644 --- a/host/lib/types/metadata_python.hpp +++ b/host/lib/types/metadata_python.hpp @@ -12,23 +12,22 @@ void export_metadata(py::module& m) { - using range_t = uhd::range_t; - using meta_range_t = uhd::meta_range_t; - using rx_metadata_t = uhd::rx_metadata_t; - using error_code_t = rx_metadata_t::error_code_t; - using tx_metadata_t = uhd::tx_metadata_t; + using range_t = uhd::range_t; + using meta_range_t = uhd::meta_range_t; + using rx_metadata_t = uhd::rx_metadata_t; + using error_code_t = rx_metadata_t::error_code_t; + using tx_metadata_t = uhd::tx_metadata_t; using async_metadata_t = uhd::async_metadata_t; - using event_code_t = async_metadata_t::event_code_t; + using event_code_t = async_metadata_t::event_code_t; py::enum_<error_code_t>(m, "rx_metadata_error_code") - .value("none" , error_code_t::ERROR_CODE_NONE ) - .value("timeout" , error_code_t::ERROR_CODE_TIMEOUT ) - .value("late" , error_code_t::ERROR_CODE_LATE_COMMAND) + .value("none", error_code_t::ERROR_CODE_NONE) + .value("timeout", error_code_t::ERROR_CODE_TIMEOUT) + .value("late", error_code_t::ERROR_CODE_LATE_COMMAND) .value("broken_chain", error_code_t::ERROR_CODE_BROKEN_CHAIN) - .value("overflow" , error_code_t::ERROR_CODE_OVERFLOW ) - .value("alignment" , error_code_t::ERROR_CODE_ALIGNMENT ) - .value("bad_packet" , error_code_t::ERROR_CODE_BAD_PACKET ) - ; + .value("overflow", error_code_t::ERROR_CODE_OVERFLOW) + .value("alignment", error_code_t::ERROR_CODE_ALIGNMENT) + .value("bad_packet", error_code_t::ERROR_CODE_BAD_PACKET); py::class_<range_t>(m, "range") // Constructors @@ -37,11 +36,10 @@ void export_metadata(py::module& m) .def(py::init<double, double, double>()) // Methods - .def("start" , &range_t::start ) - .def("stop" , &range_t::stop ) - .def("step" , &range_t::step ) - .def("__str__", &range_t::to_pp_string) - ; + .def("start", &range_t::start) + .def("stop", &range_t::stop) + .def("step", &range_t::step) + .def("__str__", &range_t::to_pp_string); py::class_<meta_range_t>(m, "meta_range_t") // Constructors @@ -50,60 +48,56 @@ void export_metadata(py::module& m) .def(py::init<double, double, double>()) // Methods - .def("start" , &meta_range_t::start ) - .def("stop" , &meta_range_t::stop ) - .def("step" , &meta_range_t::step ) - .def("clip" , &meta_range_t::clip, py::arg("value"), py::arg("clip_step") = false) - .def("__str__", &meta_range_t::to_pp_string) - ; + .def("start", &meta_range_t::start) + .def("stop", &meta_range_t::stop) + .def("step", &meta_range_t::step) + .def("clip", &meta_range_t::clip, py::arg("value"), py::arg("clip_step") = false) + .def("__str__", &meta_range_t::to_pp_string); py::class_<rx_metadata_t>(m, "rx_metadata") .def(py::init<>()) // Methods - .def("reset" , &rx_metadata_t::reset ) + .def("reset", &rx_metadata_t::reset) .def("to_pp_string", &rx_metadata_t::to_pp_string) - .def("strerror" , &rx_metadata_t::strerror ) - .def("__str__" , &rx_metadata_t::to_pp_string, py::arg("compact") = false) + .def("strerror", &rx_metadata_t::strerror) + .def("__str__", &rx_metadata_t::to_pp_string, py::arg("compact") = false) // Properties - .def_readonly("has_time_spec" , &rx_metadata_t::has_time_spec ) - .def_readonly("time_spec" , &rx_metadata_t::time_spec ) - .def_readonly("more_fragments" , &rx_metadata_t::more_fragments ) - .def_readonly("start_of_burst" , &rx_metadata_t::start_of_burst ) - .def_readonly("end_of_burst" , &rx_metadata_t::end_of_burst ) - .def_readonly("error_code" , &rx_metadata_t::error_code ) - .def_readonly("out_of_sequence", &rx_metadata_t::out_of_sequence) - ; + .def_readonly("has_time_spec", &rx_metadata_t::has_time_spec) + .def_readonly("time_spec", &rx_metadata_t::time_spec) + .def_readonly("more_fragments", &rx_metadata_t::more_fragments) + .def_readonly("start_of_burst", &rx_metadata_t::start_of_burst) + .def_readonly("end_of_burst", &rx_metadata_t::end_of_burst) + .def_readonly("error_code", &rx_metadata_t::error_code) + .def_readonly("out_of_sequence", &rx_metadata_t::out_of_sequence); py::class_<tx_metadata_t>(m, "tx_metadata") .def(py::init<>()) // Properties - .def_readwrite("has_time_spec" , &tx_metadata_t::has_time_spec ) - .def_readwrite("time_spec" , &tx_metadata_t::time_spec ) + .def_readwrite("has_time_spec", &tx_metadata_t::has_time_spec) + .def_readwrite("time_spec", &tx_metadata_t::time_spec) .def_readwrite("start_of_burst", &tx_metadata_t::start_of_burst) - .def_readwrite("end_of_burst" , &tx_metadata_t::end_of_burst ) - ; + .def_readwrite("end_of_burst", &tx_metadata_t::end_of_burst); py::enum_<event_code_t>(m, "tx_metadata_event_code") - .value("burst_ack" , event_code_t::EVENT_CODE_BURST_ACK ) - .value("underflow" , event_code_t::EVENT_CODE_UNDERFLOW ) - .value("seq_error" , event_code_t::EVENT_CODE_SEQ_ERROR ) - .value("time_error" , event_code_t::EVENT_CODE_TIME_ERROR ) + .value("burst_ack", event_code_t::EVENT_CODE_BURST_ACK) + .value("underflow", event_code_t::EVENT_CODE_UNDERFLOW) + .value("seq_error", event_code_t::EVENT_CODE_SEQ_ERROR) + .value("time_error", event_code_t::EVENT_CODE_TIME_ERROR) .value("underflow_in_packet", event_code_t::EVENT_CODE_UNDERFLOW_IN_PACKET) - .value("seq_error_in_packet", event_code_t::EVENT_CODE_SEQ_ERROR_IN_BURST ) - .value("user_payload" , event_code_t::EVENT_CODE_USER_PAYLOAD ) - ; + .value("seq_error_in_packet", event_code_t::EVENT_CODE_SEQ_ERROR_IN_BURST) + .value("user_payload", event_code_t::EVENT_CODE_USER_PAYLOAD); py::class_<async_metadata_t>(m, "async_metadata") .def(py::init<>()) // Properties - .def_readonly("channel" , &async_metadata_t::channel ) + .def_readonly("channel", &async_metadata_t::channel) .def_readonly("has_time_spec", &async_metadata_t::has_time_spec) - .def_readonly("time_spec" , &async_metadata_t::time_spec ) - .def_readonly("event_code" , &async_metadata_t::event_code ) + .def_readonly("time_spec", &async_metadata_t::time_spec) + .def_readonly("event_code", &async_metadata_t::event_code) // TODO: Expose user payloads //.def_readonly("user_payload" , &async_metadata_t::user_payload ) ; diff --git a/host/lib/types/ranges.cpp b/host/lib/types/ranges.cpp index 3b452aee5..f7fbc0f92 100644 --- a/host/lib/types/ranges.cpp +++ b/host/lib/types/ranges.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/types/ranges.hpp> #include <uhd/exception.hpp> +#include <uhd/types/ranges.hpp> #include <boost/math/special_functions/round.hpp> #include <algorithm> #include <sstream> @@ -16,139 +16,151 @@ using namespace uhd; /*********************************************************************** * range_t implementation code **********************************************************************/ -range_t::range_t(double value): - _start(value), _stop(value), _step(0.0) +range_t::range_t(double value) : _start(value), _stop(value), _step(0.0) { /* NOP */ } -range_t::range_t( - double start, double stop, double step -): - _start(start), _stop(stop), _step(step) +range_t::range_t(double start, double stop, double step) + : _start(start), _stop(stop), _step(step) { - if (stop < start){ + if (stop < start) { throw uhd::value_error("cannot make range where stop < start"); } } -double range_t::start(void) const{ +double range_t::start(void) const +{ return _start; } -double range_t::stop(void) const{ +double range_t::stop(void) const +{ return _stop; } -double range_t::step(void) const{ +double range_t::step(void) const +{ return _step; } -const std::string range_t::to_pp_string(void) const{ +const std::string range_t::to_pp_string(void) const +{ std::stringstream ss; ss << "(" << this->start(); - if (this->start() != this->stop()) ss << ", " << this->stop(); - if (this->step() != 0) ss << ", " << this->step(); + if (this->start() != this->stop()) + ss << ", " << this->stop(); + if (this->step() != 0) + ss << ", " << this->step(); ss << ")"; return ss.str(); } -bool range_t::operator==(const range_t &other) const{ - return (other._start == _start and - other._step == _step and - other._stop == _stop); +bool range_t::operator==(const range_t& other) const +{ + return (other._start == _start and other._step == _step and other._stop == _stop); } -bool range_t::operator!=(const range_t &other) const{ - return (other._start != _start or - other._step != _step or - other._stop != _stop); +bool range_t::operator!=(const range_t& other) const +{ + return (other._start != _start or other._step != _step or other._stop != _stop); } /*********************************************************************** * meta_range_t implementation code **********************************************************************/ -void check_meta_range_monotonic(const meta_range_t &mr){ - if (mr.empty()){ +void check_meta_range_monotonic(const meta_range_t& mr) +{ + if (mr.empty()) { throw uhd::value_error("meta-range cannot be empty"); } - for (size_t i = 1; i < mr.size(); i++){ - if (mr.at(i).start() < mr.at(i-1).stop()){ + for (size_t i = 1; i < mr.size(); i++) { + if (mr.at(i).start() < mr.at(i - 1).stop()) { throw uhd::value_error("meta-range is not monotonic"); } } } -meta_range_t::meta_range_t(void){ +meta_range_t::meta_range_t(void) +{ /* NOP */ } -meta_range_t::meta_range_t( - double start, double stop, double step -): - std::vector<range_t > (1, range_t(start, stop, step)) +meta_range_t::meta_range_t(double start, double stop, double step) + : std::vector<range_t>(1, range_t(start, stop, step)) { /* NOP */ } -double meta_range_t::start(void) const{ +double meta_range_t::start(void) const +{ check_meta_range_monotonic(*this); double min_start = this->front().start(); - for(const range_t &r: (*this)){ + for (const range_t& r : (*this)) { min_start = std::min(min_start, r.start()); } return min_start; } -double meta_range_t::stop(void) const{ +double meta_range_t::stop(void) const +{ check_meta_range_monotonic(*this); double max_stop = this->front().stop(); - for(const range_t &r: (*this)){ + for (const range_t& r : (*this)) { max_stop = std::max(max_stop, r.stop()); } return max_stop; } -double meta_range_t::step(void) const{ +double meta_range_t::step(void) const +{ check_meta_range_monotonic(*this); std::vector<double> non_zero_steps; range_t last = this->front(); - for(const range_t &r: (*this)){ - //steps at each range - if (r.step() > 0) non_zero_steps.push_back(r.step()); - //and steps in-between ranges + for (const range_t& r : (*this)) { + // steps at each range + if (r.step() > 0) + non_zero_steps.push_back(r.step()); + // and steps in-between ranges double ibtw_step = r.start() - last.stop(); - if (ibtw_step > 0) non_zero_steps.push_back(ibtw_step); - //store ref to last + if (ibtw_step > 0) + non_zero_steps.push_back(ibtw_step); + // store ref to last last = r; } - if (non_zero_steps.empty()) return 0; //all zero steps, its zero... + if (non_zero_steps.empty()) + return 0; // all zero steps, its zero... return *std::min_element(non_zero_steps.begin(), non_zero_steps.end()); } -double meta_range_t::clip(double value, bool clip_step) const{ +double meta_range_t::clip(double value, bool clip_step) const +{ check_meta_range_monotonic(*this); double last_stop = this->front().stop(); - for(const range_t &r: (*this)){ - //in-between ranges, clip to nearest - if (value < r.start()){ - return (std::abs(value - r.start()) < std::abs(value - last_stop))? - r.start() : last_stop; + for (const range_t& r : (*this)) { + // in-between ranges, clip to nearest + if (value < r.start()) { + return (std::abs(value - r.start()) < std::abs(value - last_stop)) + ? r.start() + : last_stop; } - //in this range, clip here - if (value <= r.stop()){ - if (not clip_step or r.step() == 0) return value; - return boost::math::round((value - r.start())/r.step())*r.step() + r.start(); + // in this range, clip here + if (value <= r.stop()) { + if (not clip_step or r.step() == 0) + return value; + return boost::math::round((value - r.start()) / r.step()) * r.step() + + r.start(); } - //continue on to the next range + // continue on to the next range last_stop = r.stop(); } return last_stop; } -const std::string meta_range_t::to_pp_string(void) const{ +const std::string meta_range_t::to_pp_string(void) const +{ std::stringstream ss; - for(const range_t &r: (*this)){ + for (const range_t& r : (*this)) { ss << r.to_pp_string() << std::endl; } return ss.str(); diff --git a/host/lib/types/ranges_c.cpp b/host/lib/types/ranges_c.cpp index 922955147..8b50e7ed8 100644 --- a/host/lib/types/ranges_c.cpp +++ b/host/lib/types/ranges_c.cpp @@ -6,147 +6,93 @@ // #include <uhd/types/ranges.h> - #include <string.h> /* * uhd::range_t */ uhd_error uhd_range_to_pp_string( - const uhd_range_t *range, - char* pp_string_out, - size_t strbuffer_len -){ - UHD_SAFE_C( - uhd::range_t range_cpp = uhd_range_c_to_cpp(range); - std::string pp_string_cpp = range_cpp.to_pp_string(); - - memset(pp_string_out, '\0', strbuffer_len); - strncpy(pp_string_out, pp_string_cpp.c_str(), strbuffer_len); - ) + const uhd_range_t* range, char* pp_string_out, size_t strbuffer_len) +{ + UHD_SAFE_C(uhd::range_t range_cpp = uhd_range_c_to_cpp(range); + std::string pp_string_cpp = range_cpp.to_pp_string(); + + memset(pp_string_out, '\0', strbuffer_len); + strncpy(pp_string_out, pp_string_cpp.c_str(), strbuffer_len);) } -uhd::range_t uhd_range_c_to_cpp( - const uhd_range_t *range_c -){ +uhd::range_t uhd_range_c_to_cpp(const uhd_range_t* range_c) +{ return uhd::range_t(range_c->start, range_c->stop, range_c->step); } -void uhd_range_cpp_to_c( - const uhd::range_t &range_cpp, - uhd_range_t *range_c -){ +void uhd_range_cpp_to_c(const uhd::range_t& range_cpp, uhd_range_t* range_c) +{ range_c->start = range_cpp.start(); - range_c->stop = range_cpp.stop(); - range_c->step = range_cpp.step(); + range_c->stop = range_cpp.stop(); + range_c->step = range_cpp.step(); } /* * uhd::meta_range_t */ -uhd_error uhd_meta_range_make( - uhd_meta_range_handle* h -){ - UHD_SAFE_C( - (*h) = new uhd_meta_range_t; - ) +uhd_error uhd_meta_range_make(uhd_meta_range_handle* h) +{ + UHD_SAFE_C((*h) = new uhd_meta_range_t;) } -uhd_error uhd_meta_range_free( - uhd_meta_range_handle* h -){ - UHD_SAFE_C( - delete (*h); - (*h) = NULL; - ) +uhd_error uhd_meta_range_free(uhd_meta_range_handle* h) +{ + UHD_SAFE_C(delete (*h); (*h) = NULL;) } -uhd_error uhd_meta_range_start( - uhd_meta_range_handle h, - double *start_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *start_out = h->meta_range_cpp.start(); - ) +uhd_error uhd_meta_range_start(uhd_meta_range_handle h, double* start_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *start_out = h->meta_range_cpp.start();) } -uhd_error uhd_meta_range_stop( - uhd_meta_range_handle h, - double *stop_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *stop_out = h->meta_range_cpp.stop(); - ) +uhd_error uhd_meta_range_stop(uhd_meta_range_handle h, double* stop_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *stop_out = h->meta_range_cpp.stop();) } -uhd_error uhd_meta_range_step( - uhd_meta_range_handle h, - double *step_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *step_out = h->meta_range_cpp.step(); - ) +uhd_error uhd_meta_range_step(uhd_meta_range_handle h, double* step_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *step_out = h->meta_range_cpp.step();) } uhd_error uhd_meta_range_clip( - uhd_meta_range_handle h, - double value, - bool clip_step, - double *result_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *result_out = h->meta_range_cpp.clip(value, clip_step); - ) + uhd_meta_range_handle h, double value, bool clip_step, double* result_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *result_out = h->meta_range_cpp.clip(value, clip_step);) } -uhd_error uhd_meta_range_size( - uhd_meta_range_handle h, - size_t *size_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *size_out = h->meta_range_cpp.size(); - ) +uhd_error uhd_meta_range_size(uhd_meta_range_handle h, size_t* size_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *size_out = h->meta_range_cpp.size();) } -uhd_error uhd_meta_range_push_back( - uhd_meta_range_handle h, - const uhd_range_t *range -){ - UHD_SAFE_C_SAVE_ERROR(h, - h->meta_range_cpp.push_back(uhd_range_c_to_cpp(range)); - ) +uhd_error uhd_meta_range_push_back(uhd_meta_range_handle h, const uhd_range_t* range) +{ + UHD_SAFE_C_SAVE_ERROR(h, h->meta_range_cpp.push_back(uhd_range_c_to_cpp(range));) } -uhd_error uhd_meta_range_at( - uhd_meta_range_handle h, - size_t num, - uhd_range_t *range_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd_range_cpp_to_c(h->meta_range_cpp.at(num), - range_out); - ) +uhd_error uhd_meta_range_at(uhd_meta_range_handle h, size_t num, uhd_range_t* range_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, uhd_range_cpp_to_c(h->meta_range_cpp.at(num), range_out);) } uhd_error uhd_meta_range_to_pp_string( - uhd_meta_range_handle h, - char* pp_string_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string pp_string_cpp = h->meta_range_cpp.to_pp_string(); - memset(pp_string_out, '\0', strbuffer_len); - strncpy(pp_string_out, pp_string_cpp.c_str(), strbuffer_len); - ) + uhd_meta_range_handle h, char* pp_string_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR(h, std::string pp_string_cpp = h->meta_range_cpp.to_pp_string(); + memset(pp_string_out, '\0', strbuffer_len); + strncpy(pp_string_out, pp_string_cpp.c_str(), strbuffer_len);) } uhd_error uhd_meta_range_last_error( - uhd_meta_range_handle h, - char* error_out, - size_t strbuffer_len -){ - UHD_SAFE_C( - memset(error_out, '\0', strbuffer_len); - strncpy(error_out, h->last_error.c_str(), strbuffer_len); - ) + uhd_meta_range_handle h, char* error_out, size_t strbuffer_len) +{ + UHD_SAFE_C(memset(error_out, '\0', strbuffer_len); + strncpy(error_out, h->last_error.c_str(), strbuffer_len);) } diff --git a/host/lib/types/sensors.cpp b/host/lib/types/sensors.cpp index 982e02f05..07a90b6a4 100644 --- a/host/lib/types/sensors.cpp +++ b/host/lib/types/sensors.cpp @@ -5,62 +5,51 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/types/sensors.hpp> #include <uhd/exception.hpp> +#include <uhd/types/sensors.hpp> #include <boost/format.hpp> using namespace uhd; -sensor_value_t::sensor_value_t( - const std::string &name, +sensor_value_t::sensor_value_t(const std::string& name, bool value, - const std::string &utrue, - const std::string &ufalse -): - name(name), value(value?"true":"false"), - unit(value?utrue:ufalse), type(BOOLEAN) + const std::string& utrue, + const std::string& ufalse) + : name(name) + , value(value ? "true" : "false") + , unit(value ? utrue : ufalse) + , type(BOOLEAN) { /* NOP */ } -sensor_value_t::sensor_value_t( - const std::string &name, +sensor_value_t::sensor_value_t(const std::string& name, signed value, - const std::string &unit, - const std::string &formatter -): - name(name), value(str(boost::format(formatter) % value)), - unit(unit), type(INTEGER) + const std::string& unit, + const std::string& formatter) + : name(name), value(str(boost::format(formatter) % value)), unit(unit), type(INTEGER) { /* NOP */ } -sensor_value_t::sensor_value_t( - const std::string &name, +sensor_value_t::sensor_value_t(const std::string& name, double value, - const std::string &unit, - const std::string &formatter -): - name(name), value(str(boost::format(formatter) % value)), - unit(unit), type(REALNUM) + const std::string& unit, + const std::string& formatter) + : name(name), value(str(boost::format(formatter) % value)), unit(unit), type(REALNUM) { /* NOP */ } sensor_value_t::sensor_value_t( - const std::string &name, - const std::string &value, - const std::string &unit -): - name(name), value(value), - unit(unit), type(STRING) + const std::string& name, const std::string& value, const std::string& unit) + : name(name), value(value), unit(unit), type(STRING) { /* NOP */ } -static sensor_value_t::data_type_t _string_to_type( - const std::string &type_str -) { +static sensor_value_t::data_type_t _string_to_type(const std::string& type_str) +{ if (type_str == "STRING") { return sensor_value_t::STRING; } else if (type_str == "REALNUM") { @@ -70,15 +59,12 @@ static sensor_value_t::data_type_t _string_to_type( } else if (type_str == "BOOLEAN") { return sensor_value_t::BOOLEAN; } else { - throw uhd::value_error( - std::string("Invalid sensor value type: ") + type_str - ); + throw uhd::value_error(std::string("Invalid sensor value type: ") + type_str); } } -static std::string _type_to_string( - const sensor_value_t::data_type_t &type -) { +static std::string _type_to_string(const sensor_value_t::data_type_t& type) +{ if (type == sensor_value_t::STRING) { return "STRING"; } else if (type == sensor_value_t::REALNUM) { @@ -88,19 +74,15 @@ static std::string _type_to_string( } else if (type == sensor_value_t::BOOLEAN) { return "BOOLEAN"; } else { - throw uhd::value_error( - std::string("Invalid raw sensor value type.") - ); + throw uhd::value_error(std::string("Invalid raw sensor value type.")); } } -sensor_value_t::sensor_value_t( - const std::map<std::string, std::string> &sensor_dict -): - name(sensor_dict.at("name")), - value(sensor_dict.at("value")), - unit(sensor_dict.at("unit")), - type(_string_to_type(sensor_dict.at("type"))) +sensor_value_t::sensor_value_t(const std::map<std::string, std::string>& sensor_dict) + : name(sensor_dict.at("name")) + , value(sensor_dict.at("value")) + , unit(sensor_dict.at("unit")) + , type(_string_to_type(sensor_dict.at("type"))) { UHD_ASSERT_THROW(not name.empty()); UHD_ASSERT_THROW(not value.empty()); @@ -110,20 +92,14 @@ sensor_value_t::sensor_value_t( } else if (type == REALNUM) { to_real(); } - } - catch (const std::invalid_argument&) { - throw uhd::value_error(str( - boost::format("Could not convert sensor value `%s' to type `%s'") - % value - % sensor_dict.at("type") - )); - } - catch (const std::out_of_range&) { - throw uhd::value_error(str( - boost::format("Could not convert sensor value `%s' to type `%s'") - % value - % sensor_dict.at("type") - )); + } catch (const std::invalid_argument&) { + throw uhd::value_error( + str(boost::format("Could not convert sensor value `%s' to type `%s'") % value + % sensor_dict.at("type"))); + } catch (const std::out_of_range&) { + throw uhd::value_error( + str(boost::format("Could not convert sensor value `%s' to type `%s'") % value + % sensor_dict.at("type"))); } } @@ -133,44 +109,49 @@ sensor_value_t::sensor_value_t(const sensor_value_t& source) } -std::string sensor_value_t::to_pp_string(void) const{ - switch(type){ - case BOOLEAN: - return str(boost::format("%s: %s") % name % unit); - case INTEGER: - case REALNUM: - case STRING: - return str(boost::format("%s: %s %s") % name % value % unit); +std::string sensor_value_t::to_pp_string(void) const +{ + switch (type) { + case BOOLEAN: + return str(boost::format("%s: %s") % name % unit); + case INTEGER: + case REALNUM: + case STRING: + return str(boost::format("%s: %s %s") % name % value % unit); } UHD_THROW_INVALID_CODE_PATH(); } -bool sensor_value_t::to_bool(void) const{ +bool sensor_value_t::to_bool(void) const +{ return value == "true"; } -signed sensor_value_t::to_int(void) const{ +signed sensor_value_t::to_int(void) const +{ return std::stoi(value); } -double sensor_value_t::to_real(void) const{ +double sensor_value_t::to_real(void) const +{ return std::stod(value); } -sensor_value_t::sensor_map_t sensor_value_t::to_map(void) const{ +sensor_value_t::sensor_map_t sensor_value_t::to_map(void) const +{ sensor_map_t ret_map; - ret_map["name"] = name; + ret_map["name"] = name; ret_map["value"] = value; - ret_map["unit"] = unit; - ret_map["type"] = _type_to_string(type); + ret_map["unit"] = unit; + ret_map["type"] = _type_to_string(type); return ret_map; } sensor_value_t& sensor_value_t::operator=(const sensor_value_t& rhs) { - this->name = rhs.name; + this->name = rhs.name; this->value = rhs.value; - this->unit = rhs.unit; - this->type = rhs.type; + this->unit = rhs.unit; + this->type = rhs.type; return *this; } diff --git a/host/lib/types/sensors_c.cpp b/host/lib/types/sensors_c.cpp index 6ea3eadae..2932e9ec8 100644 --- a/host/lib/types/sensors_c.cpp +++ b/host/lib/types/sensors_c.cpp @@ -6,225 +6,152 @@ // #include <uhd/types/sensors.h> +#include <string.h> #include <stdexcept> #include <string> -#include <string.h> -uhd_error uhd_sensor_value_make( - uhd_sensor_value_handle* h -){ - try{ +uhd_error uhd_sensor_value_make(uhd_sensor_value_handle* h) +{ + try { *h = new uhd_sensor_value_t; - } - catch(...){ + } catch (...) { return UHD_ERROR_UNKNOWN; } - UHD_SAFE_C_SAVE_ERROR((*h), - (*h)->sensor_value_cpp = new uhd::sensor_value_t("", false, "", ""); - ) + UHD_SAFE_C_SAVE_ERROR( + (*h), (*h)->sensor_value_cpp = new uhd::sensor_value_t("", false, "", "");) } -uhd_error uhd_sensor_value_make_from_bool( - uhd_sensor_value_handle* h, +uhd_error uhd_sensor_value_make_from_bool(uhd_sensor_value_handle* h, const char* name, bool value, const char* utrue, - const char* ufalse -){ - try{ + const char* ufalse) +{ + try { *h = new uhd_sensor_value_t; - } - catch(...){ + } catch (...) { return UHD_ERROR_UNKNOWN; } - UHD_SAFE_C_SAVE_ERROR((*h), - (*h)->sensor_value_cpp = new uhd::sensor_value_t(name, - value, - utrue, - ufalse); - ) + UHD_SAFE_C_SAVE_ERROR( + (*h), + (*h)->sensor_value_cpp = new uhd::sensor_value_t(name, value, utrue, ufalse);) } -uhd_error uhd_sensor_value_make_from_int( - uhd_sensor_value_handle* h, +uhd_error uhd_sensor_value_make_from_int(uhd_sensor_value_handle* h, const char* name, int value, const char* unit, - const char* formatter -){ - try{ + const char* formatter) +{ + try { *h = new uhd_sensor_value_t; - } - catch(...){ + } catch (...) { return UHD_ERROR_UNKNOWN; } - UHD_SAFE_C_SAVE_ERROR((*h), - std::string fmt(formatter); - if(fmt.empty()){ - (*h)->sensor_value_cpp = new uhd::sensor_value_t(name, - value, - unit); - } - else{ - (*h)->sensor_value_cpp = new uhd::sensor_value_t(name, - value, - unit, - fmt); - } - ) -} - -uhd_error uhd_sensor_value_make_from_realnum( - uhd_sensor_value_handle* h, + UHD_SAFE_C_SAVE_ERROR( + (*h), std::string fmt(formatter); if (fmt.empty()) { + (*h)->sensor_value_cpp = new uhd::sensor_value_t(name, value, unit); + } else { + (*h)->sensor_value_cpp = new uhd::sensor_value_t(name, value, unit, fmt); + }) +} + +uhd_error uhd_sensor_value_make_from_realnum(uhd_sensor_value_handle* h, const char* name, double value, const char* unit, - const char* formatter -){ - try{ + const char* formatter) +{ + try { *h = new uhd_sensor_value_t; - } - catch(...){ + } catch (...) { return UHD_ERROR_UNKNOWN; } - UHD_SAFE_C_SAVE_ERROR((*h), - std::string fmt(formatter); - if(fmt.empty()){ - (*h)->sensor_value_cpp = new uhd::sensor_value_t(name, - value, - unit); - } - else{ - (*h)->sensor_value_cpp = new uhd::sensor_value_t(name, - value, - unit, - fmt); - } - ) + UHD_SAFE_C_SAVE_ERROR( + (*h), std::string fmt(formatter); if (fmt.empty()) { + (*h)->sensor_value_cpp = new uhd::sensor_value_t(name, value, unit); + } else { + (*h)->sensor_value_cpp = new uhd::sensor_value_t(name, value, unit, fmt); + }) } uhd_error uhd_sensor_value_make_from_string( - uhd_sensor_value_handle* h, - const char* name, - const char* value, - const char* unit -){ - try{ + uhd_sensor_value_handle* h, const char* name, const char* value, const char* unit) +{ + try { *h = new uhd_sensor_value_t; - } - catch(...){ + } catch (...) { return UHD_ERROR_UNKNOWN; } - UHD_SAFE_C_SAVE_ERROR((*h), - (*h)->sensor_value_cpp = new uhd::sensor_value_t(name, - value, - unit); - ) + UHD_SAFE_C_SAVE_ERROR( + (*h), (*h)->sensor_value_cpp = new uhd::sensor_value_t(name, value, unit);) } -uhd_error uhd_sensor_value_free( - uhd_sensor_value_handle *h -){ - UHD_SAFE_C( - delete (*h)->sensor_value_cpp; - delete *h; - *h = NULL; - ) +uhd_error uhd_sensor_value_free(uhd_sensor_value_handle* h) +{ + UHD_SAFE_C(delete (*h)->sensor_value_cpp; delete *h; *h = NULL;) } -uhd_error uhd_sensor_value_to_bool( - uhd_sensor_value_handle h, - bool *value_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *value_out = h->sensor_value_cpp->to_bool(); - ) +uhd_error uhd_sensor_value_to_bool(uhd_sensor_value_handle h, bool* value_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *value_out = h->sensor_value_cpp->to_bool();) } -uhd_error uhd_sensor_value_to_int( - uhd_sensor_value_handle h, - int *value_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *value_out = h->sensor_value_cpp->to_int(); - ) +uhd_error uhd_sensor_value_to_int(uhd_sensor_value_handle h, int* value_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *value_out = h->sensor_value_cpp->to_int();) } -uhd_error uhd_sensor_value_to_realnum( - uhd_sensor_value_handle h, - double *value_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *value_out = h->sensor_value_cpp->to_real(); - ) +uhd_error uhd_sensor_value_to_realnum(uhd_sensor_value_handle h, double* value_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *value_out = h->sensor_value_cpp->to_real();) } uhd_error uhd_sensor_value_name( - uhd_sensor_value_handle h, - char* name_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - memset(name_out, '\0', strbuffer_len); - strncpy(name_out, h->sensor_value_cpp->name.c_str(), strbuffer_len); - ) + uhd_sensor_value_handle h, char* name_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR(h, memset(name_out, '\0', strbuffer_len); strncpy( + name_out, h->sensor_value_cpp->name.c_str(), strbuffer_len);) } uhd_error uhd_sensor_value_value( - uhd_sensor_value_handle h, - char* value_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - memset(value_out, '\0', strbuffer_len); - strncpy(value_out, h->sensor_value_cpp->value.c_str(), strbuffer_len); - ) + uhd_sensor_value_handle h, char* value_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR(h, memset(value_out, '\0', strbuffer_len); strncpy( + value_out, h->sensor_value_cpp->value.c_str(), strbuffer_len);) } uhd_error uhd_sensor_value_unit( - uhd_sensor_value_handle h, - char* unit_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - memset(unit_out, '\0', strbuffer_len); - strncpy(unit_out, h->sensor_value_cpp->unit.c_str(), strbuffer_len); - ) + uhd_sensor_value_handle h, char* unit_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR(h, memset(unit_out, '\0', strbuffer_len); strncpy( + unit_out, h->sensor_value_cpp->unit.c_str(), strbuffer_len);) } uhd_error uhd_sensor_value_data_type( - uhd_sensor_value_handle h, - uhd_sensor_value_data_type_t *data_type_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *data_type_out = uhd_sensor_value_data_type_t(h->sensor_value_cpp->type); - ) + uhd_sensor_value_handle h, uhd_sensor_value_data_type_t* data_type_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, *data_type_out = uhd_sensor_value_data_type_t(h->sensor_value_cpp->type);) } uhd_error uhd_sensor_value_to_pp_string( - uhd_sensor_value_handle h, - char* pp_string_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string pp_string_cpp = h->sensor_value_cpp->to_pp_string(); + uhd_sensor_value_handle h, char* pp_string_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR( + h, std::string pp_string_cpp = h->sensor_value_cpp->to_pp_string(); memset(pp_string_out, '\0', strbuffer_len); - strncpy(pp_string_out, pp_string_cpp.c_str(), strbuffer_len); - ) + strncpy(pp_string_out, pp_string_cpp.c_str(), strbuffer_len);) } uhd_error uhd_sensor_value_last_error( - uhd_sensor_value_handle h, - char* error_out, - size_t strbuffer_len -){ - UHD_SAFE_C( - memset(error_out, '\0', strbuffer_len); - strncpy(error_out, h->last_error.c_str(), strbuffer_len); - ) + uhd_sensor_value_handle h, char* error_out, size_t strbuffer_len) +{ + UHD_SAFE_C(memset(error_out, '\0', strbuffer_len); + strncpy(error_out, h->last_error.c_str(), strbuffer_len);) } diff --git a/host/lib/types/sensors_python.hpp b/host/lib/types/sensors_python.hpp index e3937d117..f795214fd 100644 --- a/host/lib/types/sensors_python.hpp +++ b/host/lib/types/sensors_python.hpp @@ -19,28 +19,32 @@ void export_sensors(py::module& m) .value("b", data_type_t::BOOLEAN) .value("i", data_type_t::INTEGER) .value("r", data_type_t::REALNUM) - .value("s", data_type_t::STRING ) - ; + .value("s", data_type_t::STRING); py::class_<sensor_value_t>(m, "sensor_value") // Constructors .def(py::init<const std::string&, bool, const std::string&, const std::string&>()) - .def(py::init<const std::string&, signed, const std::string&, const std::string&>()) - .def(py::init<const std::string&, double, const std::string&, const std::string&>()) - .def(py::init<const std::string&, const std::string& , const std::string&>()) + .def(py::init<const std::string&, + signed, + const std::string&, + const std::string&>()) + .def(py::init<const std::string&, + double, + const std::string&, + const std::string&>()) + .def(py::init<const std::string&, const std::string&, const std::string&>()) // Methods - .def("to_bool", &sensor_value_t::to_bool ) - .def("to_int", &sensor_value_t::to_int ) - .def("to_real", &sensor_value_t::to_real ) + .def("to_bool", &sensor_value_t::to_bool) + .def("to_int", &sensor_value_t::to_int) + .def("to_real", &sensor_value_t::to_real) .def("__str__", &sensor_value_t::to_pp_string) // Properties - .def_readwrite("name", &sensor_value_t::name ) + .def_readwrite("name", &sensor_value_t::name) .def_readwrite("value", &sensor_value_t::value) - .def_readwrite("unit", &sensor_value_t::unit ) - .def_readwrite("type", &sensor_value_t::type ) - ; + .def_readwrite("unit", &sensor_value_t::unit) + .def_readwrite("type", &sensor_value_t::type); } #endif /* INCLUDED_UHD_SENSORS_PYTHON_HPP */ diff --git a/host/lib/types/serial.cpp b/host/lib/types/serial.cpp index 83f538f5e..e146b4c6c 100644 --- a/host/lib/types/serial.cpp +++ b/host/lib/types/serial.cpp @@ -14,52 +14,42 @@ using namespace uhd; i2c_iface::~i2c_iface(void) { - //empty + // empty } spi_iface::~spi_iface(void) { - //empty + // empty } uart_iface::~uart_iface(void) { - //empty + // empty } -spi_config_t::spi_config_t(edge_t edge): - mosi_edge(edge), - miso_edge(edge) +spi_config_t::spi_config_t(edge_t edge) : mosi_edge(edge), miso_edge(edge) { // By default don't use a custom clock speed for the transaction use_custom_divider = false; } -void i2c_iface::write_eeprom( - uint16_t addr, - uint16_t offset, - const byte_vector_t &bytes -){ - for (size_t i = 0; i < bytes.size(); i++){ - //write a byte at a time, its easy that way +void i2c_iface::write_eeprom(uint16_t addr, uint16_t offset, const byte_vector_t& bytes) +{ + for (size_t i = 0; i < bytes.size(); i++) { + // write a byte at a time, its easy that way byte_vector_t cmd = { - narrow_cast<uint8_t>(offset+i), - narrow_cast<uint8_t>(bytes[i]) - }; + narrow_cast<uint8_t>(offset + i), narrow_cast<uint8_t>(bytes[i])}; this->write_i2c(addr, cmd); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); //worst case write + std::this_thread::sleep_for(std::chrono::milliseconds(10)); // worst case write } } -byte_vector_t i2c_iface::read_eeprom( - uint16_t addr, - uint16_t offset, - size_t num_bytes -){ +byte_vector_t i2c_iface::read_eeprom(uint16_t addr, uint16_t offset, size_t num_bytes) +{ byte_vector_t bytes; - for (size_t i = 0; i < num_bytes; i++){ - //do a zero byte write to start read cycle - this->write_i2c(addr, byte_vector_t(1, narrow_cast<uint8_t>(offset+i))); + for (size_t i = 0; i < num_bytes; i++) { + // do a zero byte write to start read cycle + this->write_i2c(addr, byte_vector_t(1, narrow_cast<uint8_t>(offset + i))); bytes.push_back(this->read_i2c(addr, 1).at(0)); } return bytes; @@ -73,49 +63,35 @@ struct eeprom16_impl : i2c_iface } i2c_iface* _internal; - byte_vector_t read_i2c( - uint16_t addr, - size_t num_bytes - ){ + byte_vector_t read_i2c(uint16_t addr, size_t num_bytes) + { return _internal->read_i2c(addr, num_bytes); } - void write_i2c( - uint16_t addr, - const byte_vector_t &bytes - ){ + void write_i2c(uint16_t addr, const byte_vector_t& bytes) + { return _internal->write_i2c(addr, bytes); } - byte_vector_t read_eeprom( - uint16_t addr, - uint16_t offset, - size_t num_bytes - ){ + byte_vector_t read_eeprom(uint16_t addr, uint16_t offset, size_t num_bytes) + { byte_vector_t cmd = { - narrow_cast<uint8_t>(offset >> 8), - narrow_cast<uint8_t>(offset & 0xff) - }; + narrow_cast<uint8_t>(offset >> 8), narrow_cast<uint8_t>(offset & 0xff)}; this->write_i2c(addr, cmd); return this->read_i2c(addr, num_bytes); } - void write_eeprom( - uint16_t addr, - uint16_t offset, - const byte_vector_t &bytes - ){ - for (uint16_t i = 0; i < bytes.size(); i++) - { - //write a byte at a time, its easy that way - uint16_t offset_i = offset+i; - byte_vector_t cmd{ - narrow_cast<uint8_t>(offset_i >> 8), + void write_eeprom(uint16_t addr, uint16_t offset, const byte_vector_t& bytes) + { + for (uint16_t i = 0; i < bytes.size(); i++) { + // write a byte at a time, its easy that way + uint16_t offset_i = offset + i; + byte_vector_t cmd{narrow_cast<uint8_t>(offset_i >> 8), narrow_cast<uint8_t>(offset_i & 0xff), - bytes[i] - }; + bytes[i]}; this->write_i2c(addr, cmd); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); //worst case write + std::this_thread::sleep_for(std::chrono::milliseconds(10)); // worst case + // write } } }; @@ -126,23 +102,13 @@ i2c_iface::sptr i2c_iface::eeprom16(void) } uint32_t spi_iface::read_spi( - int which_slave, - const spi_config_t &config, - uint32_t data, - size_t num_bits -){ - return transact_spi( - which_slave, config, data, num_bits, true - ); + int which_slave, const spi_config_t& config, uint32_t data, size_t num_bits) +{ + return transact_spi(which_slave, config, data, num_bits, true); } void spi_iface::write_spi( - int which_slave, - const spi_config_t &config, - uint32_t data, - size_t num_bits -){ - transact_spi( - which_slave, config, data, num_bits, false - ); + int which_slave, const spi_config_t& config, uint32_t data, size_t num_bits) +{ + transact_spi(which_slave, config, data, num_bits, false); } diff --git a/host/lib/types/serial_python.hpp b/host/lib/types/serial_python.hpp index eb52472a5..7e1d14390 100644 --- a/host/lib/types/serial_python.hpp +++ b/host/lib/types/serial_python.hpp @@ -16,19 +16,17 @@ void export_spi_config(py::module& m) using spi_edge_t = spi_config_t::edge_t; py::enum_<spi_edge_t>(m, "spi_edge") - .value("EDGE_RISE" , spi_edge_t::EDGE_RISE) - .value("EDGE_FALL", spi_edge_t::EDGE_FALL) - ; + .value("EDGE_RISE", spi_edge_t::EDGE_RISE) + .value("EDGE_FALL", spi_edge_t::EDGE_FALL); py::class_<spi_config_t>(m, "spi_config") .def(py::init<spi_edge_t>()) // Properties - .def_readwrite("mosi_edge" , &spi_config_t::mosi_edge ) - .def_readwrite("miso_edge" , &spi_config_t::miso_edge ) + .def_readwrite("mosi_edge", &spi_config_t::mosi_edge) + .def_readwrite("miso_edge", &spi_config_t::miso_edge) .def_readwrite("use_custom_divider", &spi_config_t::use_custom_divider) - .def_readwrite("divider" , &spi_config_t::divider ) - ; + .def_readwrite("divider", &spi_config_t::divider); } #endif /* INCLUDED_UHD_SERIAL_PYTHON_HPP */ diff --git a/host/lib/types/string_vector_c.cpp b/host/lib/types/string_vector_c.cpp index cf5da529a..89288fb43 100644 --- a/host/lib/types/string_vector_c.cpp +++ b/host/lib/types/string_vector_c.cpp @@ -6,65 +6,40 @@ // #include <uhd/types/string_vector.h> - #include <string.h> -uhd_error uhd_string_vector_make( - uhd_string_vector_handle *h -){ - UHD_SAFE_C( - (*h) = new uhd_string_vector_t; - ) +uhd_error uhd_string_vector_make(uhd_string_vector_handle* h) +{ + UHD_SAFE_C((*h) = new uhd_string_vector_t;) } -uhd_error uhd_string_vector_free( - uhd_string_vector_handle *h -){ - UHD_SAFE_C( - delete (*h); - (*h) = NULL; - ) +uhd_error uhd_string_vector_free(uhd_string_vector_handle* h) +{ + UHD_SAFE_C(delete (*h); (*h) = NULL;) } -uhd_error uhd_string_vector_push_back( - uhd_string_vector_handle *h, - const char* value -){ - UHD_SAFE_C_SAVE_ERROR((*h), - (*h)->string_vector_cpp.push_back(value); - ) +uhd_error uhd_string_vector_push_back(uhd_string_vector_handle* h, const char* value) +{ + UHD_SAFE_C_SAVE_ERROR((*h), (*h)->string_vector_cpp.push_back(value);) } uhd_error uhd_string_vector_at( - uhd_string_vector_handle h, - size_t index, - char* value_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - memset(value_out, '\0', strbuffer_len); + uhd_string_vector_handle h, size_t index, char* value_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR(h, memset(value_out, '\0', strbuffer_len); - const std::string& value_cpp = h->string_vector_cpp.at(index); - strncpy(value_out, value_cpp.c_str(), strbuffer_len); - ) + const std::string& value_cpp = h->string_vector_cpp.at(index); + strncpy(value_out, value_cpp.c_str(), strbuffer_len);) } -uhd_error uhd_string_vector_size( - uhd_string_vector_handle h, - size_t *size_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *size_out = h->string_vector_cpp.size(); - ) +uhd_error uhd_string_vector_size(uhd_string_vector_handle h, size_t* size_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *size_out = h->string_vector_cpp.size();) } uhd_error uhd_string_vector_last_error( - uhd_string_vector_handle h, - char* error_out, - size_t strbuffer_len -){ - UHD_SAFE_C( - memset(error_out, '\0', strbuffer_len); - strncpy(error_out, h->last_error.c_str(), strbuffer_len); - ) + uhd_string_vector_handle h, char* error_out, size_t strbuffer_len) +{ + UHD_SAFE_C(memset(error_out, '\0', strbuffer_len); + strncpy(error_out, h->last_error.c_str(), strbuffer_len);) } diff --git a/host/lib/types/time_spec.cpp b/host/lib/types/time_spec.cpp index c07ab8525..bcccda140 100644 --- a/host/lib/types/time_spec.cpp +++ b/host/lib/types/time_spec.cpp @@ -6,119 +6,122 @@ // #include <uhd/types/time_spec.hpp> -#include <cmath> +#include <cmath> using namespace uhd; /*********************************************************************** * Time spec constructors **********************************************************************/ -#define time_spec_init(full, frac) { \ - const int64_t _full = int64_t(full); \ - const double _frac = double(frac); \ - const int _frac_int = int(_frac); \ - _full_secs = _full + _frac_int; \ - _frac_secs = _frac - _frac_int; \ - if (_frac_secs < 0) {\ - _full_secs -= 1; \ - _frac_secs += 1; \ - } \ -} - -UHD_INLINE long long fast_llround(const double x){ +#define time_spec_init(full, frac) \ + { \ + const int64_t _full = int64_t(full); \ + const double _frac = double(frac); \ + const int _frac_int = int(_frac); \ + _full_secs = _full + _frac_int; \ + _frac_secs = _frac - _frac_int; \ + if (_frac_secs < 0) { \ + _full_secs -= 1; \ + _frac_secs += 1; \ + } \ + } + +UHD_INLINE long long fast_llround(const double x) +{ return (long long)(x + 0.5); // assumption of non-negativity } -time_spec_t::time_spec_t(double secs){ +time_spec_t::time_spec_t(double secs) +{ time_spec_init(0, secs); } -time_spec_t::time_spec_t(int64_t full_secs, double frac_secs){ +time_spec_t::time_spec_t(int64_t full_secs, double frac_secs) +{ time_spec_init(full_secs, frac_secs); } -time_spec_t::time_spec_t(int64_t full_secs, long tick_count, double tick_rate){ - const double frac_secs = tick_count/tick_rate; +time_spec_t::time_spec_t(int64_t full_secs, long tick_count, double tick_rate) +{ + const double frac_secs = tick_count / tick_rate; time_spec_init(full_secs, frac_secs); } -time_spec_t time_spec_t::from_ticks(long long ticks, double tick_rate){ - const long long rate_i = (long long)(tick_rate); - const double rate_f = tick_rate - rate_i; - const int64_t secs_full = int64_t(ticks/rate_i); - const long long ticks_error = ticks - (secs_full*rate_i); - const double ticks_frac = ticks_error - secs_full*rate_f; - return time_spec_t(secs_full, ticks_frac/tick_rate); +time_spec_t time_spec_t::from_ticks(long long ticks, double tick_rate) +{ + const long long rate_i = (long long)(tick_rate); + const double rate_f = tick_rate - rate_i; + const int64_t secs_full = int64_t(ticks / rate_i); + const long long ticks_error = ticks - (secs_full * rate_i); + const double ticks_frac = ticks_error - secs_full * rate_f; + return time_spec_t(secs_full, ticks_frac / tick_rate); } /*********************************************************************** * Time spec accessors **********************************************************************/ -long time_spec_t::get_tick_count(double tick_rate) const{ - return long(fast_llround(this->get_frac_secs()*tick_rate)); +long time_spec_t::get_tick_count(double tick_rate) const +{ + return long(fast_llround(this->get_frac_secs() * tick_rate)); } -long long time_spec_t::to_ticks(double tick_rate) const{ - const long long rate_i = (long long)(tick_rate); - const double rate_f = tick_rate - rate_i; - const long long ticks_full = this->get_full_secs()*rate_i; - const double ticks_error = this->get_full_secs()*rate_f; - const double ticks_frac = this->get_frac_secs()*tick_rate; +long long time_spec_t::to_ticks(double tick_rate) const +{ + const long long rate_i = (long long)(tick_rate); + const double rate_f = tick_rate - rate_i; + const long long ticks_full = this->get_full_secs() * rate_i; + const double ticks_error = this->get_full_secs() * rate_f; + const double ticks_frac = this->get_frac_secs() * tick_rate; return ticks_full + fast_llround(ticks_error + ticks_frac); } -double time_spec_t::get_real_secs(void) const{ +double time_spec_t::get_real_secs(void) const +{ return this->get_full_secs() + this->get_frac_secs(); } /*********************************************************************** * Time spec math overloads **********************************************************************/ -time_spec_t &time_spec_t::operator+=(const time_spec_t &rhs){ - time_spec_init( - this->get_full_secs() + rhs.get_full_secs(), - this->get_frac_secs() + rhs.get_frac_secs() - ); +time_spec_t& time_spec_t::operator+=(const time_spec_t& rhs) +{ + time_spec_init(this->get_full_secs() + rhs.get_full_secs(), + this->get_frac_secs() + rhs.get_frac_secs()); return *this; } -time_spec_t &time_spec_t::operator+=(double &rhs){ +time_spec_t& time_spec_t::operator+=(double& rhs) +{ double full_secs = std::trunc(rhs); - time_spec_init( - this->get_full_secs() + full_secs, - this->get_frac_secs() + rhs - full_secs - ); + time_spec_init( + this->get_full_secs() + full_secs, this->get_frac_secs() + rhs - full_secs); return *this; } -time_spec_t &time_spec_t::operator-=(const time_spec_t &rhs){ - time_spec_init( - this->get_full_secs() - rhs.get_full_secs(), - this->get_frac_secs() - rhs.get_frac_secs() - ); +time_spec_t& time_spec_t::operator-=(const time_spec_t& rhs) +{ + time_spec_init(this->get_full_secs() - rhs.get_full_secs(), + this->get_frac_secs() - rhs.get_frac_secs()); return *this; } -time_spec_t &time_spec_t::operator-=(double &rhs) { +time_spec_t& time_spec_t::operator-=(double& rhs) +{ double full_secs = std::trunc(rhs); time_spec_init( - this->get_full_secs() - full_secs, - this->get_frac_secs() - (rhs - full_secs) - ); + this->get_full_secs() - full_secs, this->get_frac_secs() - (rhs - full_secs)); return *this; } -bool uhd::operator==(const time_spec_t &lhs, const time_spec_t &rhs){ - return - lhs.get_full_secs() == rhs.get_full_secs() and - lhs.get_frac_secs() == rhs.get_frac_secs() - ; +bool uhd::operator==(const time_spec_t& lhs, const time_spec_t& rhs) +{ + return lhs.get_full_secs() == rhs.get_full_secs() + and lhs.get_frac_secs() == rhs.get_frac_secs(); } -bool uhd::operator<(const time_spec_t &lhs, const time_spec_t &rhs){ - return ( - (lhs.get_full_secs() < rhs.get_full_secs()) or ( - (lhs.get_full_secs() == rhs.get_full_secs()) and - (lhs.get_frac_secs() < rhs.get_frac_secs()) - )); +bool uhd::operator<(const time_spec_t& lhs, const time_spec_t& rhs) +{ + return ((lhs.get_full_secs() < rhs.get_full_secs()) + or ((lhs.get_full_secs() == rhs.get_full_secs()) + and (lhs.get_frac_secs() < rhs.get_frac_secs()))); } diff --git a/host/lib/types/time_spec_python.hpp b/host/lib/types/time_spec_python.hpp index 3f87e9885..9deca822b 100644 --- a/host/lib/types/time_spec_python.hpp +++ b/host/lib/types/time_spec_python.hpp @@ -16,19 +16,19 @@ void export_time_spec(py::module& m) using time_spec_t = uhd::time_spec_t; py::class_<time_spec_t>(m, "time_spec") - //Additional constructors + // Additional constructors .def(py::init<double>()) .def(py::init<int64_t, double>()) .def(py::init<int64_t, long, double>()) // Methods - .def_static("from_ticks" , &time_spec_t::from_ticks) + .def_static("from_ticks", &time_spec_t::from_ticks) - .def("get_tick_count" , &time_spec_t::get_tick_count ) - .def("to_ticks" , &time_spec_t::to_ticks ) - .def("get_real_secs" , &time_spec_t::get_real_secs ) - .def("get_full_secs" , &time_spec_t::get_full_secs ) - .def("get_frac_secs" , &time_spec_t::get_frac_secs ) + .def("get_tick_count", &time_spec_t::get_tick_count) + .def("to_ticks", &time_spec_t::to_ticks) + .def("get_real_secs", &time_spec_t::get_real_secs) + .def("get_full_secs", &time_spec_t::get_full_secs) + .def("get_frac_secs", &time_spec_t::get_frac_secs) .def(py::self += time_spec_t()) .def(py::self -= time_spec_t()) @@ -37,8 +37,7 @@ void export_time_spec(py::module& m) .def(py::self += double()) .def(py::self -= double()) .def(py::self + double()) - .def(py::self - double()) - ; + .def(py::self - double()); } #endif /* INCLUDED_UHD_TIME_SPEC_PYTHON_HPP */ diff --git a/host/lib/types/tune.cpp b/host/lib/types/tune.cpp index eb504d1a3..9515fe7f1 100644 --- a/host/lib/types/tune.cpp +++ b/host/lib/types/tune.cpp @@ -11,35 +11,33 @@ using namespace uhd; -tune_request_t::tune_request_t(double target_freq): - target_freq(target_freq), - rf_freq_policy(POLICY_AUTO), - rf_freq(0.0), - dsp_freq_policy(POLICY_AUTO), - dsp_freq(0.0) +tune_request_t::tune_request_t(double target_freq) + : target_freq(target_freq) + , rf_freq_policy(POLICY_AUTO) + , rf_freq(0.0) + , dsp_freq_policy(POLICY_AUTO) + , dsp_freq(0.0) { /* NOP */ } -tune_request_t::tune_request_t(double target_freq, double lo_off): - target_freq(target_freq), - rf_freq_policy(POLICY_MANUAL), - rf_freq(target_freq + lo_off), - dsp_freq_policy(POLICY_AUTO), - dsp_freq(0.0) +tune_request_t::tune_request_t(double target_freq, double lo_off) + : target_freq(target_freq) + , rf_freq_policy(POLICY_MANUAL) + , rf_freq(target_freq + lo_off) + , dsp_freq_policy(POLICY_AUTO) + , dsp_freq(0.0) { /* NOP */ } -std::string tune_result_t::to_pp_string(void) const{ - return str(boost::format( - "Tune Result:\n" - " Target RF Freq: %f (MHz)\n" - " Actual RF Freq: %f (MHz)\n" - " Target DSP Freq: %f (MHz)\n" - " Actual DSP Freq: %f (MHz)\n" - ) - % (target_rf_freq/1e6) % (actual_rf_freq/1e6) - % (target_dsp_freq/1e6) % (actual_dsp_freq/1e6) - ); +std::string tune_result_t::to_pp_string(void) const +{ + return str(boost::format("Tune Result:\n" + " Target RF Freq: %f (MHz)\n" + " Actual RF Freq: %f (MHz)\n" + " Target DSP Freq: %f (MHz)\n" + " Actual DSP Freq: %f (MHz)\n") + % (target_rf_freq / 1e6) % (actual_rf_freq / 1e6) % (target_dsp_freq / 1e6) + % (actual_dsp_freq / 1e6)); } diff --git a/host/lib/types/tune_c.cpp b/host/lib/types/tune_c.cpp index db53e84ef..b91a5f9ed 100644 --- a/host/lib/types/tune_c.cpp +++ b/host/lib/types/tune_c.cpp @@ -7,9 +7,7 @@ #include <uhd/types/tune_request.h> #include <uhd/types/tune_result.h> - #include <boost/format.hpp> - #include <cstdlib> #include <cstring> #include <iostream> @@ -18,16 +16,20 @@ * Tune request */ -uhd::tune_request_t uhd_tune_request_c_to_cpp(uhd_tune_request_t *tune_request_c){ +uhd::tune_request_t uhd_tune_request_c_to_cpp(uhd_tune_request_t* tune_request_c) +{ uhd::tune_request_t tune_request_cpp; tune_request_cpp.target_freq = tune_request_c->target_freq; - tune_request_cpp.rf_freq_policy = uhd::tune_request_t::policy_t(tune_request_c->rf_freq_policy); + tune_request_cpp.rf_freq_policy = + uhd::tune_request_t::policy_t(tune_request_c->rf_freq_policy); tune_request_cpp.rf_freq = tune_request_c->rf_freq; - tune_request_cpp.dsp_freq_policy = uhd::tune_request_t::policy_t(tune_request_c->dsp_freq_policy); + tune_request_cpp.dsp_freq_policy = + uhd::tune_request_t::policy_t(tune_request_c->dsp_freq_policy); tune_request_cpp.dsp_freq = tune_request_c->dsp_freq; - std::string args_cpp = (tune_request_c->args) ? tune_request_c->args : std::string(""); + std::string args_cpp = (tune_request_c->args) ? tune_request_c->args + : std::string(""); tune_request_cpp.args = uhd::device_addr_t(args_cpp); return tune_request_cpp; @@ -37,30 +39,33 @@ uhd::tune_request_t uhd_tune_request_c_to_cpp(uhd_tune_request_t *tune_request_c * Tune result */ -void uhd_tune_result_to_pp_string(uhd_tune_result_t *tune_result_c, - char* pp_string_out, size_t strbuffer_len){ +void uhd_tune_result_to_pp_string( + uhd_tune_result_t* tune_result_c, char* pp_string_out, size_t strbuffer_len) +{ std::string pp_string_cpp = uhd_tune_result_c_to_cpp(tune_result_c).to_pp_string(); memset(pp_string_out, '\0', strbuffer_len); strncpy(pp_string_out, pp_string_cpp.c_str(), strbuffer_len); } -uhd::tune_result_t uhd_tune_result_c_to_cpp(uhd_tune_result_t *tune_result_c){ +uhd::tune_result_t uhd_tune_result_c_to_cpp(uhd_tune_result_t* tune_result_c) +{ uhd::tune_result_t tune_result_cpp; tune_result_cpp.clipped_rf_freq = tune_result_c->clipped_rf_freq; - tune_result_cpp.target_rf_freq = tune_result_c->target_rf_freq; - tune_result_cpp.actual_rf_freq = tune_result_c->actual_rf_freq; + tune_result_cpp.target_rf_freq = tune_result_c->target_rf_freq; + tune_result_cpp.actual_rf_freq = tune_result_c->actual_rf_freq; tune_result_cpp.target_dsp_freq = tune_result_c->target_dsp_freq; tune_result_cpp.actual_dsp_freq = tune_result_c->actual_dsp_freq; return tune_result_cpp; } -void uhd_tune_result_cpp_to_c(const uhd::tune_result_t &tune_result_cpp, - uhd_tune_result_t *tune_result_c){ +void uhd_tune_result_cpp_to_c( + const uhd::tune_result_t& tune_result_cpp, uhd_tune_result_t* tune_result_c) +{ tune_result_c->clipped_rf_freq = tune_result_cpp.clipped_rf_freq; - tune_result_c->target_rf_freq = tune_result_cpp.target_rf_freq; - tune_result_c->actual_rf_freq = tune_result_cpp.actual_rf_freq; + tune_result_c->target_rf_freq = tune_result_cpp.target_rf_freq; + tune_result_c->actual_rf_freq = tune_result_cpp.actual_rf_freq; tune_result_c->target_dsp_freq = tune_result_cpp.target_dsp_freq; tune_result_c->actual_dsp_freq = tune_result_cpp.actual_dsp_freq; } diff --git a/host/lib/types/tune_python.hpp b/host/lib/types/tune_python.hpp index d345b384c..75455e3d8 100644 --- a/host/lib/types/tune_python.hpp +++ b/host/lib/types/tune_python.hpp @@ -8,8 +8,8 @@ #ifndef INCLUDED_UHD_TUNE_PYTHON_HPP #define INCLUDED_UHD_TUNE_PYTHON_HPP -#include <uhd/types/tune_result.hpp> #include <uhd/types/tune_request.hpp> +#include <uhd/types/tune_result.hpp> void export_tune(py::module& m) { @@ -18,31 +18,28 @@ void export_tune(py::module& m) using policy_t = tune_request_t::policy_t; py::enum_<policy_t>(m, "tune_request_policy") - .value("none", tune_request_t::POLICY_NONE ) - .value("auto", tune_request_t::POLICY_AUTO ) - .value("manual", tune_request_t::POLICY_MANUAL) - ; + .value("none", tune_request_t::POLICY_NONE) + .value("auto", tune_request_t::POLICY_AUTO) + .value("manual", tune_request_t::POLICY_MANUAL); py::class_<tune_request_t>(m, "tune_request") .def(py::init<double, double>()) - .def(py::init<double>(), py::arg("target_freq")=0.0) - .def_readwrite("target_freq" , &tune_request_t::target_freq ) - .def_readwrite("rf_freq_policy" , &tune_request_t::rf_freq_policy ) + .def(py::init<double>(), py::arg("target_freq") = 0.0) + .def_readwrite("target_freq", &tune_request_t::target_freq) + .def_readwrite("rf_freq_policy", &tune_request_t::rf_freq_policy) .def_readwrite("dsp_freq_policy", &tune_request_t::dsp_freq_policy) - .def_readwrite("rf_freq" , &tune_request_t::rf_freq ) - .def_readwrite("dsp_freq" , &tune_request_t::dsp_freq ) - .def_readwrite("args" , &tune_request_t::args ) - ; + .def_readwrite("rf_freq", &tune_request_t::rf_freq) + .def_readwrite("dsp_freq", &tune_request_t::dsp_freq) + .def_readwrite("args", &tune_request_t::args); py::class_<tune_result_t>(m, "tune_result") .def(py::init<>()) .def_readwrite("clipped_rf_freq", &tune_result_t::clipped_rf_freq) - .def_readwrite("target_rf_freq" , &tune_result_t::target_rf_freq ) - .def_readwrite("actual_rf_freq" , &tune_result_t::actual_rf_freq ) + .def_readwrite("target_rf_freq", &tune_result_t::target_rf_freq) + .def_readwrite("actual_rf_freq", &tune_result_t::actual_rf_freq) .def_readwrite("target_dsp_freq", &tune_result_t::target_dsp_freq) .def_readwrite("actual_dsp_freq", &tune_result_t::actual_dsp_freq) - .def("__str__" , &tune_result_t::to_pp_string ) - ; + .def("__str__", &tune_result_t::to_pp_string); } #endif /* INCLUDED_UHD_TUNE_PYTHON_HPP */ diff --git a/host/lib/types/types.cpp b/host/lib/types/types.cpp index 7e947a4f8..df2a6d9b2 100644 --- a/host/lib/types/types.cpp +++ b/host/lib/types/types.cpp @@ -5,18 +5,16 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/types/stream_cmd.hpp> #include <uhd/types/metadata.hpp> +#include <uhd/types/stream_cmd.hpp> using namespace uhd; /*********************************************************************** * stream command **********************************************************************/ -stream_cmd_t::stream_cmd_t(const stream_mode_t &stream_mode): - stream_mode(stream_mode), - num_samps(0), - stream_now(true) +stream_cmd_t::stream_cmd_t(const stream_mode_t& stream_mode) + : stream_mode(stream_mode), num_samps(0), stream_now(true) { /* NOP */ } diff --git a/host/lib/types/types_python.hpp b/host/lib/types/types_python.hpp index b7003d7b0..0e5bd3cdc 100644 --- a/host/lib/types/types_python.hpp +++ b/host/lib/types/types_python.hpp @@ -8,33 +8,31 @@ #ifndef INCLUDED_UHD_TYPES_PYTHON_HPP #define INCLUDED_UHD_TYPES_PYTHON_HPP -#include <pybind11/stl.h> #include <uhd/types/device_addr.hpp> #include <uhd/types/stream_cmd.hpp> -#include <string> +#include <pybind11/stl.h> #include <map> +#include <string> void export_types(py::module& m) { using stream_cmd_t = uhd::stream_cmd_t; using stream_mode_t = stream_cmd_t::stream_mode_t; - using str_map = std::map<std::string, std::string>; + using str_map = std::map<std::string, std::string>; py::enum_<stream_mode_t>(m, "stream_mode") - .value("start_cont", stream_cmd_t::STREAM_MODE_START_CONTINUOUS ) - .value("stop_cont" , stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS ) - .value("num_done" , stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE) - .value("num_more" , stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE) - ; + .value("start_cont", stream_cmd_t::STREAM_MODE_START_CONTINUOUS) + .value("stop_cont", stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS) + .value("num_done", stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE) + .value("num_more", stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE); py::class_<stream_cmd_t>(m, "stream_cmd") .def(py::init<stream_cmd_t::stream_mode_t>()) // Properties - .def_readwrite("num_samps" , &stream_cmd_t::num_samps ) - .def_readwrite("time_spec" , &stream_cmd_t::time_spec ) - .def_readwrite("stream_now", &stream_cmd_t::stream_now) - ; + .def_readwrite("num_samps", &stream_cmd_t::num_samps) + .def_readwrite("time_spec", &stream_cmd_t::time_spec) + .def_readwrite("stream_now", &stream_cmd_t::stream_now); py::class_<uhd::device_addr_t>(m, "device_addr") // Constructors @@ -45,12 +43,10 @@ void export_types(py::module& m) // Methods .def("__str__", &uhd::device_addr_t::to_pp_string) .def("to_string", &uhd::device_addr_t::to_string) - .def("to_pp_string", &uhd::device_addr_t::to_pp_string) - ; + .def("to_pp_string", &uhd::device_addr_t::to_pp_string); // This will allow functions in Python that take a device_addr to also take // a string: py::implicitly_convertible<std::string, uhd::device_addr_t>(); - } #endif /* INCLUDED_UHD_TYPES_PYTHON_HPP */ diff --git a/host/lib/types/usrp_info_c.cpp b/host/lib/types/usrp_info_c.cpp index 841607be5..c5ad04f34 100644 --- a/host/lib/types/usrp_info_c.cpp +++ b/host/lib/types/usrp_info_c.cpp @@ -7,7 +7,8 @@ #include <uhd/types/usrp_info.h> -uhd_error uhd_usrp_rx_info_free(uhd_usrp_rx_info_t *rx_info){ +uhd_error uhd_usrp_rx_info_free(uhd_usrp_rx_info_t* rx_info) +{ free(rx_info->mboard_id); free(rx_info->mboard_name); free(rx_info->mboard_serial); @@ -20,7 +21,8 @@ uhd_error uhd_usrp_rx_info_free(uhd_usrp_rx_info_t *rx_info){ return UHD_ERROR_NONE; } -uhd_error uhd_usrp_tx_info_free(uhd_usrp_tx_info_t *tx_info){ +uhd_error uhd_usrp_tx_info_free(uhd_usrp_tx_info_t* tx_info) +{ free(tx_info->mboard_id); free(tx_info->mboard_name); free(tx_info->mboard_serial); diff --git a/host/lib/types/wb_iface.cpp b/host/lib/types/wb_iface.cpp index aad5d0bfe..15a919732 100644 --- a/host/lib/types/wb_iface.cpp +++ b/host/lib/types/wb_iface.cpp @@ -5,14 +5,14 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/types/wb_iface.hpp> #include <uhd/exception.hpp> +#include <uhd/types/wb_iface.hpp> using namespace uhd; wb_iface::~wb_iface(void) { - //NOP + // NOP } void wb_iface::poke64(const wb_iface::wb_addr_type, const uint64_t) diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index 3cd166507..9f0c3bdd2 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -26,28 +26,31 @@ using namespace uhd::usrp; using namespace uhd::transport; namespace { - constexpr uint16_t B100_VENDOR_ID = 0x2500; - constexpr uint16_t B100_PRODUCT_ID = 0x0002; - constexpr int64_t REENUMERATION_TIMEOUT_MS = 3000; -} +constexpr uint16_t B100_VENDOR_ID = 0x2500; +constexpr uint16_t B100_PRODUCT_ID = 0x0002; +constexpr int64_t REENUMERATION_TIMEOUT_MS = 3000; +} // namespace /*********************************************************************** * Discovery **********************************************************************/ -static device_addrs_t b100_find(const device_addr_t &hint) +static device_addrs_t b100_find(const device_addr_t& hint) { device_addrs_t b100_addrs; - //return an empty list of addresses when type is set to non-b100 - if (hint.has_key("type") and hint["type"] != "b100") return b100_addrs; + // return an empty list of addresses when type is set to non-b100 + if (hint.has_key("type") and hint["type"] != "b100") + return b100_addrs; - //Return an empty list of addresses when an address or resource is specified, - //since an address and resource is intended for a different, non-USB, device. - if (hint.has_key("addr") || hint.has_key("resource")) return b100_addrs; + // Return an empty list of addresses when an address or resource is specified, + // since an address and resource is intended for a different, non-USB, device. + if (hint.has_key("addr") || hint.has_key("resource")) + return b100_addrs; uint16_t vid, pid; - if(hint.has_key("vid") && hint.has_key("pid") && hint.has_key("type") && hint["type"] == "b100") { + if (hint.has_key("vid") && hint.has_key("pid") && hint.has_key("type") + && hint["type"] == "b100") { vid = uhd::cast::hexstr_cast<uint16_t>(hint.get("vid")); pid = uhd::cast::hexstr_cast<uint16_t>(hint.get("pid")); } else { @@ -61,60 +64,60 @@ static device_addrs_t b100_find(const device_addr_t &hint) // so that re-enumeration after fw load can occur successfully. // This requirement is a courtesy of libusb1.0 on windows. - //find the usrps and load firmware + // find the usrps and load firmware size_t found = 0; - for(usb_device_handle::sptr handle: usb_device_handle::get_device_list(vid, pid)) { - //extract the firmware path for the b100 + for (usb_device_handle::sptr handle : usb_device_handle::get_device_list(vid, pid)) { + // extract the firmware path for the b100 std::string b100_fw_image; - try{ + try { b100_fw_image = find_image_path(hint.get("fw", B100_FW_FILE_NAME)); - } - catch(...){ - UHD_LOGGER_WARNING("B100") << boost::format("Could not locate B100 firmware. %s\n") % print_utility_error("uhd_images_downloader.py"); + } catch (...) { + UHD_LOGGER_WARNING("B100") + << boost::format("Could not locate B100 firmware. %s\n") + % print_utility_error("uhd_images_downloader.py"); return b100_addrs; } - UHD_LOGGER_DEBUG("B100") << "the firmware image: " << b100_fw_image ; + UHD_LOGGER_DEBUG("B100") << "the firmware image: " << b100_fw_image; usb_control::sptr control; - try{control = usb_control::make(handle, 0);} - catch(const uhd::exception &){continue;} //ignore claimed + try { + control = usb_control::make(handle, 0); + } catch (const uhd::exception&) { + continue; + } // ignore claimed fx2_ctrl::make(control)->usrp_load_firmware(b100_fw_image); found++; } - //get descriptors again with serial number, but using the initialized VID/PID now since we have firmware + // get descriptors again with serial number, but using the initialized VID/PID now + // since we have firmware vid = B100_VENDOR_ID; pid = B100_PRODUCT_ID; - const auto timeout_time = - std::chrono::steady_clock::now() - + std::chrono::milliseconds(REENUMERATION_TIMEOUT_MS); + const auto timeout_time = std::chrono::steady_clock::now() + + std::chrono::milliseconds(REENUMERATION_TIMEOUT_MS); - //search for the device until found or timeout - while (std::chrono::steady_clock::now() < timeout_time - and b100_addrs.empty() - and found != 0) { + // search for the device until found or timeout + while (std::chrono::steady_clock::now() < timeout_time and b100_addrs.empty() + and found != 0) { for (auto handle : usb_device_handle::get_device_list(vid, pid)) { usb_control::sptr control; try { control = usb_control::make(handle, 0); + } catch (const uhd::exception&) { + continue; // ignore claimed } - catch (const uhd::exception &) { - continue; //ignore claimed - } - fx2_ctrl::sptr fx2_ctrl = fx2_ctrl::make(control); - const mboard_eeprom_t mb_eeprom = - b100_impl::get_mb_eeprom(fx2_ctrl); + fx2_ctrl::sptr fx2_ctrl = fx2_ctrl::make(control); + const mboard_eeprom_t mb_eeprom = b100_impl::get_mb_eeprom(fx2_ctrl); device_addr_t new_addr; - new_addr["type"] = "b100"; - new_addr["name"] = mb_eeprom["name"]; + new_addr["type"] = "b100"; + new_addr["name"] = mb_eeprom["name"]; new_addr["serial"] = handle->get_serial(); - //this is a found b100 when the hint serial and name match or blank - if ( - (not hint.has_key("name") or hint["name"] == new_addr["name"]) and - (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) - ) { + // this is a found b100 when the hint serial and name match or blank + if ((not hint.has_key("name") or hint["name"] == new_addr["name"]) + and (not hint.has_key("serial") + or hint["serial"] == new_addr["serial"])) { b100_addrs.push_back(new_addr); } } @@ -126,81 +129,85 @@ static device_addrs_t b100_find(const device_addr_t &hint) /*********************************************************************** * Make **********************************************************************/ -static device::sptr b100_make(const device_addr_t &device_addr){ +static device::sptr b100_make(const device_addr_t& device_addr) +{ return device::sptr(new b100_impl(device_addr)); } -UHD_STATIC_BLOCK(register_b100_device){ +UHD_STATIC_BLOCK(register_b100_device) +{ device::register_device(&b100_find, &b100_make, device::USRP); } /*********************************************************************** * Structors **********************************************************************/ -b100_impl::b100_impl(const device_addr_t &device_addr){ +b100_impl::b100_impl(const device_addr_t& device_addr) +{ size_t initialization_count = 0; - b100_impl_constructor_begin: +b100_impl_constructor_begin: initialization_count++; - _type = device::USRP; - _tree = property_tree::make(); + _type = device::USRP; + _tree = property_tree::make(); _ignore_cal_file = device_addr.has_key("ignore-cal-file"); - //extract the FPGA path for the B100 + // extract the FPGA path for the B100 std::string b100_fpga_image = find_image_path( - device_addr.has_key("fpga")? device_addr["fpga"] : B100_FPGA_FILE_NAME - ); + device_addr.has_key("fpga") ? device_addr["fpga"] : B100_FPGA_FILE_NAME); - //try to match the given device address with something on the USB bus + // try to match the given device address with something on the USB bus std::vector<usb_device_handle::sptr> device_list = usb_device_handle::get_device_list(B100_VENDOR_ID, B100_PRODUCT_ID); - //locate the matching handle in the device list + // locate the matching handle in the device list usb_device_handle::sptr handle; - for(usb_device_handle::sptr dev_handle: device_list) { - if (dev_handle->get_serial() == device_addr["serial"]){ + for (usb_device_handle::sptr dev_handle : device_list) { + if (dev_handle->get_serial() == device_addr["serial"]) { handle = dev_handle; break; } } - UHD_ASSERT_THROW(handle.get() != NULL); //better be found + UHD_ASSERT_THROW(handle.get() != NULL); // better be found - //create control objects + // create control objects usb_control::sptr fx2_transport = usb_control::make(handle, 0); - _fx2_ctrl = fx2_ctrl::make(fx2_transport); - this->check_fw_compat(); //check after making fx2 + _fx2_ctrl = fx2_ctrl::make(fx2_transport); + this->check_fw_compat(); // check after making fx2 //-- setup clock after making fx2 and before loading fpga --// - _clock_ctrl = b100_clock_ctrl::make(_fx2_ctrl, device_addr.cast<double>("master_clock_rate", B100_DEFAULT_TICK_RATE)); + _clock_ctrl = b100_clock_ctrl::make( + _fx2_ctrl, device_addr.cast<double>("master_clock_rate", B100_DEFAULT_TICK_RATE)); - //load FPGA image, slave xfers are disabled while loading + // load FPGA image, slave xfers are disabled while loading this->enable_gpif(false); _fx2_ctrl->usrp_load_fpga(b100_fpga_image); - _fx2_ctrl->usrp_fpga_reset(false); //active low reset + _fx2_ctrl->usrp_fpga_reset(false); // active low reset _fx2_ctrl->usrp_fpga_reset(true); - //create the control transport + // create the control transport device_addr_t ctrl_xport_args; ctrl_xport_args["recv_frame_size"] = "512"; ctrl_xport_args["num_recv_frames"] = "16"; ctrl_xport_args["send_frame_size"] = "512"; ctrl_xport_args["num_send_frames"] = "16"; - //try to open ctrl transport - //this could fail with libusb_submit_transfer under some conditions - try{ - _ctrl_transport = usb_zero_copy::make( - handle, - 4, 8, //interface, endpoint - 3, 4, //interface, endpoint - ctrl_xport_args - ); + // try to open ctrl transport + // this could fail with libusb_submit_transfer under some conditions + try { + _ctrl_transport = usb_zero_copy::make(handle, + 4, + 8, // interface, endpoint + 3, + 4, // interface, endpoint + ctrl_xport_args); } - //try reset once in the case of failure - catch(const uhd::exception &ex){ - if (initialization_count > 1) throw; - UHD_LOGGER_WARNING("B100") << - "The control endpoint was left in a bad state.\n" - "Attempting endpoint re-enumeration...\n" << ex.what() ; + // try reset once in the case of failure + catch (const uhd::exception& ex) { + if (initialization_count > 1) + throw; + UHD_LOGGER_WARNING("B100") << "The control endpoint was left in a bad state.\n" + "Attempting endpoint re-enumeration...\n" + << ex.what(); _fifo_ctrl.reset(); _ctrl_transport.reset(); _fx2_ctrl->usrp_fx2_reset(); @@ -214,27 +221,27 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ fifo_ctrl_excelsior_config fifo_ctrl_config; fifo_ctrl_config.async_sid_base = B100_TX_ASYNC_SID; fifo_ctrl_config.num_async_chan = 1; - fifo_ctrl_config.ctrl_sid_base = B100_CTRL_MSG_SID; - fifo_ctrl_config.spi_base = TOREG(SR_SPI); - fifo_ctrl_config.spi_rb = REG_RB_SPI; + fifo_ctrl_config.ctrl_sid_base = B100_CTRL_MSG_SID; + fifo_ctrl_config.spi_base = TOREG(SR_SPI); + fifo_ctrl_config.spi_rb = REG_RB_SPI; _fifo_ctrl = fifo_ctrl_excelsior::make(_ctrl_transport, fifo_ctrl_config); - //perform a test peek operation - try{ + // perform a test peek operation + try { _fifo_ctrl->peek32(0); } - //try reset once in the case of failure - catch(const uhd::exception &){ - if (initialization_count > 1) throw; - UHD_LOGGER_WARNING("B100") << - "The control endpoint was left in a bad state.\n" - "Attempting endpoint re-enumeration...\n" ; + // try reset once in the case of failure + catch (const uhd::exception&) { + if (initialization_count > 1) + throw; + UHD_LOGGER_WARNING("B100") << "The control endpoint was left in a bad state.\n" + "Attempting endpoint re-enumeration...\n"; _fifo_ctrl.reset(); _ctrl_transport.reset(); _fx2_ctrl->usrp_fx2_reset(); goto b100_impl_constructor_begin; } - this->check_fpga_compat(); //check after reset and making control + this->check_fpga_compat(); // check after reset and making control //////////////////////////////////////////////////////////////////// // Initialize peripherals after reset @@ -253,19 +260,19 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ data_xport_args["send_frame_size"] = device_addr.get("send_frame_size", "16384"); data_xport_args["num_send_frames"] = device_addr.get("num_send_frames", "16"); - //let packet padder know the LUT size in number of words32 - const size_t rx_lut_size = size_t(data_xport_args.cast<double>("recv_frame_size", 0.0)); - _fifo_ctrl->poke32(TOREG(SR_PADDER+0), rx_lut_size/sizeof(uint32_t)); + // let packet padder know the LUT size in number of words32 + const size_t rx_lut_size = + size_t(data_xport_args.cast<double>("recv_frame_size", 0.0)); + _fifo_ctrl->poke32(TOREG(SR_PADDER + 0), rx_lut_size / sizeof(uint32_t)); - _data_transport = usb_zero_copy_make_wrapper( - usb_zero_copy::make( - handle, // identifier - 2, 6, // IN interface, endpoint - 1, 2, // OUT interface, endpoint - data_xport_args // param hints - ), - B100_MAX_PKT_BYTE_LIMIT - ); + _data_transport = usb_zero_copy_make_wrapper(usb_zero_copy::make(handle, // identifier + 2, + 6, // IN interface, endpoint + 1, + 2, // OUT interface, endpoint + data_xport_args // param hints + ), + B100_MAX_PKT_BYTE_LIMIT); //////////////////////////////////////////////////////////////////// // Initialize the properties tree @@ -275,7 +282,8 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ _tree->create<std::string>(mb_path / "name").set("B100"); _tree->create<std::string>(mb_path / "codename").set("B-Hundo"); _tree->create<std::string>(mb_path / "load_eeprom") - .add_coerced_subscriber(std::bind(&fx2_ctrl::usrp_load_eeprom, _fx2_ctrl, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&fx2_ctrl::usrp_load_eeprom, _fx2_ctrl, std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // setup the mboard eeprom @@ -283,7 +291,8 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ const mboard_eeprom_t mb_eeprom = this->get_mb_eeprom(_fx2_ctrl); _tree->create<mboard_eeprom_t>(mb_path / "eeprom") .set(mb_eeprom) - .add_coerced_subscriber(std::bind(&b100_impl::set_mb_eeprom, this, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b100_impl::set_mb_eeprom, this, std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // create clock control objects @@ -291,28 +300,35 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ //^^^ clock created up top, just reg props here... ^^^ _tree->create<double>(mb_path / "tick_rate") .set_publisher(std::bind(&b100_clock_ctrl::get_fpga_clock_rate, _clock_ctrl)) - .add_coerced_subscriber(std::bind(&fifo_ctrl_excelsior::set_tick_rate, _fifo_ctrl, std::placeholders::_1)) - .add_coerced_subscriber(std::bind(&b100_impl::update_tick_rate, this, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &fifo_ctrl_excelsior::set_tick_rate, _fifo_ctrl, std::placeholders::_1)) + .add_coerced_subscriber( + std::bind(&b100_impl::update_tick_rate, this, std::placeholders::_1)); - //add_coerced_subscriber the command time while we are at it + // add_coerced_subscriber the command time while we are at it _tree->create<time_spec_t>(mb_path / "time/cmd") - .add_coerced_subscriber(std::bind(&fifo_ctrl_excelsior::set_time, _fifo_ctrl, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&fifo_ctrl_excelsior::set_time, _fifo_ctrl, std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // create codec control objects //////////////////////////////////////////////////////////////////// - _codec_ctrl = b100_codec_ctrl::make(_fifo_ctrl); + _codec_ctrl = b100_codec_ctrl::make(_fifo_ctrl); const fs_path rx_codec_path = mb_path / "rx_codecs/A"; const fs_path tx_codec_path = mb_path / "tx_codecs/A"; _tree->create<std::string>(rx_codec_path / "name").set("ad9522"); - _tree->create<meta_range_t>(rx_codec_path / "gains/pga/range").set(b100_codec_ctrl::rx_pga_gain_range); + _tree->create<meta_range_t>(rx_codec_path / "gains/pga/range") + .set(b100_codec_ctrl::rx_pga_gain_range); _tree->create<double>(rx_codec_path / "gains/pga/value") - .set_coercer(std::bind(&b100_impl::update_rx_codec_gain, this, std::placeholders::_1)) + .set_coercer( + std::bind(&b100_impl::update_rx_codec_gain, this, std::placeholders::_1)) .set(0.0); _tree->create<std::string>(tx_codec_path / "name").set("ad9522"); - _tree->create<meta_range_t>(tx_codec_path / "gains/pga/range").set(b100_codec_ctrl::tx_pga_gain_range); + _tree->create<meta_range_t>(tx_codec_path / "gains/pga/range") + .set(b100_codec_ctrl::tx_pga_gain_range); _tree->create<double>(tx_codec_path / "gains/pga/value") - .add_coerced_subscriber(std::bind(&b100_codec_ctrl::set_tx_pga_gain, _codec_ctrl, std::placeholders::_1)) + .add_coerced_subscriber(std::bind( + &b100_codec_ctrl::set_tx_pga_gain, _codec_ctrl, std::placeholders::_1)) .set_publisher(std::bind(&b100_codec_ctrl::get_tx_pga_gain, _codec_ctrl)) .set(0.0); @@ -329,78 +345,91 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ _tx_fe = tx_frontend_core_200::make(_fifo_ctrl, TOREG(SR_TX_FE)); _tree->create<subdev_spec_t>(mb_path / "rx_subdev_spec") - .add_coerced_subscriber(std::bind(&b100_impl::update_rx_subdev_spec, this, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b100_impl::update_rx_subdev_spec, this, std::placeholders::_1)); _tree->create<subdev_spec_t>(mb_path / "tx_subdev_spec") - .add_coerced_subscriber(std::bind(&b100_impl::update_tx_subdev_spec, this, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b100_impl::update_tx_subdev_spec, this, std::placeholders::_1)); const fs_path rx_fe_path = mb_path / "rx_frontends" / "A"; const fs_path tx_fe_path = mb_path / "tx_frontends" / "A"; - _tree->create<std::complex<double> >(rx_fe_path / "dc_offset" / "value") - .set_coercer(std::bind(&rx_frontend_core_200::set_dc_offset, _rx_fe, std::placeholders::_1)) + _tree->create<std::complex<double>>(rx_fe_path / "dc_offset" / "value") + .set_coercer(std::bind( + &rx_frontend_core_200::set_dc_offset, _rx_fe, std::placeholders::_1)) .set(std::complex<double>(0.0, 0.0)); _tree->create<bool>(rx_fe_path / "dc_offset" / "enable") - .add_coerced_subscriber(std::bind(&rx_frontend_core_200::set_dc_offset_auto, _rx_fe, std::placeholders::_1)) + .add_coerced_subscriber(std::bind( + &rx_frontend_core_200::set_dc_offset_auto, _rx_fe, std::placeholders::_1)) .set(true); - _tree->create<std::complex<double> >(rx_fe_path / "iq_balance" / "value") - .add_coerced_subscriber(std::bind(&rx_frontend_core_200::set_iq_balance, _rx_fe, std::placeholders::_1)) + _tree->create<std::complex<double>>(rx_fe_path / "iq_balance" / "value") + .add_coerced_subscriber(std::bind( + &rx_frontend_core_200::set_iq_balance, _rx_fe, std::placeholders::_1)) .set(std::complex<double>(0.0, 0.0)); - _tree->create<std::complex<double> >(tx_fe_path / "dc_offset" / "value") - .set_coercer(std::bind(&tx_frontend_core_200::set_dc_offset, _tx_fe, std::placeholders::_1)) + _tree->create<std::complex<double>>(tx_fe_path / "dc_offset" / "value") + .set_coercer(std::bind( + &tx_frontend_core_200::set_dc_offset, _tx_fe, std::placeholders::_1)) .set(std::complex<double>(0.0, 0.0)); - _tree->create<std::complex<double> >(tx_fe_path / "iq_balance" / "value") - .add_coerced_subscriber(std::bind(&tx_frontend_core_200::set_iq_balance, _tx_fe, std::placeholders::_1)) + _tree->create<std::complex<double>>(tx_fe_path / "iq_balance" / "value") + .add_coerced_subscriber(std::bind( + &tx_frontend_core_200::set_iq_balance, _tx_fe, std::placeholders::_1)) .set(std::complex<double>(0.0, 0.0)); //////////////////////////////////////////////////////////////////// // create rx dsp control objects //////////////////////////////////////////////////////////////////// const size_t num_rx_dsps = _fifo_ctrl->peek32(REG_RB_NUM_RX_DSP); - for (size_t dspno = 0; dspno < num_rx_dsps; dspno++) - { - const size_t sr_off = dspno*32; - _rx_dsps.push_back(rx_dsp_core_200::make( - _fifo_ctrl, - TOREG(SR_RX_DSP0+sr_off), - TOREG(SR_RX_CTRL0+sr_off), - B100_RX_SID_BASE + dspno - )); + for (size_t dspno = 0; dspno < num_rx_dsps; dspno++) { + const size_t sr_off = dspno * 32; + _rx_dsps.push_back(rx_dsp_core_200::make(_fifo_ctrl, + TOREG(SR_RX_DSP0 + sr_off), + TOREG(SR_RX_CTRL0 + sr_off), + B100_RX_SID_BASE + dspno)); _rx_dsps[dspno]->set_link_rate(B100_LINK_RATE_BPS); _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber(std::bind(&rx_dsp_core_200::set_tick_rate, _rx_dsps[dspno], std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &rx_dsp_core_200::set_tick_rate, _rx_dsps[dspno], std::placeholders::_1)); fs_path rx_dsp_path = mb_path / str(boost::format("rx_dsps/%u") % dspno); _tree->create<meta_range_t>(rx_dsp_path / "rate/range") .set_publisher(std::bind(&rx_dsp_core_200::get_host_rates, _rx_dsps[dspno])); _tree->create<double>(rx_dsp_path / "rate/value") - .set(1e6) //some default - .set_coercer(std::bind(&rx_dsp_core_200::set_host_rate, _rx_dsps[dspno], std::placeholders::_1)) - .add_coerced_subscriber(std::bind(&b100_impl::update_rx_samp_rate, this, dspno, std::placeholders::_1)); + .set(1e6) // some default + .set_coercer(std::bind( + &rx_dsp_core_200::set_host_rate, _rx_dsps[dspno], std::placeholders::_1)) + .add_coerced_subscriber(std::bind( + &b100_impl::update_rx_samp_rate, this, dspno, std::placeholders::_1)); _tree->create<double>(rx_dsp_path / "freq/value") - .set_coercer(std::bind(&rx_dsp_core_200::set_freq, _rx_dsps[dspno], std::placeholders::_1)); + .set_coercer(std::bind( + &rx_dsp_core_200::set_freq, _rx_dsps[dspno], std::placeholders::_1)); _tree->create<meta_range_t>(rx_dsp_path / "freq/range") .set_publisher(std::bind(&rx_dsp_core_200::get_freq_range, _rx_dsps[dspno])); _tree->create<stream_cmd_t>(rx_dsp_path / "stream_cmd") - .add_coerced_subscriber(std::bind(&rx_dsp_core_200::issue_stream_command, _rx_dsps[dspno], std::placeholders::_1)); + .add_coerced_subscriber(std::bind(&rx_dsp_core_200::issue_stream_command, + _rx_dsps[dspno], + std::placeholders::_1)); } //////////////////////////////////////////////////////////////////// // create tx dsp control objects //////////////////////////////////////////////////////////////////// _tx_dsp = tx_dsp_core_200::make( - _fifo_ctrl, TOREG(SR_TX_DSP), TOREG(SR_TX_CTRL), B100_TX_ASYNC_SID - ); + _fifo_ctrl, TOREG(SR_TX_DSP), TOREG(SR_TX_CTRL), B100_TX_ASYNC_SID); _tx_dsp->set_link_rate(B100_LINK_RATE_BPS); _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber(std::bind(&tx_dsp_core_200::set_tick_rate, _tx_dsp, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&tx_dsp_core_200::set_tick_rate, _tx_dsp, std::placeholders::_1)); _tree->create<meta_range_t>(mb_path / "tx_dsps/0/rate/range") .set_publisher(std::bind(&tx_dsp_core_200::get_host_rates, _tx_dsp)); _tree->create<double>(mb_path / "tx_dsps/0/rate/value") - .set(1e6) //some default - .set_coercer(std::bind(&tx_dsp_core_200::set_host_rate, _tx_dsp, std::placeholders::_1)) - .add_coerced_subscriber(std::bind(&b100_impl::update_tx_samp_rate, this, 0, std::placeholders::_1)); + .set(1e6) // some default + .set_coercer( + std::bind(&tx_dsp_core_200::set_host_rate, _tx_dsp, std::placeholders::_1)) + .add_coerced_subscriber( + std::bind(&b100_impl::update_tx_samp_rate, this, 0, std::placeholders::_1)); _tree->create<double>(mb_path / "tx_dsps/0/freq/value") - .set_coercer(std::bind(&tx_dsp_core_200::set_freq, _tx_dsp, std::placeholders::_1)); + .set_coercer( + std::bind(&tx_dsp_core_200::set_freq, _tx_dsp, std::placeholders::_1)); _tree->create<meta_range_t>(mb_path / "tx_dsps/0/freq/range") .set_publisher(std::bind(&tx_dsp_core_200::get_freq_range, _tx_dsp)); @@ -412,202 +441,241 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ time64_rb_bases.rb_lo_now = REG_RB_TIME_NOW_LO; time64_rb_bases.rb_hi_pps = REG_RB_TIME_PPS_HI; time64_rb_bases.rb_lo_pps = REG_RB_TIME_PPS_LO; - _time64 = time64_core_200::make( - _fifo_ctrl, TOREG(SR_TIME64), time64_rb_bases - ); + _time64 = time64_core_200::make(_fifo_ctrl, TOREG(SR_TIME64), time64_rb_bases); _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber(std::bind(&time64_core_200::set_tick_rate, _time64, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&time64_core_200::set_tick_rate, _time64, std::placeholders::_1)); _tree->create<time_spec_t>(mb_path / "time/now") .set_publisher(std::bind(&time64_core_200::get_time_now, _time64)) - .add_coerced_subscriber(std::bind(&time64_core_200::set_time_now, _time64, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&time64_core_200::set_time_now, _time64, std::placeholders::_1)); _tree->create<time_spec_t>(mb_path / "time/pps") .set_publisher(std::bind(&time64_core_200::get_time_last_pps, _time64)) - .add_coerced_subscriber(std::bind(&time64_core_200::set_time_next_pps, _time64, std::placeholders::_1)); - //setup time source props + .add_coerced_subscriber(std::bind( + &time64_core_200::set_time_next_pps, _time64, std::placeholders::_1)); + // setup time source props _tree->create<std::string>(mb_path / "time_source/value") - .add_coerced_subscriber(std::bind(&time64_core_200::set_time_source, _time64, std::placeholders::_1)); - _tree->create<std::vector<std::string> >(mb_path / "time_source/options") + .add_coerced_subscriber( + std::bind(&time64_core_200::set_time_source, _time64, std::placeholders::_1)); + _tree->create<std::vector<std::string>>(mb_path / "time_source/options") .set_publisher(std::bind(&time64_core_200::get_time_sources, _time64)); - //setup reference source props + // setup reference source props _tree->create<std::string>(mb_path / "clock_source/value") - .add_coerced_subscriber(std::bind(&b100_impl::update_clock_source, this, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b100_impl::update_clock_source, this, std::placeholders::_1)); static const std::vector<std::string> clock_sources = { - "internal", "external", "auto" - }; - _tree->create<std::vector<std::string> >(mb_path / "clock_source/options").set(clock_sources); + "internal", "external", "auto"}; + _tree->create<std::vector<std::string>>(mb_path / "clock_source/options") + .set(clock_sources); //////////////////////////////////////////////////////////////////// // create user-defined control objects //////////////////////////////////////////////////////////////////// _user = user_settings_core_200::make(_fifo_ctrl, TOREG(SR_USER_REGS)); _tree->create<user_settings_core_200::user_reg_t>(mb_path / "user/regs") - .add_coerced_subscriber(std::bind(&user_settings_core_200::set_reg, _user, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&user_settings_core_200::set_reg, _user, std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // create dboard control objects //////////////////////////////////////////////////////////////////// - //read the dboard eeprom to extract the dboard ids + // read the dboard eeprom to extract the dboard ids dboard_eeprom_t rx_db_eeprom, tx_db_eeprom, gdb_eeprom; rx_db_eeprom.load(*_fpga_i2c_ctrl, I2C_ADDR_RX_A); tx_db_eeprom.load(*_fpga_i2c_ctrl, I2C_ADDR_TX_A); gdb_eeprom.load(*_fpga_i2c_ctrl, I2C_ADDR_TX_A ^ 5); - //disable rx dc offset if LFRX - if (rx_db_eeprom.id == 0x000f) _tree->access<bool>(rx_fe_path / "dc_offset" / "enable").set(false); + // disable rx dc offset if LFRX + if (rx_db_eeprom.id == 0x000f) + _tree->access<bool>(rx_fe_path / "dc_offset" / "enable").set(false); - //create the properties and register subscribers + // create the properties and register subscribers _tree->create<dboard_eeprom_t>(mb_path / "dboards/A/rx_eeprom") .set(rx_db_eeprom) - .add_coerced_subscriber(std::bind(&b100_impl::set_db_eeprom, this, "rx", std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b100_impl::set_db_eeprom, this, "rx", std::placeholders::_1)); _tree->create<dboard_eeprom_t>(mb_path / "dboards/A/tx_eeprom") .set(tx_db_eeprom) - .add_coerced_subscriber(std::bind(&b100_impl::set_db_eeprom, this, "tx", std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b100_impl::set_db_eeprom, this, "tx", std::placeholders::_1)); _tree->create<dboard_eeprom_t>(mb_path / "dboards/A/gdb_eeprom") .set(gdb_eeprom) - .add_coerced_subscriber(std::bind(&b100_impl::set_db_eeprom, this, "gdb", std::placeholders::_1)); - - //create a new dboard interface and manager - _dboard_manager = dboard_manager::make( - rx_db_eeprom.id, tx_db_eeprom.id, gdb_eeprom.id, - make_b100_dboard_iface(_fifo_ctrl, _fpga_i2c_ctrl, _fifo_ctrl/*spi*/, _clock_ctrl, _codec_ctrl), - _tree->subtree(mb_path / "dboards/A") - ); - - //bind frontend corrections to the dboard freq props + .add_coerced_subscriber( + std::bind(&b100_impl::set_db_eeprom, this, "gdb", std::placeholders::_1)); + + // create a new dboard interface and manager + _dboard_manager = dboard_manager::make(rx_db_eeprom.id, + tx_db_eeprom.id, + gdb_eeprom.id, + make_b100_dboard_iface( + _fifo_ctrl, _fpga_i2c_ctrl, _fifo_ctrl /*spi*/, _clock_ctrl, _codec_ctrl), + _tree->subtree(mb_path / "dboards/A")); + + // bind frontend corrections to the dboard freq props const fs_path db_tx_fe_path = mb_path / "dboards" / "A" / "tx_frontends"; - for(const std::string &name: _tree->list(db_tx_fe_path)){ + for (const std::string& name : _tree->list(db_tx_fe_path)) { _tree->access<double>(db_tx_fe_path / name / "freq" / "value") - .add_coerced_subscriber(std::bind(&b100_impl::set_tx_fe_corrections, this, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &b100_impl::set_tx_fe_corrections, this, std::placeholders::_1)); } const fs_path db_rx_fe_path = mb_path / "dboards" / "A" / "rx_frontends"; - for(const std::string &name: _tree->list(db_rx_fe_path)){ + for (const std::string& name : _tree->list(db_rx_fe_path)) { _tree->access<double>(db_rx_fe_path / name / "freq" / "value") - .add_coerced_subscriber(std::bind(&b100_impl::set_rx_fe_corrections, this, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &b100_impl::set_rx_fe_corrections, this, std::placeholders::_1)); } - //initialize io handling + // initialize io handling _recv_demuxer.reset(new recv_packet_demuxer_3000(_data_transport)); - //allocate streamer weak ptrs containers + // allocate streamer weak ptrs containers _rx_streamers.resize(_rx_dsps.size()); - _tx_streamers.resize(1/*known to be 1 dsp*/); + _tx_streamers.resize(1 /*known to be 1 dsp*/); //////////////////////////////////////////////////////////////////// // do some post-init tasks //////////////////////////////////////////////////////////////////// this->update_rates(); - _tree->access<double>(mb_path / "tick_rate") //now add_coerced_subscriber the clock rate setter - .add_coerced_subscriber(std::bind(&b100_clock_ctrl::set_fpga_clock_rate, _clock_ctrl, std::placeholders::_1)); + _tree + ->access<double>( + mb_path / "tick_rate") // now add_coerced_subscriber the clock rate setter + .add_coerced_subscriber(std::bind( + &b100_clock_ctrl::set_fpga_clock_rate, _clock_ctrl, std::placeholders::_1)); - //reset cordic rates and their properties to zero - for(const std::string &name: _tree->list(mb_path / "rx_dsps")){ + // reset cordic rates and their properties to zero + for (const std::string& name : _tree->list(mb_path / "rx_dsps")) { _tree->access<double>(mb_path / "rx_dsps" / name / "freq" / "value").set(0.0); } - for(const std::string &name: _tree->list(mb_path / "tx_dsps")){ + for (const std::string& name : _tree->list(mb_path / "tx_dsps")) { _tree->access<double>(mb_path / "tx_dsps" / name / "freq" / "value").set(0.0); } - _tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(subdev_spec_t("A:" + _tree->list(mb_path / "dboards/A/rx_frontends").at(0))); - _tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(subdev_spec_t("A:" + _tree->list(mb_path / "dboards/A/tx_frontends").at(0))); + _tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec") + .set(subdev_spec_t("A:" + _tree->list(mb_path / "dboards/A/rx_frontends").at(0))); + _tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec") + .set(subdev_spec_t("A:" + _tree->list(mb_path / "dboards/A/tx_frontends").at(0))); _tree->access<std::string>(mb_path / "clock_source/value").set("internal"); _tree->access<std::string>(mb_path / "time_source/value").set("none"); _tree->create<double>(mb_path / "link_max_rate").set(B100_MAX_RATE_USB2); } -b100_impl::~b100_impl(void){ - //NOP +b100_impl::~b100_impl(void) +{ + // NOP } -void b100_impl::check_fw_compat(void){ - unsigned char data[4]; //useless data buffer - const uint16_t fw_compat_num = _fx2_ctrl->usrp_control_read( - VRQ_FW_COMPAT, 0, 0, data, sizeof(data) - ); - if (fw_compat_num != B100_FW_COMPAT_NUM){ - throw uhd::runtime_error(str(boost::format( - "Expected firmware compatibility number %d, but got %d:\n" - "The firmware build is not compatible with the host code build.\n" - "%s" - ) % int(B100_FW_COMPAT_NUM) % fw_compat_num % print_utility_error("uhd_images_downloader.py"))); +void b100_impl::check_fw_compat(void) +{ + unsigned char data[4]; // useless data buffer + const uint16_t fw_compat_num = + _fx2_ctrl->usrp_control_read(VRQ_FW_COMPAT, 0, 0, data, sizeof(data)); + if (fw_compat_num != B100_FW_COMPAT_NUM) { + throw uhd::runtime_error( + str(boost::format( + "Expected firmware compatibility number %d, but got %d:\n" + "The firmware build is not compatible with the host code build.\n" + "%s") + % int(B100_FW_COMPAT_NUM) % fw_compat_num + % print_utility_error("uhd_images_downloader.py"))); } - _tree->create<std::string>("/mboards/0/fw_version").set(str(boost::format("%u.0") % fw_compat_num)); + _tree->create<std::string>("/mboards/0/fw_version") + .set(str(boost::format("%u.0") % fw_compat_num)); } -void b100_impl::check_fpga_compat(void){ +void b100_impl::check_fpga_compat(void) +{ const uint32_t fpga_compat_num = _fifo_ctrl->peek32(REG_RB_COMPAT); uint16_t fpga_major = fpga_compat_num >> 16, fpga_minor = fpga_compat_num & 0xffff; - if (fpga_major == 0){ //old version scheme + if (fpga_major == 0) { // old version scheme fpga_major = fpga_minor; fpga_minor = 0; } - if (fpga_major != B100_FPGA_COMPAT_NUM){ - throw uhd::runtime_error(str(boost::format( - "Expected FPGA compatibility number %d, but got %d:\n" - "The FPGA build is not compatible with the host code build." - "%s" - ) % int(B100_FPGA_COMPAT_NUM) % fpga_major % print_utility_error("uhd_images_downloader.py"))); + if (fpga_major != B100_FPGA_COMPAT_NUM) { + throw uhd::runtime_error( + str(boost::format("Expected FPGA compatibility number %d, but got %d:\n" + "The FPGA build is not compatible with the host code build." + "%s") + % int(B100_FPGA_COMPAT_NUM) % fpga_major + % print_utility_error("uhd_images_downloader.py"))); } - _tree->create<std::string>("/mboards/0/fpga_version").set(str(boost::format("%u.%u") % fpga_major % fpga_minor)); + _tree->create<std::string>("/mboards/0/fpga_version") + .set(str(boost::format("%u.%u") % fpga_major % fpga_minor)); } -double b100_impl::update_rx_codec_gain(const double gain){ - //set gain on both I and Q, readback on one - //TODO in the future, gains should have individual control +double b100_impl::update_rx_codec_gain(const double gain) +{ + // set gain on both I and Q, readback on one + // TODO in the future, gains should have individual control _codec_ctrl->set_rx_pga_gain(gain, 'A'); _codec_ctrl->set_rx_pga_gain(gain, 'B'); return _codec_ctrl->get_rx_pga_gain('A'); } -void b100_impl::set_db_eeprom(const std::string &type, const uhd::usrp::dboard_eeprom_t &db_eeprom){ - if (type == "rx") db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_RX_A); - if (type == "tx") db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_TX_A); - if (type == "gdb") db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_TX_A ^ 5); +void b100_impl::set_db_eeprom( + const std::string& type, const uhd::usrp::dboard_eeprom_t& db_eeprom) +{ + if (type == "rx") + db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_RX_A); + if (type == "tx") + db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_TX_A); + if (type == "gdb") + db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_TX_A ^ 5); } -void b100_impl::update_clock_source(const std::string &source){ - - if (source == "pps_sync"){ +void b100_impl::update_clock_source(const std::string& source) +{ + if (source == "pps_sync") { _clock_ctrl->use_external_ref(); - _fifo_ctrl->poke32(TOREG(SR_MISC+2), 1); + _fifo_ctrl->poke32(TOREG(SR_MISC + 2), 1); return; } - if (source == "_pps_sync_"){ + if (source == "_pps_sync_") { _clock_ctrl->use_external_ref(); - _fifo_ctrl->poke32(TOREG(SR_MISC+2), 3); + _fifo_ctrl->poke32(TOREG(SR_MISC + 2), 3); return; } - _fifo_ctrl->poke32(TOREG(SR_MISC+2), 0); + _fifo_ctrl->poke32(TOREG(SR_MISC + 2), 0); - if (source == "auto") _clock_ctrl->use_auto_ref(); - else if (source == "internal") _clock_ctrl->use_internal_ref(); - else if (source == "external") _clock_ctrl->use_external_ref(); - else throw uhd::runtime_error("unhandled clock configuration reference source: " + source); + if (source == "auto") + _clock_ctrl->use_auto_ref(); + else if (source == "internal") + _clock_ctrl->use_internal_ref(); + else if (source == "external") + _clock_ctrl->use_external_ref(); + else + throw uhd::runtime_error( + "unhandled clock configuration reference source: " + source); } ////////////////// some GPIF preparation related stuff ///////////////// -void b100_impl::enable_gpif(const bool en) { +void b100_impl::enable_gpif(const bool en) +{ _fx2_ctrl->usrp_control_write(VRQ_ENABLE_GPIF, en ? 1 : 0, 0, 0, 0); } -void b100_impl::clear_fpga_fifo(void) { +void b100_impl::clear_fpga_fifo(void) +{ _fx2_ctrl->usrp_control_write(VRQ_CLEAR_FPGA_FIFO, 0, 0, 0, 0); } -sensor_value_t b100_impl::get_ref_locked(void){ +sensor_value_t b100_impl::get_ref_locked(void) +{ const bool lock = _clock_ctrl->get_locked(); return sensor_value_t("Ref", lock, "locked", "unlocked"); } -void b100_impl::set_rx_fe_corrections(const double lo_freq){ - if(not _ignore_cal_file){ +void b100_impl::set_rx_fe_corrections(const double lo_freq) +{ + if (not _ignore_cal_file) { apply_rx_fe_corrections(this->get_tree()->subtree("/mboards/0"), "A", lo_freq); } } -void b100_impl::set_tx_fe_corrections(const double lo_freq){ - if(not _ignore_cal_file){ +void b100_impl::set_tx_fe_corrections(const double lo_freq) +{ + if (not _ignore_cal_file) { apply_tx_fe_corrections(this->get_tree()->subtree("/mboards/0"), "A", lo_freq); } } diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index bb72cd63e..0b46c4815 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -13,55 +13,53 @@ #include "fifo_ctrl_excelsior.hpp" #include <uhd/device.hpp> #include <uhd/property_tree.hpp> +#include <uhd/transport/usb_zero_copy.hpp> #include <uhd/types/dict.hpp> #include <uhd/types/sensors.hpp> #include <uhd/types/stream_cmd.hpp> -#include <uhd/usrp/mboard_eeprom.hpp> -#include <uhd/usrp/subdev_spec.hpp> #include <uhd/usrp/dboard_eeprom.hpp> #include <uhd/usrp/dboard_manager.hpp> -#include <uhd/transport/usb_zero_copy.hpp> +#include <uhd/usrp/mboard_eeprom.hpp> +#include <uhd/usrp/subdev_spec.hpp> #include <uhdlib/usrp/common/fx2_ctrl.hpp> #include <uhdlib/usrp/common/recv_packet_demuxer_3000.hpp> #include <uhdlib/usrp/cores/i2c_core_200.hpp> -#include <uhdlib/usrp/cores/rx_frontend_core_200.hpp> -#include <uhdlib/usrp/cores/tx_frontend_core_200.hpp> #include <uhdlib/usrp/cores/rx_dsp_core_200.hpp> -#include <uhdlib/usrp/cores/tx_dsp_core_200.hpp> +#include <uhdlib/usrp/cores/rx_frontend_core_200.hpp> #include <uhdlib/usrp/cores/time64_core_200.hpp> +#include <uhdlib/usrp/cores/tx_dsp_core_200.hpp> +#include <uhdlib/usrp/cores/tx_frontend_core_200.hpp> #include <uhdlib/usrp/cores/user_settings_core_200.hpp> #include <memory> -static const double B100_LINK_RATE_BPS = 256e6/5; //pratical link rate (< 480 Mbps) -static const std::string B100_FW_FILE_NAME = "usrp_b100_fw.ihx"; -static const std::string B100_FPGA_FILE_NAME = "usrp_b100_fpga.bin"; -static const uint16_t B100_FW_COMPAT_NUM = 4; -static const uint16_t B100_FPGA_COMPAT_NUM = 11; -static const uint32_t B100_RX_SID_BASE = 30; -static const uint32_t B100_TX_ASYNC_SID = 10; -static const uint32_t B100_CTRL_MSG_SID = 20; -static const double B100_DEFAULT_TICK_RATE = 64e6; -static const size_t B100_MAX_PKT_BYTE_LIMIT = 2048; -static const size_t B100_MAX_RATE_USB2 = 32000000; // bytes/s - -#define I2C_ADDR_TX_A (I2C_DEV_EEPROM | 0x4) -#define I2C_ADDR_RX_A (I2C_DEV_EEPROM | 0x5) -#define I2C_ADDR_TX_B (I2C_DEV_EEPROM | 0x6) -#define I2C_ADDR_RX_B (I2C_DEV_EEPROM | 0x7) -#define I2C_DEV_EEPROM 0x50 - -#define VRQ_FW_COMPAT 0x83 -#define VRQ_ENABLE_GPIF 0x0d +static const double B100_LINK_RATE_BPS = 256e6 / 5; // pratical link rate (< 480 Mbps) +static const std::string B100_FW_FILE_NAME = "usrp_b100_fw.ihx"; +static const std::string B100_FPGA_FILE_NAME = "usrp_b100_fpga.bin"; +static const uint16_t B100_FW_COMPAT_NUM = 4; +static const uint16_t B100_FPGA_COMPAT_NUM = 11; +static const uint32_t B100_RX_SID_BASE = 30; +static const uint32_t B100_TX_ASYNC_SID = 10; +static const uint32_t B100_CTRL_MSG_SID = 20; +static const double B100_DEFAULT_TICK_RATE = 64e6; +static const size_t B100_MAX_PKT_BYTE_LIMIT = 2048; +static const size_t B100_MAX_RATE_USB2 = 32000000; // bytes/s + +#define I2C_ADDR_TX_A (I2C_DEV_EEPROM | 0x4) +#define I2C_ADDR_RX_A (I2C_DEV_EEPROM | 0x5) +#define I2C_ADDR_TX_B (I2C_DEV_EEPROM | 0x6) +#define I2C_ADDR_RX_B (I2C_DEV_EEPROM | 0x7) +#define I2C_DEV_EEPROM 0x50 + +#define VRQ_FW_COMPAT 0x83 +#define VRQ_ENABLE_GPIF 0x0d #define VRQ_CLEAR_FPGA_FIFO 0x0e //! Make a b100 dboard interface -uhd::usrp::dboard_iface::sptr make_b100_dboard_iface( - uhd::timed_wb_iface::sptr wb_iface, +uhd::usrp::dboard_iface::sptr make_b100_dboard_iface(uhd::timed_wb_iface::sptr wb_iface, uhd::i2c_iface::sptr i2c_iface, uhd::spi_iface::sptr spi_iface, b100_clock_ctrl::sptr clock, - b100_codec_ctrl::sptr codec -); + b100_codec_ctrl::sptr codec); /*! * Make a wrapper around a zero copy implementation. @@ -78,25 +76,25 @@ uhd::usrp::dboard_iface::sptr make_b100_dboard_iface( * \return a new zero copy wrapper object */ uhd::transport::zero_copy_if::sptr usb_zero_copy_make_wrapper( - uhd::transport::zero_copy_if::sptr usb_zc, size_t usb_frame_boundary = 512 -); + uhd::transport::zero_copy_if::sptr usb_zc, size_t usb_frame_boundary = 512); //! Implementation guts -class b100_impl : public uhd::device { +class b100_impl : public uhd::device +{ public: - //structors - b100_impl(const uhd::device_addr_t &); + // structors + b100_impl(const uhd::device_addr_t&); ~b100_impl(void); - //the io interface - uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t &args); - uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t &args); - bool recv_async_msg(uhd::async_metadata_t &, double); + // the io interface + uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t& args); + uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t& args); + bool recv_async_msg(uhd::async_metadata_t&, double); static uhd::usrp::mboard_eeprom_t get_mb_eeprom(uhd::i2c_iface::sptr); private: - //controllers + // controllers fifo_ctrl_excelsior::sptr _fifo_ctrl; i2c_core_200::sptr _fpga_i2c_ctrl; rx_frontend_core_200::sptr _rx_fe; @@ -109,30 +107,30 @@ private: b100_codec_ctrl::sptr _codec_ctrl; uhd::usrp::fx2_ctrl::sptr _fx2_ctrl; - //transports + // transports uhd::transport::zero_copy_if::sptr _ctrl_transport; uhd::transport::zero_copy_if::sptr _data_transport; std::shared_ptr<uhd::usrp::recv_packet_demuxer_3000> _recv_demuxer; - //dboard stuff + // dboard stuff uhd::usrp::dboard_manager::sptr _dboard_manager; bool _ignore_cal_file; - std::vector<std::weak_ptr<uhd::rx_streamer> > _rx_streamers; - std::vector<std::weak_ptr<uhd::tx_streamer> > _tx_streamers; + std::vector<std::weak_ptr<uhd::rx_streamer>> _rx_streamers; + std::vector<std::weak_ptr<uhd::tx_streamer>> _tx_streamers; void check_fw_compat(void); void check_fpga_compat(void); - double update_rx_codec_gain(const double); //sets A and B at once - void set_mb_eeprom(const uhd::usrp::mboard_eeprom_t &); - void set_db_eeprom(const std::string &, const uhd::usrp::dboard_eeprom_t &); + double update_rx_codec_gain(const double); // sets A and B at once + void set_mb_eeprom(const uhd::usrp::mboard_eeprom_t&); + void set_db_eeprom(const std::string&, const uhd::usrp::dboard_eeprom_t&); void update_tick_rate(const double rate); void update_rx_samp_rate(const size_t, const double rate); void update_tx_samp_rate(const size_t, const double rate); void update_rates(void); - void update_rx_subdev_spec(const uhd::usrp::subdev_spec_t &); - void update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &); - void update_clock_source(const std::string &); + void update_rx_subdev_spec(const uhd::usrp::subdev_spec_t&); + void update_tx_subdev_spec(const uhd::usrp::subdev_spec_t&); + void update_clock_source(const std::string&); void enable_gpif(const bool); void clear_fpga_fifo(void); uhd::sensor_value_t get_ref_locked(void); diff --git a/host/lib/usrp/b100/b100_regs.hpp b/host/lib/usrp/b100/b100_regs.hpp index 8cb231488..541a14849 100644 --- a/host/lib/usrp/b100/b100_regs.hpp +++ b/host/lib/usrp/b100/b100_regs.hpp @@ -14,40 +14,39 @@ #define localparam static const int -localparam SR_MISC = 0; // 5 -localparam SR_USER_REGS = 5; // 2 -localparam SR_PADDER = 10; // 2 +localparam SR_MISC = 0; // 5 +localparam SR_USER_REGS = 5; // 2 +localparam SR_PADDER = 10; // 2 -localparam SR_TX_CTRL = 32; // 6 -localparam SR_TX_DSP = 40; // 5 -localparam SR_TX_FE = 48; // 5 +localparam SR_TX_CTRL = 32; // 6 +localparam SR_TX_DSP = 40; // 5 +localparam SR_TX_FE = 48; // 5 -localparam SR_RX_CTRL0 = 96; // 9 -localparam SR_RX_DSP0 = 106; // 7 -localparam SR_RX_FE = 114; // 5 +localparam SR_RX_CTRL0 = 96; // 9 +localparam SR_RX_DSP0 = 106; // 7 +localparam SR_RX_FE = 114; // 5 -localparam SR_RX_CTRL1 = 128; // 9 -localparam SR_RX_DSP1 = 138; // 7 +localparam SR_RX_CTRL1 = 128; // 9 +localparam SR_RX_DSP1 = 138; // 7 -localparam SR_TIME64 = 192; // 6 -localparam SR_SPI = 208; // 3 -localparam SR_I2C = 216; // 1 -localparam SR_GPIO = 224; // 5 +localparam SR_TIME64 = 192; // 6 +localparam SR_SPI = 208; // 3 +localparam SR_I2C = 216; // 1 +localparam SR_GPIO = 224; // 5 #define REG_RB_TIME_NOW_HI TOREG(10) #define REG_RB_TIME_NOW_LO TOREG(11) #define REG_RB_TIME_PPS_HI TOREG(14) #define REG_RB_TIME_PPS_LO TOREG(15) -#define REG_RB_SPI TOREG(0) -#define REG_RB_COMPAT TOREG(1) -#define REG_RB_GPIO TOREG(3) -#define REG_RB_I2C TOREG(2) -#define REG_RB_NUM_RX_DSP TOREG(6) +#define REG_RB_SPI TOREG(0) +#define REG_RB_COMPAT TOREG(1) +#define REG_RB_GPIO TOREG(3) +#define REG_RB_I2C TOREG(2) +#define REG_RB_NUM_RX_DSP TOREG(6) -//spi slave constants -#define B100_SPI_SS_AD9862 (1 << 2) -#define B100_SPI_SS_TX_DB (1 << 1) -#define B100_SPI_SS_RX_DB (1 << 0) +// spi slave constants +#define B100_SPI_SS_AD9862 (1 << 2) +#define B100_SPI_SS_TX_DB (1 << 1) +#define B100_SPI_SS_RX_DB (1 << 0) #endif /*INCLUDED_B100_REGS_HPP*/ - diff --git a/host/lib/usrp/b100/clock_ctrl.cpp b/host/lib/usrp/b100/clock_ctrl.cpp index 676ebd981..12ef2052f 100644 --- a/host/lib/usrp/b100/clock_ctrl.cpp +++ b/host/lib/usrp/b100/clock_ctrl.cpp @@ -87,7 +87,8 @@ struct clock_settings_type }; //! gives the greatest divisor of num between 1 and max inclusive -template <typename T> static inline T greatest_divisor(T num, T max) +template <typename T> +static inline T greatest_divisor(T num, T max) { for (T i = max; i > 1; i--) { if (num % i == 0) { @@ -98,7 +99,8 @@ template <typename T> static inline T greatest_divisor(T num, T max) } //! gives the least divisor of num between min and num exclusive -template <typename T> static inline T least_divisor(T num, T min) +template <typename T> +static inline T least_divisor(T num, T min) { for (T i = min; i < num; i++) { if (num % i == 0) { diff --git a/host/lib/usrp/b100/clock_ctrl.hpp b/host/lib/usrp/b100/clock_ctrl.hpp index b208e8a0c..318d1b248 100644 --- a/host/lib/usrp/b100/clock_ctrl.hpp +++ b/host/lib/usrp/b100/clock_ctrl.hpp @@ -17,7 +17,8 @@ * The B100 clock control: * - Disable/enable clock lines. */ -class b100_clock_ctrl : uhd::noncopyable{ +class b100_clock_ctrl : uhd::noncopyable +{ public: typedef std::shared_ptr<b100_clock_ctrl> sptr; @@ -81,12 +82,12 @@ public: * \return the clock rate in Hz */ virtual double get_tx_clock_rate(void) = 0; - + /*! * Enable/disable the FPGA clock. * \param enb true to enable */ - + virtual void enable_fpga_clock(bool enb) = 0; /*! @@ -100,17 +101,17 @@ public: * \param enb true to enable */ virtual void enable_tx_dboard_clock(bool enb) = 0; - + /*! * Use the internal TCXO reference */ virtual void use_internal_ref(void) = 0; - + /*! * Use the external SMA reference */ virtual void use_external_ref(void) = 0; - + /*! * Use external if available, internal otherwise */ @@ -118,7 +119,6 @@ public: //! Is the reference locked? virtual bool get_locked(void) = 0; - }; #endif /* INCLUDED_B100_CLOCK_CTRL_HPP */ diff --git a/host/lib/usrp/b100/codec_ctrl.cpp b/host/lib/usrp/b100/codec_ctrl.cpp index 10cfa686a..f6e2d8b93 100644 --- a/host/lib/usrp/b100/codec_ctrl.cpp +++ b/host/lib/usrp/b100/codec_ctrl.cpp @@ -7,15 +7,15 @@ #include "codec_ctrl.hpp" #include "ad9862_regs.hpp" -#include <uhd/types/dict.hpp> +#include "b100_regs.hpp" //spi slave constants #include <uhd/exception.hpp> +#include <uhd/types/dict.hpp> #include <uhd/utils/algorithm.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/safe_call.hpp> #include <stdint.h> -#include <boost/math/special_functions/round.hpp> -#include "b100_regs.hpp" //spi slave constants #include <boost/assign/list_of.hpp> +#include <boost/math/special_functions/round.hpp> #include <tuple> using namespace uhd; @@ -23,24 +23,26 @@ using namespace uhd; const gain_range_t b100_codec_ctrl::tx_pga_gain_range(-20, 0, double(0.1)); const gain_range_t b100_codec_ctrl::rx_pga_gain_range(0, 20, 1); -b100_codec_ctrl::~b100_codec_ctrl(void){ +b100_codec_ctrl::~b100_codec_ctrl(void) +{ /* NOP */ } /*********************************************************************** * Codec Control Implementation **********************************************************************/ -class b100_codec_ctrl_impl : public b100_codec_ctrl{ +class b100_codec_ctrl_impl : public b100_codec_ctrl +{ public: - //structors + // structors b100_codec_ctrl_impl(spi_iface::sptr iface); ~b100_codec_ctrl_impl(void); - //aux adc and dac control + // aux adc and dac control double read_aux_adc(aux_adc_t which); void write_aux_dac(aux_dac_t which, double volts); - //pga gain control + // pga gain control void set_tx_pga_gain(double); double get_tx_pga_gain(void); void set_rx_pga_gain(double, char); @@ -56,157 +58,178 @@ private: /*********************************************************************** * Codec Control Structors **********************************************************************/ -b100_codec_ctrl_impl::b100_codec_ctrl_impl(spi_iface::sptr iface){ +b100_codec_ctrl_impl::b100_codec_ctrl_impl(spi_iface::sptr iface) +{ _iface = iface; - //soft reset + // soft reset _ad9862_regs.soft_reset = 1; this->send_reg(0); - //initialize the codec register settings + // initialize the codec register settings _ad9862_regs.sdio_bidir = ad9862_regs_t::SDIO_BIDIR_SDIO_SDO; - _ad9862_regs.lsb_first = ad9862_regs_t::LSB_FIRST_MSB; + _ad9862_regs.lsb_first = ad9862_regs_t::LSB_FIRST_MSB; _ad9862_regs.soft_reset = 0; - //setup rx side of codec + // setup rx side of codec _ad9862_regs.byp_buffer_a = 1; _ad9862_regs.byp_buffer_b = 1; - _ad9862_regs.buffer_a_pd = 1; - _ad9862_regs.buffer_b_pd = 1; - _ad9862_regs.mux_out = ad9862_regs_t::MUX_OUT_RX_MUX_MODE; //B100 uses interleaved RX->FPGA - _ad9862_regs.rx_pga_a = 0;//0x1f; //TODO bring under api control - _ad9862_regs.rx_pga_b = 0;//0x1f; //TODO bring under api control + _ad9862_regs.buffer_a_pd = 1; + _ad9862_regs.buffer_b_pd = 1; + _ad9862_regs.mux_out = + ad9862_regs_t::MUX_OUT_RX_MUX_MODE; // B100 uses interleaved RX->FPGA + _ad9862_regs.rx_pga_a = 0; // 0x1f; //TODO bring under api control + _ad9862_regs.rx_pga_b = 0; // 0x1f; //TODO bring under api control _ad9862_regs.rx_twos_comp = 1; - _ad9862_regs.rx_hilbert = ad9862_regs_t::RX_HILBERT_DIS; + _ad9862_regs.rx_hilbert = ad9862_regs_t::RX_HILBERT_DIS; - //setup tx side of codec + // setup tx side of codec _ad9862_regs.two_data_paths = ad9862_regs_t::TWO_DATA_PATHS_BOTH; - _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_INTERLEAVED; - _ad9862_regs.tx_retime = ad9862_regs_t::TX_RETIME_CLKOUT2; - _ad9862_regs.tx_pga_gain = 199; //TODO bring under api control - _ad9862_regs.tx_hilbert = ad9862_regs_t::TX_HILBERT_DIS; - _ad9862_regs.interp = ad9862_regs_t::INTERP_2; - _ad9862_regs.tx_twos_comp = 1; - _ad9862_regs.fine_mode = ad9862_regs_t::FINE_MODE_BYPASS; - _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS; + _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_INTERLEAVED; + _ad9862_regs.tx_retime = ad9862_regs_t::TX_RETIME_CLKOUT2; + _ad9862_regs.tx_pga_gain = 199; // TODO bring under api control + _ad9862_regs.tx_hilbert = ad9862_regs_t::TX_HILBERT_DIS; + _ad9862_regs.interp = ad9862_regs_t::INTERP_2; + _ad9862_regs.tx_twos_comp = 1; + _ad9862_regs.fine_mode = ad9862_regs_t::FINE_MODE_BYPASS; + _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS; _ad9862_regs.dac_a_coarse_gain = 0x3; _ad9862_regs.dac_b_coarse_gain = 0x3; - _ad9862_regs.edges = ad9862_regs_t::EDGES_NORMAL; + _ad9862_regs.edges = ad9862_regs_t::EDGES_NORMAL; - //setup the dll + // setup the dll _ad9862_regs.input_clk_ctrl = ad9862_regs_t::INPUT_CLK_CTRL_EXTERNAL; - _ad9862_regs.dll_mult = ad9862_regs_t::DLL_MULT_2; - _ad9862_regs.dll_mode = ad9862_regs_t::DLL_MODE_FAST; + _ad9862_regs.dll_mult = ad9862_regs_t::DLL_MULT_2; + _ad9862_regs.dll_mode = ad9862_regs_t::DLL_MODE_FAST; - //write the register settings to the codec - for (uint8_t addr = 0; addr <= 25; addr++){ + // write the register settings to the codec + for (uint8_t addr = 0; addr <= 25; addr++) { this->send_reg(addr); } - //always start conversions for aux ADC + // always start conversions for aux ADC _ad9862_regs.start_a = 1; _ad9862_regs.start_b = 1; - //aux adc clock + // aux adc clock _ad9862_regs.clk_4 = ad9862_regs_t::CLK_4_1_4; this->send_reg(34); } -b100_codec_ctrl_impl::~b100_codec_ctrl_impl(void){ +b100_codec_ctrl_impl::~b100_codec_ctrl_impl(void) +{ UHD_SAFE_CALL( - //set aux dacs to zero - this->write_aux_dac(AUX_DAC_A, 0); - this->write_aux_dac(AUX_DAC_B, 0); + // set aux dacs to zero + this->write_aux_dac(AUX_DAC_A, 0); this->write_aux_dac(AUX_DAC_B, 0); this->write_aux_dac(AUX_DAC_C, 0); this->write_aux_dac(AUX_DAC_D, 0); - //power down + // power down _ad9862_regs.all_rx_pd = 1; this->send_reg(1); _ad9862_regs.tx_digital_pd = 1; - _ad9862_regs.tx_analog_pd = ad9862_regs_t::TX_ANALOG_PD_BOTH; - this->send_reg(8); - ) + _ad9862_regs.tx_analog_pd = ad9862_regs_t::TX_ANALOG_PD_BOTH; + this->send_reg(8);) } /*********************************************************************** * Codec Control Gain Control Methods **********************************************************************/ -static const int mtpgw = 255; //maximum tx pga gain word +static const int mtpgw = 255; // maximum tx pga gain word -void b100_codec_ctrl_impl::set_tx_pga_gain(double gain){ - int gain_word = int(mtpgw*(gain - tx_pga_gain_range.start())/(tx_pga_gain_range.stop() - tx_pga_gain_range.start())); +void b100_codec_ctrl_impl::set_tx_pga_gain(double gain) +{ + int gain_word = int(mtpgw * (gain - tx_pga_gain_range.start()) + / (tx_pga_gain_range.stop() - tx_pga_gain_range.start())); _ad9862_regs.tx_pga_gain = uhd::clip(gain_word, 0, mtpgw); this->send_reg(16); } -double b100_codec_ctrl_impl::get_tx_pga_gain(void){ - return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.stop() - tx_pga_gain_range.start())/mtpgw) + tx_pga_gain_range.start(); +double b100_codec_ctrl_impl::get_tx_pga_gain(void) +{ + return (_ad9862_regs.tx_pga_gain + * (tx_pga_gain_range.stop() - tx_pga_gain_range.start()) / mtpgw) + + tx_pga_gain_range.start(); } -static const int mrpgw = 0x14; //maximum rx pga gain word - -void b100_codec_ctrl_impl::set_rx_pga_gain(double gain, char which){ - int gain_word = int(mrpgw*(gain - rx_pga_gain_range.start())/(rx_pga_gain_range.stop() - rx_pga_gain_range.start())); - gain_word = uhd::clip(gain_word, 0, mrpgw); - switch(which){ - case 'A': - _ad9862_regs.rx_pga_a = gain_word; - this->send_reg(2); - return; - case 'B': - _ad9862_regs.rx_pga_b = gain_word; - this->send_reg(3); - return; - default: UHD_THROW_INVALID_CODE_PATH(); +static const int mrpgw = 0x14; // maximum rx pga gain word + +void b100_codec_ctrl_impl::set_rx_pga_gain(double gain, char which) +{ + int gain_word = int(mrpgw * (gain - rx_pga_gain_range.start()) + / (rx_pga_gain_range.stop() - rx_pga_gain_range.start())); + gain_word = uhd::clip(gain_word, 0, mrpgw); + switch (which) { + case 'A': + _ad9862_regs.rx_pga_a = gain_word; + this->send_reg(2); + return; + case 'B': + _ad9862_regs.rx_pga_b = gain_word; + this->send_reg(3); + return; + default: + UHD_THROW_INVALID_CODE_PATH(); } } -double b100_codec_ctrl_impl::get_rx_pga_gain(char which){ +double b100_codec_ctrl_impl::get_rx_pga_gain(char which) +{ int gain_word; - switch(which){ - case 'A': gain_word = _ad9862_regs.rx_pga_a; break; - case 'B': gain_word = _ad9862_regs.rx_pga_b; break; - default: UHD_THROW_INVALID_CODE_PATH(); + switch (which) { + case 'A': + gain_word = _ad9862_regs.rx_pga_a; + break; + case 'B': + gain_word = _ad9862_regs.rx_pga_b; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } - return (gain_word*(rx_pga_gain_range.stop() - rx_pga_gain_range.start())/mrpgw) + rx_pga_gain_range.start(); + return (gain_word * (rx_pga_gain_range.stop() - rx_pga_gain_range.start()) / mrpgw) + + rx_pga_gain_range.start(); } /*********************************************************************** * Codec Control AUX ADC Methods **********************************************************************/ -static double aux_adc_to_volts(uint8_t high, uint8_t low){ - return double((uint16_t(high) << 2) | low)*3.3/0x3ff; +static double aux_adc_to_volts(uint8_t high, uint8_t low) +{ + return double((uint16_t(high) << 2) | low) * 3.3 / 0x3ff; } -double b100_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ - switch(which){ - - case AUX_ADC_A1: - _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC1; - this->send_reg(34); //start conversion and select mux - this->recv_reg(28); //read the value (2 bytes, 2 reads) - this->recv_reg(29); - return aux_adc_to_volts(_ad9862_regs.aux_adc_a1_9_2, _ad9862_regs.aux_adc_a1_1_0); - case AUX_ADC_A2: - _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC2; - this->send_reg(34); //start conversion and select mux - this->recv_reg(26); //read the value (2 bytes, 2 reads) - this->recv_reg(27); - return aux_adc_to_volts(_ad9862_regs.aux_adc_a2_9_2, _ad9862_regs.aux_adc_a2_1_0); - - case AUX_ADC_B1: - _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC1; - this->send_reg(34); //start conversion and select mux - this->recv_reg(32); //read the value (2 bytes, 2 reads) - this->recv_reg(33); - return aux_adc_to_volts(_ad9862_regs.aux_adc_b1_9_2, _ad9862_regs.aux_adc_b1_1_0); - case AUX_ADC_B2: - _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC2; - this->send_reg(34); //start conversion and select mux - this->recv_reg(30); //read the value (2 bytes, 2 reads) - this->recv_reg(31); - return aux_adc_to_volts(_ad9862_regs.aux_adc_b2_9_2, _ad9862_regs.aux_adc_b2_1_0); +double b100_codec_ctrl_impl::read_aux_adc(aux_adc_t which) +{ + switch (which) { + case AUX_ADC_A1: + _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC1; + this->send_reg(34); // start conversion and select mux + this->recv_reg(28); // read the value (2 bytes, 2 reads) + this->recv_reg(29); + return aux_adc_to_volts( + _ad9862_regs.aux_adc_a1_9_2, _ad9862_regs.aux_adc_a1_1_0); + case AUX_ADC_A2: + _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC2; + this->send_reg(34); // start conversion and select mux + this->recv_reg(26); // read the value (2 bytes, 2 reads) + this->recv_reg(27); + return aux_adc_to_volts( + _ad9862_regs.aux_adc_a2_9_2, _ad9862_regs.aux_adc_a2_1_0); + + case AUX_ADC_B1: + _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC1; + this->send_reg(34); // start conversion and select mux + this->recv_reg(32); // read the value (2 bytes, 2 reads) + this->recv_reg(33); + return aux_adc_to_volts( + _ad9862_regs.aux_adc_b1_9_2, _ad9862_regs.aux_adc_b1_1_0); + case AUX_ADC_B2: + _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC2; + this->send_reg(34); // start conversion and select mux + this->recv_reg(30); // read the value (2 bytes, 2 reads) + this->recv_reg(31); + return aux_adc_to_volts( + _ad9862_regs.aux_adc_b2_9_2, _ad9862_regs.aux_adc_b2_1_0); } UHD_THROW_INVALID_CODE_PATH(); } @@ -214,64 +237,64 @@ double b100_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ /*********************************************************************** * Codec Control AUX DAC Methods **********************************************************************/ -void b100_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts){ - //special case for aux dac d (aka sigma delta word) - if (which == AUX_DAC_D){ - uint16_t dac_word = uhd::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff); +void b100_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts) +{ + // special case for aux dac d (aka sigma delta word) + if (which == AUX_DAC_D) { + uint16_t dac_word = uhd::clip(boost::math::iround(volts * 0xfff / 3.3), 0, 0xfff); _ad9862_regs.sig_delt_11_4 = uint8_t(dac_word >> 4); - _ad9862_regs.sig_delt_3_0 = uint8_t(dac_word & 0xf); + _ad9862_regs.sig_delt_3_0 = uint8_t(dac_word & 0xf); this->send_reg(42); this->send_reg(43); return; } - //calculate the dac word for aux dac a, b, c - uint8_t dac_word = uhd::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff); + // calculate the dac word for aux dac a, b, c + uint8_t dac_word = uhd::clip(boost::math::iround(volts * 0xff / 3.3), 0, 0xff); - //setup a lookup table for the aux dac params (reg ref, reg addr) + // setup a lookup table for the aux dac params (reg ref, reg addr) typedef std::tuple<uint8_t*, uint8_t> dac_params_t; - uhd::dict<aux_dac_t, dac_params_t> aux_dac_to_params = boost::assign::map_list_of - (AUX_DAC_A, dac_params_t(&_ad9862_regs.aux_dac_a, 36)) - (AUX_DAC_B, dac_params_t(&_ad9862_regs.aux_dac_b, 37)) - (AUX_DAC_C, dac_params_t(&_ad9862_regs.aux_dac_c, 38)) - ; + uhd::dict<aux_dac_t, dac_params_t> aux_dac_to_params = + boost::assign::map_list_of(AUX_DAC_A, dac_params_t(&_ad9862_regs.aux_dac_a, 36))( + AUX_DAC_B, dac_params_t(&_ad9862_regs.aux_dac_b, 37))( + AUX_DAC_C, dac_params_t(&_ad9862_regs.aux_dac_c, 38)); - //set the aux dac register + // set the aux dac register UHD_ASSERT_THROW(aux_dac_to_params.has_key(which)); uint8_t *reg_ref, reg_addr; std::tie(reg_ref, reg_addr) = aux_dac_to_params[which]; - *reg_ref = dac_word; + *reg_ref = dac_word; this->send_reg(reg_addr); } /*********************************************************************** * Codec Control SPI Methods **********************************************************************/ -void b100_codec_ctrl_impl::send_reg(uint8_t addr){ +void b100_codec_ctrl_impl::send_reg(uint8_t addr) +{ uint32_t reg = _ad9862_regs.get_write_reg(addr); - UHD_LOGGER_TRACE("B100") << "codec control write reg: " << std::hex << reg ; + UHD_LOGGER_TRACE("B100") << "codec control write reg: " << std::hex << reg; _iface->transact_spi( - B100_SPI_SS_AD9862, - spi_config_t::EDGE_RISE, - reg, 16, false /*no rb*/ + B100_SPI_SS_AD9862, spi_config_t::EDGE_RISE, reg, 16, false /*no rb*/ ); } -void b100_codec_ctrl_impl::recv_reg(uint8_t addr){ +void b100_codec_ctrl_impl::recv_reg(uint8_t addr) +{ uint32_t reg = _ad9862_regs.get_read_reg(addr); - UHD_LOGGER_TRACE("B100") << "codec control read reg: " << std::hex << reg ; + UHD_LOGGER_TRACE("B100") << "codec control read reg: " << std::hex << reg; uint32_t ret = _iface->transact_spi( - B100_SPI_SS_AD9862, - spi_config_t::EDGE_RISE, - reg, 16, true /*rb*/ + B100_SPI_SS_AD9862, spi_config_t::EDGE_RISE, reg, 16, true /*rb*/ ); - UHD_LOGGER_TRACE("B100") << "codec control read ret: " << std::hex << uint16_t(ret & 0xFF) ; - _ad9862_regs.set_reg(addr, uint8_t(ret&0xff)); + UHD_LOGGER_TRACE("B100") << "codec control read ret: " << std::hex + << uint16_t(ret & 0xFF); + _ad9862_regs.set_reg(addr, uint8_t(ret & 0xff)); } /*********************************************************************** * Codec Control Make **********************************************************************/ -b100_codec_ctrl::sptr b100_codec_ctrl::make(spi_iface::sptr iface){ +b100_codec_ctrl::sptr b100_codec_ctrl::make(spi_iface::sptr iface) +{ return sptr(new b100_codec_ctrl_impl(iface)); } diff --git a/host/lib/usrp/b100/codec_ctrl.hpp b/host/lib/usrp/b100/codec_ctrl.hpp index 5f77d00f9..36714fc60 100644 --- a/host/lib/usrp/b100/codec_ctrl.hpp +++ b/host/lib/usrp/b100/codec_ctrl.hpp @@ -8,8 +8,8 @@ #ifndef INCLUDED_B100_CODEC_CTRL_HPP #define INCLUDED_B100_CODEC_CTRL_HPP -#include <uhd/types/serial.hpp> #include <uhd/types/ranges.hpp> +#include <uhd/types/serial.hpp> #include <uhd/utils/noncopyable.hpp> #include <memory> @@ -18,7 +18,8 @@ * - Init/power down codec. * - Read aux adc, write aux dac. */ -class b100_codec_ctrl : uhd::noncopyable{ +class b100_codec_ctrl : uhd::noncopyable +{ public: typedef std::shared_ptr<b100_codec_ctrl> sptr; @@ -35,7 +36,7 @@ public: static sptr make(uhd::spi_iface::sptr iface); //! aux adc identifier constants - enum aux_adc_t{ + enum aux_adc_t { AUX_ADC_A2 = 0xA2, AUX_ADC_A1 = 0xA1, AUX_ADC_B2 = 0xB2, @@ -52,11 +53,11 @@ public: virtual double read_aux_adc(aux_adc_t which) = 0; //! aux dac identifier constants - enum aux_dac_t{ + enum aux_dac_t { AUX_DAC_A = 0xA, AUX_DAC_B = 0xB, AUX_DAC_C = 0xC, - AUX_DAC_D = 0xD //really the sigma delta output + AUX_DAC_D = 0xD // really the sigma delta output }; /*! diff --git a/host/lib/usrp/b100/dboard_iface.cpp b/host/lib/usrp/b100/dboard_iface.cpp index 2ea467fe4..627e7a876 100644 --- a/host/lib/usrp/b100/dboard_iface.cpp +++ b/host/lib/usrp/b100/dboard_iface.cpp @@ -8,10 +8,10 @@ #include "b100_regs.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" +#include <uhd/exception.hpp> +#include <uhd/types/dict.hpp> #include <uhd/types/serial.hpp> #include <uhd/usrp/dboard_iface.hpp> -#include <uhd/types/dict.hpp> -#include <uhd/exception.hpp> #include <uhdlib/usrp/cores/gpio_core_200.hpp> #include <boost/assign/list_of.hpp> @@ -19,36 +19,37 @@ using namespace uhd; using namespace uhd::usrp; using namespace boost::assign; -class b100_dboard_iface : public dboard_iface{ +class b100_dboard_iface : public dboard_iface +{ public: - - b100_dboard_iface( - timed_wb_iface::sptr wb_iface, + b100_dboard_iface(timed_wb_iface::sptr wb_iface, i2c_iface::sptr i2c_iface, spi_iface::sptr spi_iface, b100_clock_ctrl::sptr clock, - b100_codec_ctrl::sptr codec - ){ - _wb_iface = wb_iface; + b100_codec_ctrl::sptr codec) + { + _wb_iface = wb_iface; _i2c_iface = i2c_iface; _spi_iface = spi_iface; - _clock = clock; - _codec = codec; - _gpio = gpio_core_200::make(_wb_iface, TOREG(SR_GPIO), REG_RB_GPIO); + _clock = clock; + _codec = codec; + _gpio = gpio_core_200::make(_wb_iface, TOREG(SR_GPIO), REG_RB_GPIO); - //init the clock rate shadows + // init the clock rate shadows this->set_clock_rate(UNIT_RX, _clock->get_fpga_clock_rate()); this->set_clock_rate(UNIT_TX, _clock->get_fpga_clock_rate()); } - ~b100_dboard_iface(void){ + ~b100_dboard_iface(void) + { /* NOP */ } - special_props_t get_special_props(void){ + special_props_t get_special_props(void) + { special_props_t props; props.soft_clock_divider = false; - props.mangle_i2c_addrs = false; + props.mangle_i2c_addrs = false; return props; } @@ -57,7 +58,8 @@ public: void set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_pin_ctrl(unit_t unit); - void set_atr_reg(unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask = 0xffffffff); + void set_atr_reg( + unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_atr_reg(unit_t unit, atr_reg_t reg); void set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_gpio_ddr(unit_t unit); @@ -68,29 +70,22 @@ public: void set_command_time(const uhd::time_spec_t& t); uhd::time_spec_t get_command_time(void); - void write_i2c(uint16_t, const byte_vector_t &); + void write_i2c(uint16_t, const byte_vector_t&); byte_vector_t read_i2c(uint16_t, size_t); void write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits - ); + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits); uint32_t read_write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits - ); + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits); void set_clock_rate(unit_t, double); std::vector<double> get_clock_rates(unit_t); double get_clock_rate(unit_t); void set_clock_enabled(unit_t, bool); double get_codec_rate(unit_t); - void set_fe_connection(unit_t unit, const std::string&, const fe_connection_t& fe_conn); + void set_fe_connection( + unit_t unit, const std::string&, const fe_connection_t& fe_conn); private: timed_wb_iface::sptr _wb_iface; @@ -104,91 +99,123 @@ private: /*********************************************************************** * Make Function **********************************************************************/ -dboard_iface::sptr make_b100_dboard_iface( - timed_wb_iface::sptr wb_iface, +dboard_iface::sptr make_b100_dboard_iface(timed_wb_iface::sptr wb_iface, i2c_iface::sptr i2c_iface, spi_iface::sptr spi_iface, b100_clock_ctrl::sptr clock, - b100_codec_ctrl::sptr codec -){ - return dboard_iface::sptr(new b100_dboard_iface(wb_iface, i2c_iface, spi_iface, clock, codec)); + b100_codec_ctrl::sptr codec) +{ + return dboard_iface::sptr( + new b100_dboard_iface(wb_iface, i2c_iface, spi_iface, clock, codec)); } /*********************************************************************** * Clock Rates **********************************************************************/ -void b100_dboard_iface::set_clock_rate(unit_t unit, double rate){ - switch(unit){ - case UNIT_RX: return _clock->set_rx_dboard_clock_rate(rate); - case UNIT_TX: return _clock->set_tx_dboard_clock_rate(rate); - case UNIT_BOTH: set_clock_rate(UNIT_RX, rate); set_clock_rate(UNIT_TX, rate); return; +void b100_dboard_iface::set_clock_rate(unit_t unit, double rate) +{ + switch (unit) { + case UNIT_RX: + return _clock->set_rx_dboard_clock_rate(rate); + case UNIT_TX: + return _clock->set_tx_dboard_clock_rate(rate); + case UNIT_BOTH: + set_clock_rate(UNIT_RX, rate); + set_clock_rate(UNIT_TX, rate); + return; } } -std::vector<double> b100_dboard_iface::get_clock_rates(unit_t unit){ - switch(unit){ - case UNIT_RX: return _clock->get_rx_dboard_clock_rates(); - case UNIT_TX: return _clock->get_tx_dboard_clock_rates(); - default: UHD_THROW_INVALID_CODE_PATH(); +std::vector<double> b100_dboard_iface::get_clock_rates(unit_t unit) +{ + switch (unit) { + case UNIT_RX: + return _clock->get_rx_dboard_clock_rates(); + case UNIT_TX: + return _clock->get_tx_dboard_clock_rates(); + default: + UHD_THROW_INVALID_CODE_PATH(); } } -double b100_dboard_iface::get_clock_rate(unit_t unit){ - switch(unit){ - case UNIT_RX: return _clock->get_rx_clock_rate(); - case UNIT_TX: return _clock->get_tx_clock_rate(); - default: UHD_THROW_INVALID_CODE_PATH(); +double b100_dboard_iface::get_clock_rate(unit_t unit) +{ + switch (unit) { + case UNIT_RX: + return _clock->get_rx_clock_rate(); + case UNIT_TX: + return _clock->get_tx_clock_rate(); + default: + UHD_THROW_INVALID_CODE_PATH(); } } -void b100_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ - switch(unit){ - case UNIT_RX: return _clock->enable_rx_dboard_clock(enb); - case UNIT_TX: return _clock->enable_tx_dboard_clock(enb); - case UNIT_BOTH: set_clock_enabled(UNIT_RX, enb); set_clock_enabled(UNIT_TX, enb); return; +void b100_dboard_iface::set_clock_enabled(unit_t unit, bool enb) +{ + switch (unit) { + case UNIT_RX: + return _clock->enable_rx_dboard_clock(enb); + case UNIT_TX: + return _clock->enable_tx_dboard_clock(enb); + case UNIT_BOTH: + set_clock_enabled(UNIT_RX, enb); + set_clock_enabled(UNIT_TX, enb); + return; } } -double b100_dboard_iface::get_codec_rate(unit_t){ +double b100_dboard_iface::get_codec_rate(unit_t) +{ return _clock->get_fpga_clock_rate(); } /*********************************************************************** * GPIO **********************************************************************/ -void b100_dboard_iface::set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask){ +void b100_dboard_iface::set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask) +{ _gpio->set_pin_ctrl(unit, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); } -uint32_t b100_dboard_iface::get_pin_ctrl(unit_t unit){ +uint32_t b100_dboard_iface::get_pin_ctrl(unit_t unit) +{ return static_cast<uint32_t>(_gpio->get_pin_ctrl(unit)); } -void b100_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask){ - _gpio->set_atr_reg(unit, reg, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); +void b100_dboard_iface::set_atr_reg( + unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask) +{ + _gpio->set_atr_reg( + unit, reg, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); } -uint32_t b100_dboard_iface::get_atr_reg(unit_t unit, atr_reg_t reg){ +uint32_t b100_dboard_iface::get_atr_reg(unit_t unit, atr_reg_t reg) +{ return static_cast<uint32_t>(_gpio->get_atr_reg(unit, reg)); } -void b100_dboard_iface::set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask){ +void b100_dboard_iface::set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask) +{ _gpio->set_gpio_ddr(unit, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); } -uint32_t b100_dboard_iface::get_gpio_ddr(unit_t unit){ +uint32_t b100_dboard_iface::get_gpio_ddr(unit_t unit) +{ return static_cast<uint32_t>(_gpio->get_gpio_ddr(unit)); } -void b100_dboard_iface::set_gpio_out(unit_t unit, uint32_t value, uint32_t mask){ +void b100_dboard_iface::set_gpio_out(unit_t unit, uint32_t value, uint32_t mask) +{ _gpio->set_gpio_out(unit, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); } -uint32_t b100_dboard_iface::get_gpio_out(unit_t unit){ +uint32_t b100_dboard_iface::get_gpio_out(unit_t unit) +{ return static_cast<uint32_t>(_gpio->get_gpio_out(unit)); } -uint32_t b100_dboard_iface::read_gpio(unit_t unit){ +uint32_t b100_dboard_iface::read_gpio(unit_t unit) +{ return _gpio->read_gpio(unit); } @@ -200,70 +227,64 @@ uint32_t b100_dboard_iface::read_gpio(unit_t unit){ * \param unit the dboard interface unit type enum * \return the slave device number */ -static uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){ - switch(unit){ - case dboard_iface::UNIT_TX: return B100_SPI_SS_TX_DB; - case dboard_iface::UNIT_RX: return B100_SPI_SS_RX_DB; - default: UHD_THROW_INVALID_CODE_PATH(); +static uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit) +{ + switch (unit) { + case dboard_iface::UNIT_TX: + return B100_SPI_SS_TX_DB; + case dboard_iface::UNIT_RX: + return B100_SPI_SS_RX_DB; + default: + UHD_THROW_INVALID_CODE_PATH(); } } void b100_dboard_iface::write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits -){ + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits) +{ _spi_iface->write_spi(unit_to_otw_spi_dev(unit), config, data, num_bits); } uint32_t b100_dboard_iface::read_write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits -){ + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits) +{ return _spi_iface->read_spi(unit_to_otw_spi_dev(unit), config, data, num_bits); } /*********************************************************************** * I2C **********************************************************************/ -void b100_dboard_iface::write_i2c(uint16_t addr, const byte_vector_t &bytes){ +void b100_dboard_iface::write_i2c(uint16_t addr, const byte_vector_t& bytes) +{ return _i2c_iface->write_i2c(addr, bytes); } -byte_vector_t b100_dboard_iface::read_i2c(uint16_t addr, size_t num_bytes){ +byte_vector_t b100_dboard_iface::read_i2c(uint16_t addr, size_t num_bytes) +{ return _i2c_iface->read_i2c(addr, num_bytes); } /*********************************************************************** * Aux DAX/ADC **********************************************************************/ -void b100_dboard_iface::write_aux_dac(dboard_iface::unit_t, aux_dac_t which, double value){ - //same aux dacs for each unit - static const uhd::dict<aux_dac_t, b100_codec_ctrl::aux_dac_t> which_to_aux_dac = map_list_of - (AUX_DAC_A, b100_codec_ctrl::AUX_DAC_A) - (AUX_DAC_B, b100_codec_ctrl::AUX_DAC_B) - (AUX_DAC_C, b100_codec_ctrl::AUX_DAC_C) - (AUX_DAC_D, b100_codec_ctrl::AUX_DAC_D) - ; +void b100_dboard_iface::write_aux_dac(dboard_iface::unit_t, aux_dac_t which, double value) +{ + // same aux dacs for each unit + static const uhd::dict<aux_dac_t, b100_codec_ctrl::aux_dac_t> which_to_aux_dac = + map_list_of(AUX_DAC_A, b100_codec_ctrl::AUX_DAC_A)( + AUX_DAC_B, b100_codec_ctrl::AUX_DAC_B)(AUX_DAC_C, b100_codec_ctrl::AUX_DAC_C)( + AUX_DAC_D, b100_codec_ctrl::AUX_DAC_D); _codec->write_aux_dac(which_to_aux_dac[which], value); } -double b100_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, aux_adc_t which){ - static const uhd::dict< - unit_t, uhd::dict<aux_adc_t, b100_codec_ctrl::aux_adc_t> - > unit_to_which_to_aux_adc = map_list_of - (UNIT_RX, map_list_of - (AUX_ADC_A, b100_codec_ctrl::AUX_ADC_A1) - (AUX_ADC_B, b100_codec_ctrl::AUX_ADC_B1) - ) - (UNIT_TX, map_list_of - (AUX_ADC_A, b100_codec_ctrl::AUX_ADC_A2) - (AUX_ADC_B, b100_codec_ctrl::AUX_ADC_B2) - ) - ; +double b100_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, aux_adc_t which) +{ + static const uhd::dict<unit_t, uhd::dict<aux_adc_t, b100_codec_ctrl::aux_adc_t>> + unit_to_which_to_aux_adc = map_list_of(UNIT_RX, + map_list_of(AUX_ADC_A, b100_codec_ctrl::AUX_ADC_A1)( + AUX_ADC_B, b100_codec_ctrl::AUX_ADC_B1))(UNIT_TX, + map_list_of(AUX_ADC_A, b100_codec_ctrl::AUX_ADC_A2)( + AUX_ADC_B, b100_codec_ctrl::AUX_ADC_B2)); return _codec->read_aux_adc(unit_to_which_to_aux_adc[unit][which]); } @@ -277,7 +298,9 @@ uhd::time_spec_t b100_dboard_iface::get_command_time(void) return _wb_iface->get_time(); } -void b100_dboard_iface::set_fe_connection(unit_t, const std::string&, const fe_connection_t&) +void b100_dboard_iface::set_fe_connection( + unit_t, const std::string&, const fe_connection_t&) { - throw uhd::not_implemented_error("fe connection configuration support not implemented"); + throw uhd::not_implemented_error( + "fe connection configuration support not implemented"); } diff --git a/host/lib/usrp/b100/fifo_ctrl_excelsior.cpp b/host/lib/usrp/b100/fifo_ctrl_excelsior.cpp index 6eed5c813..4a21770b8 100644 --- a/host/lib/usrp/b100/fifo_ctrl_excelsior.cpp +++ b/host/lib/usrp/b100/fifo_ctrl_excelsior.cpp @@ -6,25 +6,25 @@ // #include "fifo_ctrl_excelsior.hpp" -#include <uhdlib/usrp/common/async_packet_handler.hpp> #include <uhd/exception.hpp> -#include <uhd/utils/log.hpp> +#include <uhd/transport/bounded_buffer.hpp> +#include <uhd/transport/vrt_if_packet.hpp> #include <uhd/utils/byteswap.hpp> -#include <uhd/utils/tasks.hpp> +#include <uhd/utils/log.hpp> #include <uhd/utils/safe_call.hpp> +#include <uhd/utils/tasks.hpp> #include <uhd/utils/thread.hpp> -#include <uhd/transport/vrt_if_packet.hpp> -#include <uhd/transport/bounded_buffer.hpp> +#include <uhdlib/usrp/common/async_packet_handler.hpp> #include <mutex> using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; -static const size_t POKE32_CMD = (1 << 8); -static const size_t PEEK32_CMD = 0; +static const size_t POKE32_CMD = (1 << 8); +static const size_t PEEK32_CMD = 0; static const double ACK_TIMEOUT = 0.5; -static const double MASSIVE_TIMEOUT = 10.0; //for when we wait on a timed command +static const double MASSIVE_TIMEOUT = 10.0; // for when we wait on a timed command static const uint32_t MAX_SEQS_OUT = 15; #define SPI_DIV _config.spi_base + 0 @@ -32,81 +32,94 @@ static const uint32_t MAX_SEQS_OUT = 15; #define SPI_DATA _config.spi_base + 8 #define SPI_DIVIDER 4 -struct ctrl_result_t{ +struct ctrl_result_t +{ uint32_t msg[2]; }; -class fifo_ctrl_excelsior_impl : public fifo_ctrl_excelsior{ +class fifo_ctrl_excelsior_impl : public fifo_ctrl_excelsior +{ public: - - fifo_ctrl_excelsior_impl(zero_copy_if::sptr xport, const fifo_ctrl_excelsior_config &config): - _xport(xport), - _config(config), - _seq_out(0), - _seq_ack(0), - _timeout(ACK_TIMEOUT), - _async_fifo(1000), - _ctrl_fifo(MAX_SEQS_OUT+1) + fifo_ctrl_excelsior_impl( + zero_copy_if::sptr xport, const fifo_ctrl_excelsior_config& config) + : _xport(xport) + , _config(config) + , _seq_out(0) + , _seq_ack(0) + , _timeout(ACK_TIMEOUT) + , _async_fifo(1000) + , _ctrl_fifo(MAX_SEQS_OUT + 1) { - while (_xport->get_recv_buff(0.0)){} //flush + while (_xport->get_recv_buff(0.0)) { + } // flush this->set_time(uhd::time_spec_t(0.0)); - this->set_tick_rate(1.0); //something possible but bogus - _msg_task = task::make([this](){ this->handle_msg(); }); + this->set_tick_rate(1.0); // something possible but bogus + _msg_task = task::make([this]() { this->handle_msg(); }); this->init_spi(); } - ~fifo_ctrl_excelsior_impl(void){ - _timeout = ACK_TIMEOUT; //reset timeout to something small + ~fifo_ctrl_excelsior_impl(void) + { + _timeout = ACK_TIMEOUT; // reset timeout to something small UHD_SAFE_CALL( - this->peek32(0); //dummy peek with the purpose of ack'ing all packets + this->peek32(0); // dummy peek with the purpose of ack'ing all packets ) } - bool pop_async_msg(async_metadata_t &async_metadata, double timeout){ + bool pop_async_msg(async_metadata_t& async_metadata, double timeout) + { return _async_fifo.pop_with_timed_wait(async_metadata, timeout); } - void handle_msg(void){ + void handle_msg(void) + { managed_recv_buffer::sptr buff = _xport->get_recv_buff(); - if (not buff) return; - const uint32_t *pkt = buff->cast<const uint32_t *>(); + if (not buff) + return; + const uint32_t* pkt = buff->cast<const uint32_t*>(); vrt::if_packet_info_t packet_info; - packet_info.num_packet_words32 = buff->size()/sizeof(uint32_t); - try{ + packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t); + try { vrt::if_hdr_unpack_le(pkt, packet_info); - } - catch(const std::exception &ex){ + } catch (const std::exception& ex) { UHD_LOGGER_ERROR("UHD") << "FIFO ctrl bad VITA packet: " << ex.what(); } - if (packet_info.has_sid and packet_info.sid == _config.ctrl_sid_base){ + if (packet_info.has_sid and packet_info.sid == _config.ctrl_sid_base) { ctrl_result_t res = ctrl_result_t(); - res.msg[0] = uhd::wtohx(pkt[packet_info.num_header_words32+0]); - res.msg[1] = uhd::wtohx(pkt[packet_info.num_header_words32+1]); + res.msg[0] = uhd::wtohx(pkt[packet_info.num_header_words32 + 0]); + res.msg[1] = uhd::wtohx(pkt[packet_info.num_header_words32 + 1]); _ctrl_fifo.push_with_haste(res); - } - else if (packet_info.has_sid and packet_info.sid >= _config.async_sid_base and packet_info.sid <= _config.async_sid_base + _config.num_async_chan){ + } else if (packet_info.has_sid and packet_info.sid >= _config.async_sid_base + and packet_info.sid + <= _config.async_sid_base + _config.num_async_chan) { async_metadata_t metadata; - load_metadata_from_buff(uhd::wtohx<uint32_t>, metadata, packet_info, pkt, _tick_rate, packet_info.sid - _config.async_sid_base); + load_metadata_from_buff(uhd::wtohx<uint32_t>, + metadata, + packet_info, + pkt, + _tick_rate, + packet_info.sid - _config.async_sid_base); _async_fifo.push_with_pop_on_full(metadata); standard_async_msg_prints(metadata); - } - else{ - UHD_LOGGER_ERROR("UHD") << "FIFO ctrl got unknown SID: " << packet_info.sid ; + } else { + UHD_LOGGER_ERROR("UHD") << "FIFO ctrl got unknown SID: " << packet_info.sid; } } /******************************************************************* * Peek and poke 32 bit implementation ******************************************************************/ - void poke32(const wb_addr_type addr, const uint32_t data){ + void poke32(const wb_addr_type addr, const uint32_t data) + { std::lock_guard<std::mutex> lock(_mutex); this->send_pkt(addr, data, POKE32_CMD); - this->wait_for_ack(_seq_out-MAX_SEQS_OUT); + this->wait_for_ack(_seq_out - MAX_SEQS_OUT); } - uint32_t peek32(const wb_addr_type addr){ + uint32_t peek32(const wb_addr_type addr) + { std::lock_guard<std::mutex> lock(_mutex); this->send_pkt(addr, 0, PEEK32_CMD); @@ -117,58 +130,62 @@ public: /******************************************************************* * Peek and poke 16 bit not implemented ******************************************************************/ - void poke16(const wb_addr_type, const uint16_t){ + void poke16(const wb_addr_type, const uint16_t) + { throw uhd::not_implemented_error("poke16 not implemented in fifo ctrl module"); } - uint16_t peek16(const wb_addr_type){ + uint16_t peek16(const wb_addr_type) + { throw uhd::not_implemented_error("peek16 not implemented in fifo ctrl module"); } /******************************************************************* * FIFO controlled SPI implementation ******************************************************************/ - void init_spi(void){ + void init_spi(void) + { std::lock_guard<std::mutex> lock(_mutex); this->send_pkt(SPI_DIV, SPI_DIVIDER, POKE32_CMD); - this->wait_for_ack(_seq_out-MAX_SEQS_OUT); + this->wait_for_ack(_seq_out - MAX_SEQS_OUT); _ctrl_word_cache = 0; // force update first time around } - uint32_t transact_spi( - int which_slave, - const spi_config_t &config, + uint32_t transact_spi(int which_slave, + const spi_config_t& config, uint32_t data, size_t num_bits, - bool readback - ){ + bool readback) + { std::lock_guard<std::mutex> lock(_mutex); - //load control word + // load control word uint32_t ctrl_word = 0; ctrl_word |= ((which_slave & 0xffffff) << 0); ctrl_word |= ((num_bits & 0x3ff) << 24); - if (config.mosi_edge == spi_config_t::EDGE_FALL) ctrl_word |= (1 << 31); - if (config.miso_edge == spi_config_t::EDGE_RISE) ctrl_word |= (1 << 30); + if (config.mosi_edge == spi_config_t::EDGE_FALL) + ctrl_word |= (1 << 31); + if (config.miso_edge == spi_config_t::EDGE_RISE) + ctrl_word |= (1 << 30); - //load data word (must be in upper bits) + // load data word (must be in upper bits) const uint32_t data_out = data << (32 - num_bits); - //conditionally send control word - if (_ctrl_word_cache != ctrl_word){ + // conditionally send control word + if (_ctrl_word_cache != ctrl_word) { this->send_pkt(SPI_CTRL, ctrl_word, POKE32_CMD); - this->wait_for_ack(_seq_out-MAX_SEQS_OUT); + this->wait_for_ack(_seq_out - MAX_SEQS_OUT); _ctrl_word_cache = ctrl_word; } - //send data word + // send data word this->send_pkt(SPI_DATA, data_out, POKE32_CMD); - this->wait_for_ack(_seq_out-MAX_SEQS_OUT); + this->wait_for_ack(_seq_out - MAX_SEQS_OUT); - //conditional readback - if (readback){ + // conditional readback + if (readback) { this->send_pkt(_config.spi_rb, 0, PEEK32_CMD); return this->wait_for_ack(_seq_out); } @@ -179,11 +196,13 @@ public: /******************************************************************* * Update methods for time ******************************************************************/ - void set_time(const uhd::time_spec_t &time){ + void set_time(const uhd::time_spec_t& time) + { std::lock_guard<std::mutex> lock(_mutex); - _time = time; + _time = time; _use_time = _time != uhd::time_spec_t(0.0); - if (_use_time) _timeout = MASSIVE_TIMEOUT; //permanently sets larger timeout + if (_use_time) + _timeout = MASSIVE_TIMEOUT; // permanently sets larger timeout } uhd::time_spec_t get_time(void) @@ -192,65 +211,69 @@ public: return _time; } - void set_tick_rate(const double rate){ + void set_tick_rate(const double rate) + { std::lock_guard<std::mutex> lock(_mutex); _tick_rate = rate; } private: - /******************************************************************* * Primary control and interaction private methods ******************************************************************/ - UHD_INLINE void send_pkt(wb_addr_type addr, uint32_t data, int cmd){ + UHD_INLINE void send_pkt(wb_addr_type addr, uint32_t data, int cmd) + { managed_send_buffer::sptr buff = _xport->get_send_buff(); - if (not buff){ + if (not buff) { throw uhd::runtime_error("fifo ctrl timed out getting a send buffer"); } - uint32_t *pkt = buff->cast<uint32_t *>(); + uint32_t* pkt = buff->cast<uint32_t*>(); - //load packet info + // load packet info vrt::if_packet_info_t packet_info; - packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CONTEXT; + packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CONTEXT; packet_info.num_payload_words32 = 2; - packet_info.num_payload_bytes = packet_info.num_payload_words32*sizeof(uint32_t); + packet_info.num_payload_bytes = + packet_info.num_payload_words32 * sizeof(uint32_t); packet_info.packet_count = ++_seq_out; - packet_info.tsf = _time.to_ticks(_tick_rate); - packet_info.sob = false; - packet_info.eob = false; - packet_info.has_sid = false; - packet_info.has_cid = false; - packet_info.has_tsi = false; - packet_info.has_tsf = _use_time; - packet_info.has_tlr = false; - - //load header + packet_info.tsf = _time.to_ticks(_tick_rate); + packet_info.sob = false; + packet_info.eob = false; + packet_info.has_sid = false; + packet_info.has_cid = false; + packet_info.has_tsi = false; + packet_info.has_tsf = _use_time; + packet_info.has_tlr = false; + + // load header vrt::if_hdr_pack_le(pkt, packet_info); - //load payload - const uint32_t ctrl_word = (addr/4 & 0xff) | cmd | (_seq_out << 16); - pkt[packet_info.num_header_words32+0] = uhd::htowx(ctrl_word); - pkt[packet_info.num_header_words32+1] = uhd::htowx(data); + // load payload + const uint32_t ctrl_word = (addr / 4 & 0xff) | cmd | (_seq_out << 16); + pkt[packet_info.num_header_words32 + 0] = uhd::htowx(ctrl_word); + pkt[packet_info.num_header_words32 + 1] = uhd::htowx(data); - //send the buffer over the interface - buff->commit(sizeof(uint32_t)*(packet_info.num_packet_words32)); + // send the buffer over the interface + buff->commit(sizeof(uint32_t) * (packet_info.num_packet_words32)); } - UHD_INLINE bool wraparound_lt16(const int16_t i0, const int16_t i1){ - if (((i0 ^ i1) & 0x8000) == 0) //same sign bits + UHD_INLINE bool wraparound_lt16(const int16_t i0, const int16_t i1) + { + if (((i0 ^ i1) & 0x8000) == 0) // same sign bits return uint16_t(i0) < uint16_t(i1); return int16_t(i1 - i0) > 0; } - UHD_INLINE uint32_t wait_for_ack(const uint16_t seq_to_ack){ - - while (wraparound_lt16(_seq_ack, seq_to_ack)){ + UHD_INLINE uint32_t wait_for_ack(const uint16_t seq_to_ack) + { + while (wraparound_lt16(_seq_ack, seq_to_ack)) { ctrl_result_t res = ctrl_result_t(); - if (not _ctrl_fifo.pop_with_timed_wait(res, _timeout)){ + if (not _ctrl_fifo.pop_with_timed_wait(res, _timeout)) { throw uhd::runtime_error("fifo ctrl timed out looking for acks"); } _seq_ack = res.msg[0] >> 16; - if (_seq_ack == seq_to_ack) return res.msg[1]; + if (_seq_ack == seq_to_ack) + return res.msg[1]; } return 0; @@ -272,7 +295,8 @@ private: }; -fifo_ctrl_excelsior::sptr fifo_ctrl_excelsior::make(zero_copy_if::sptr xport, const fifo_ctrl_excelsior_config &config) +fifo_ctrl_excelsior::sptr fifo_ctrl_excelsior::make( + zero_copy_if::sptr xport, const fifo_ctrl_excelsior_config& config) { return sptr(new fifo_ctrl_excelsior_impl(xport, config)); } diff --git a/host/lib/usrp/b100/fifo_ctrl_excelsior.hpp b/host/lib/usrp/b100/fifo_ctrl_excelsior.hpp index 27da0026c..69b2dd4fc 100644 --- a/host/lib/usrp/b100/fifo_ctrl_excelsior.hpp +++ b/host/lib/usrp/b100/fifo_ctrl_excelsior.hpp @@ -8,13 +8,13 @@ #ifndef INCLUDED_B200_CTRL_HPP #define INCLUDED_B200_CTRL_HPP -#include <uhd/types/time_spec.hpp> +#include <uhd/transport/zero_copy.hpp> #include <uhd/types/metadata.hpp> #include <uhd/types/serial.hpp> -#include <uhd/transport/zero_copy.hpp> -#include <memory> -#include <boost/utility.hpp> +#include <uhd/types/time_spec.hpp> #include <uhd/types/wb_iface.hpp> +#include <boost/utility.hpp> +#include <memory> #include <string> @@ -36,16 +36,14 @@ public: typedef std::shared_ptr<fifo_ctrl_excelsior> sptr; //! Make a new control object - static sptr make( - uhd::transport::zero_copy_if::sptr xport, - const fifo_ctrl_excelsior_config &config - ); + static sptr make(uhd::transport::zero_copy_if::sptr xport, + const fifo_ctrl_excelsior_config& config); //! Set the tick rate (converting time into ticks) virtual void set_tick_rate(const double rate) = 0; //! Pop an async message from the queue or timeout - virtual bool pop_async_msg(uhd::async_metadata_t &async_metadata, double timeout) = 0; + virtual bool pop_async_msg(uhd::async_metadata_t& async_metadata, double timeout) = 0; }; #endif /* INCLUDED_B200_CTRL_HPP */ diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index c50327271..8aad480e7 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -19,146 +19,169 @@ using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; -void b100_impl::update_rates(void){ +void b100_impl::update_rates(void) +{ const fs_path mb_path = "/mboards/0"; _tree->access<double>(mb_path / "tick_rate").update(); - //and now that the tick rate is set, init the host rates to something - for(const std::string &name: _tree->list(mb_path / "rx_dsps")){ + // and now that the tick rate is set, init the host rates to something + for (const std::string& name : _tree->list(mb_path / "rx_dsps")) { _tree->access<double>(mb_path / "rx_dsps" / name / "rate" / "value").update(); } - for(const std::string &name: _tree->list(mb_path / "tx_dsps")){ + for (const std::string& name : _tree->list(mb_path / "tx_dsps")) { _tree->access<double>(mb_path / "tx_dsps" / name / "rate" / "value").update(); } } -void b100_impl::update_tick_rate(const double rate){ - - //update the tick rate on all existing streamers -> thread safe - for (size_t i = 0; i < _rx_streamers.size(); i++){ +void b100_impl::update_tick_rate(const double rate) +{ + // update the tick rate on all existing streamers -> thread safe + for (size_t i = 0; i < _rx_streamers.size(); i++) { std::shared_ptr<sph::recv_packet_streamer> my_streamer = std::dynamic_pointer_cast<sph::recv_packet_streamer>(_rx_streamers[i].lock()); - if (my_streamer.get() == NULL) continue; + if (my_streamer.get() == NULL) + continue; my_streamer->set_tick_rate(rate); } - for (size_t i = 0; i < _tx_streamers.size(); i++){ + for (size_t i = 0; i < _tx_streamers.size(); i++) { std::shared_ptr<sph::send_packet_streamer> my_streamer = std::dynamic_pointer_cast<sph::send_packet_streamer>(_tx_streamers[i].lock()); - if (my_streamer.get() == NULL) continue; + if (my_streamer.get() == NULL) + continue; my_streamer->set_tick_rate(rate); } } -void b100_impl::update_rx_samp_rate(const size_t dspno, const double rate){ +void b100_impl::update_rx_samp_rate(const size_t dspno, const double rate) +{ std::shared_ptr<sph::recv_packet_streamer> my_streamer = std::dynamic_pointer_cast<sph::recv_packet_streamer>(_rx_streamers[dspno].lock()); - if (my_streamer.get() == NULL) return; + if (my_streamer.get() == NULL) + return; my_streamer->set_samp_rate(rate); const double adj = _rx_dsps[dspno]->get_scaling_adjustment(); my_streamer->set_scale_factor(adj); } -void b100_impl::update_tx_samp_rate(const size_t dspno, const double rate){ +void b100_impl::update_tx_samp_rate(const size_t dspno, const double rate) +{ std::shared_ptr<sph::send_packet_streamer> my_streamer = std::dynamic_pointer_cast<sph::send_packet_streamer>(_tx_streamers[dspno].lock()); - if (my_streamer.get() == NULL) return; + if (my_streamer.get() == NULL) + return; my_streamer->set_samp_rate(rate); const double adj = _tx_dsp->get_scaling_adjustment(); my_streamer->set_scale_factor(adj); } -void b100_impl::update_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){ +void b100_impl::update_rx_subdev_spec(const uhd::usrp::subdev_spec_t& spec) +{ fs_path root = "/mboards/0/dboards"; - //sanity checking + // sanity checking validate_subdev_spec(_tree, spec, "rx"); - //setup mux for this spec + // setup mux for this spec bool fe_swapped = false; - for (size_t i = 0; i < spec.size(); i++){ - const std::string conn = _tree->access<std::string>(root / spec[i].db_name / "rx_frontends" / spec[i].sd_name / "connection").get(); - if (i == 0 and (conn == "QI" or conn == "Q")) fe_swapped = true; + for (size_t i = 0; i < spec.size(); i++) { + const std::string conn = + _tree + ->access<std::string>(root / spec[i].db_name / "rx_frontends" + / spec[i].sd_name / "connection") + .get(); + if (i == 0 and (conn == "QI" or conn == "Q")) + fe_swapped = true; _rx_dsps[i]->set_mux(conn, fe_swapped); } _rx_fe->set_mux(fe_swapped); } -void b100_impl::update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){ +void b100_impl::update_tx_subdev_spec(const uhd::usrp::subdev_spec_t& spec) +{ fs_path root = "/mboards/0/dboards"; - //sanity checking + // sanity checking validate_subdev_spec(_tree, spec, "tx"); - //set the mux for this spec - const std::string conn = _tree->access<std::string>(root / spec[0].db_name / "tx_frontends" / spec[0].sd_name / "connection").get(); + // set the mux for this spec + const std::string conn = + _tree + ->access<std::string>( + root / spec[0].db_name / "tx_frontends" / spec[0].sd_name / "connection") + .get(); _tx_fe->set_mux(conn); } /*********************************************************************** * Async Data **********************************************************************/ -bool b100_impl::recv_async_msg( - async_metadata_t &async_metadata, double timeout -){ +bool b100_impl::recv_async_msg(async_metadata_t& async_metadata, double timeout) +{ return _fifo_ctrl->pop_async_msg(async_metadata, timeout); } /*********************************************************************** * Receive streamer **********************************************************************/ -rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){ +rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t& args_) +{ stream_args_t args = args_; - //setup defaults for unspecified values - args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; - args.channels = args.channels.empty()? std::vector<size_t>(1, 0) : args.channels; - - //calculate packet size - static const size_t hdr_size = 0 - + vrt::max_if_hdr_words32*sizeof(uint32_t) - + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - - sizeof(vrt::if_packet_info_t().cid) //no class id ever used - - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used - ; + // setup defaults for unspecified values + args.otw_format = args.otw_format.empty() ? "sc16" : args.otw_format; + args.channels = args.channels.empty() ? std::vector<size_t>(1, 0) : args.channels; + + // calculate packet size + static const size_t hdr_size = + 0 + vrt::max_if_hdr_words32 * sizeof(uint32_t) + + sizeof(vrt::if_packet_info_t().tlr) // forced to have trailer + - sizeof(vrt::if_packet_info_t().cid) // no class id ever used + - sizeof(vrt::if_packet_info_t().tsi) // no int time ever used + ; const size_t bpp = _data_transport->get_recv_frame_size() - hdr_size; const size_t bpi = convert::get_bytes_per_item(args.otw_format); - const size_t spp = unsigned(args.args.cast<double>("spp", bpp/bpi)); + const size_t spp = unsigned(args.args.cast<double>("spp", bpp / bpi)); - //make the new streamer given the samples per packet - std::shared_ptr<sph::recv_packet_streamer> my_streamer = std::make_shared<sph::recv_packet_streamer>(spp); + // make the new streamer given the samples per packet + std::shared_ptr<sph::recv_packet_streamer> my_streamer = + std::make_shared<sph::recv_packet_streamer>(spp); - //init some streamer stuff + // init some streamer stuff my_streamer->resize(args.channels.size()); my_streamer->set_vrt_unpacker(&vrt::if_hdr_unpack_le); - //set the converter + // set the converter uhd::convert::id_type id; - id.input_format = args.otw_format + "_item32_le"; - id.num_inputs = 1; + id.input_format = args.otw_format + "_item32_le"; + id.num_inputs = 1; id.output_format = args.cpu_format; - id.num_outputs = 1; + id.num_outputs = 1; my_streamer->set_converter(id); - //bind callbacks for the handler - for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++){ + // bind callbacks for the handler + for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++) { const size_t dsp = args.channels[chan_i]; - _rx_dsps[dsp]->set_nsamps_per_packet(spp); //seems to be a good place to set this + _rx_dsps[dsp]->set_nsamps_per_packet(spp); // seems to be a good place to set this _rx_dsps[dsp]->setup(args); _recv_demuxer->realloc_sid(B100_RX_SID_BASE + dsp); - my_streamer->set_xport_chan_get_buff(chan_i, std::bind( - &recv_packet_demuxer_3000::get_recv_buff, _recv_demuxer, B100_RX_SID_BASE + dsp, std::placeholders::_1 - ), true /*flush*/); - my_streamer->set_overflow_handler(chan_i, std::bind( - &rx_dsp_core_200::handle_overflow, _rx_dsps[dsp] - )); - my_streamer->set_issue_stream_cmd(chan_i, std::bind( - &rx_dsp_core_200::issue_stream_command, _rx_dsps[dsp], std::placeholders::_1)); - _rx_streamers[dsp] = my_streamer; //store weak pointer + my_streamer->set_xport_chan_get_buff(chan_i, + std::bind(&recv_packet_demuxer_3000::get_recv_buff, + _recv_demuxer, + B100_RX_SID_BASE + dsp, + std::placeholders::_1), + true /*flush*/); + my_streamer->set_overflow_handler( + chan_i, std::bind(&rx_dsp_core_200::handle_overflow, _rx_dsps[dsp])); + my_streamer->set_issue_stream_cmd(chan_i, + std::bind(&rx_dsp_core_200::issue_stream_command, + _rx_dsps[dsp], + std::placeholders::_1)); + _rx_streamers[dsp] = my_streamer; // store weak pointer } - //sets all tick and samp rates on this streamer + // sets all tick and samp rates on this streamer this->update_rates(); return my_streamer; @@ -167,52 +190,57 @@ rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){ /*********************************************************************** * Transmit streamer **********************************************************************/ -tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ +tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t& args_) +{ stream_args_t args = args_; - //setup defaults for unspecified values - args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; - args.channels = args.channels.empty()? std::vector<size_t>(1, 0) : args.channels; - - //calculate packet size - static const size_t hdr_size = 0 - + vrt::max_if_hdr_words32*sizeof(uint32_t) - + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used - - sizeof(vrt::if_packet_info_t().cid) //no class id ever used - - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used - ; + // setup defaults for unspecified values + args.otw_format = args.otw_format.empty() ? "sc16" : args.otw_format; + args.channels = args.channels.empty() ? std::vector<size_t>(1, 0) : args.channels; + + // calculate packet size + static const size_t hdr_size = + 0 + vrt::max_if_hdr_words32 * sizeof(uint32_t) + + sizeof(vrt::if_packet_info_t().tlr) // forced to have trailer + - sizeof(vrt::if_packet_info_t().sid) // no stream id ever used + - sizeof(vrt::if_packet_info_t().cid) // no class id ever used + - sizeof(vrt::if_packet_info_t().tsi) // no int time ever used + ; static const size_t bpp = _data_transport->get_send_frame_size() - hdr_size; - const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); + const size_t spp = bpp / convert::get_bytes_per_item(args.otw_format); - //make the new streamer given the samples per packet - std::shared_ptr<sph::send_packet_streamer> my_streamer = std::make_shared<sph::send_packet_streamer>(spp); + // make the new streamer given the samples per packet + std::shared_ptr<sph::send_packet_streamer> my_streamer = + std::make_shared<sph::send_packet_streamer>(spp); - //init some streamer stuff + // init some streamer stuff my_streamer->resize(args.channels.size()); my_streamer->set_vrt_packer(&vrt::if_hdr_pack_le); - //set the converter + // set the converter uhd::convert::id_type id; - id.input_format = args.cpu_format; - id.num_inputs = 1; + id.input_format = args.cpu_format; + id.num_inputs = 1; id.output_format = args.otw_format + "_item32_le"; - id.num_outputs = 1; + id.num_outputs = 1; my_streamer->set_converter(id); - //bind callbacks for the handler - for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++){ + // bind callbacks for the handler + for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++) { const size_t dsp = args.channels[chan_i]; - UHD_ASSERT_THROW(dsp == 0); //always 0 + UHD_ASSERT_THROW(dsp == 0); // always 0 _tx_dsp->setup(args); - my_streamer->set_xport_chan_get_buff(chan_i, std::bind( - &zero_copy_if::get_send_buff, _data_transport, std::placeholders::_1 - )); - my_streamer->set_async_receiver(std::bind(&fifo_ctrl_excelsior::pop_async_msg, _fifo_ctrl, std::placeholders::_1, std::placeholders::_2)); - _tx_streamers[dsp] = my_streamer; //store weak pointer + my_streamer->set_xport_chan_get_buff(chan_i, + std::bind( + &zero_copy_if::get_send_buff, _data_transport, std::placeholders::_1)); + my_streamer->set_async_receiver(std::bind(&fifo_ctrl_excelsior::pop_async_msg, + _fifo_ctrl, + std::placeholders::_1, + std::placeholders::_2)); + _tx_streamers[dsp] = my_streamer; // store weak pointer } - //sets all tick and samp rates on this streamer + // sets all tick and samp rates on this streamer this->update_rates(); return my_streamer; diff --git a/host/lib/usrp/b100/mb_eeprom.cpp b/host/lib/usrp/b100/mb_eeprom.cpp index 3e46d7d1f..2be09891f 100644 --- a/host/lib/usrp/b100/mb_eeprom.cpp +++ b/host/lib/usrp/b100/mb_eeprom.cpp @@ -5,21 +5,22 @@ // #include "b100_impl.hpp" -#include <uhdlib/utils/eeprom_utils.hpp> #include <uhd/usrp/mboard_eeprom.hpp> +#include <uhdlib/utils/eeprom_utils.hpp> namespace { - const uint8_t B100_EEPROM_ADDR = 0x50; +const uint8_t B100_EEPROM_ADDR = 0x50; - //use char array so we dont need to attribute packed - struct b100_eeprom_map{ - unsigned char _r[220]; - unsigned char revision[2]; - unsigned char product[2]; - unsigned char name[NAME_MAX_LEN]; - unsigned char serial[SERIAL_LEN]; - }; -} +// use char array so we dont need to attribute packed +struct b100_eeprom_map +{ + unsigned char _r[220]; + unsigned char revision[2]; + unsigned char product[2]; + unsigned char name[NAME_MAX_LEN]; + unsigned char serial[SERIAL_LEN]; +}; +} // namespace using namespace uhd; using uhd::usrp::mboard_eeprom_t; @@ -28,64 +29,50 @@ mboard_eeprom_t b100_impl::get_mb_eeprom(uhd::i2c_iface::sptr iface) { mboard_eeprom_t mb_eeprom; - //extract the revision number + // extract the revision number mb_eeprom["revision"] = uint16_bytes_to_string( - iface->read_eeprom( - B100_EEPROM_ADDR, - offsetof(b100_eeprom_map, revision), - 2 - ) - ); + iface->read_eeprom(B100_EEPROM_ADDR, offsetof(b100_eeprom_map, revision), 2)); - //extract the product code + // extract the product code mb_eeprom["product"] = uint16_bytes_to_string( - iface->read_eeprom( - B100_EEPROM_ADDR, - offsetof(b100_eeprom_map, product), - 2 - ) - ); + iface->read_eeprom(B100_EEPROM_ADDR, offsetof(b100_eeprom_map, product), 2)); - //extract the serial + // extract the serial mb_eeprom["serial"] = bytes_to_string(iface->read_eeprom( - B100_EEPROM_ADDR, offsetof(b100_eeprom_map, serial), SERIAL_LEN - )); + B100_EEPROM_ADDR, offsetof(b100_eeprom_map, serial), SERIAL_LEN)); - //extract the name + // extract the name mb_eeprom["name"] = bytes_to_string(iface->read_eeprom( - B100_EEPROM_ADDR, offsetof(b100_eeprom_map, name), NAME_MAX_LEN - )); + B100_EEPROM_ADDR, offsetof(b100_eeprom_map, name), NAME_MAX_LEN)); return mb_eeprom; } -void b100_impl::set_mb_eeprom( - const uhd::usrp::mboard_eeprom_t &mb_eeprom -) { - auto &iface = _fx2_ctrl; - - //parse the revision number - if (mb_eeprom.has_key("revision")) iface->write_eeprom( - B100_EEPROM_ADDR, offsetof(b100_eeprom_map, revision), - string_to_uint16_bytes(mb_eeprom["revision"]) - ); - - //parse the product code - if (mb_eeprom.has_key("product")) iface->write_eeprom( - B100_EEPROM_ADDR, offsetof(b100_eeprom_map, product), - string_to_uint16_bytes(mb_eeprom["product"]) - ); +void b100_impl::set_mb_eeprom(const uhd::usrp::mboard_eeprom_t& mb_eeprom) +{ + auto& iface = _fx2_ctrl; - //store the serial - if (mb_eeprom.has_key("serial")) iface->write_eeprom( - B100_EEPROM_ADDR, offsetof(b100_eeprom_map, serial), - string_to_bytes(mb_eeprom["serial"], SERIAL_LEN) - ); + // parse the revision number + if (mb_eeprom.has_key("revision")) + iface->write_eeprom(B100_EEPROM_ADDR, + offsetof(b100_eeprom_map, revision), + string_to_uint16_bytes(mb_eeprom["revision"])); - //store the name - if (mb_eeprom.has_key("name")) iface->write_eeprom( - B100_EEPROM_ADDR, offsetof(b100_eeprom_map, name), - string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN) - ); + // parse the product code + if (mb_eeprom.has_key("product")) + iface->write_eeprom(B100_EEPROM_ADDR, + offsetof(b100_eeprom_map, product), + string_to_uint16_bytes(mb_eeprom["product"])); + + // store the serial + if (mb_eeprom.has_key("serial")) + iface->write_eeprom(B100_EEPROM_ADDR, + offsetof(b100_eeprom_map, serial), + string_to_bytes(mb_eeprom["serial"], SERIAL_LEN)); + + // store the name + if (mb_eeprom.has_key("name")) + iface->write_eeprom(B100_EEPROM_ADDR, + offsetof(b100_eeprom_map, name), + string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN)); } - diff --git a/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp b/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp index 8059c2a0d..908841462 100644 --- a/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp +++ b/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp @@ -21,42 +21,52 @@ using namespace uhd; using namespace uhd::transport; -static const boost::posix_time::time_duration AUTOFLUSH_TIMEOUT(boost::posix_time::milliseconds(1)); +static const boost::posix_time::time_duration AUTOFLUSH_TIMEOUT( + boost::posix_time::milliseconds(1)); /*********************************************************************** * USB zero copy wrapper - managed receive buffer **********************************************************************/ -class usb_zero_copy_wrapper_mrb : public managed_recv_buffer{ +class usb_zero_copy_wrapper_mrb : public managed_recv_buffer +{ public: - usb_zero_copy_wrapper_mrb(void){/*NOP*/} + usb_zero_copy_wrapper_mrb(void) + { /*NOP*/ + } - void release(void){ - _mrb.reset(); //decrement ref count, other MRB's may hold a ref + void release(void) + { + _mrb.reset(); // decrement ref count, other MRB's may hold a ref _claimer.release(); } - UHD_INLINE sptr get_new( - managed_recv_buffer::sptr &mrb, size_t &offset_bytes, - const double timeout, size_t &index - ){ - if (not mrb or not _claimer.claim_with_wait(timeout)) return sptr(); + UHD_INLINE sptr get_new(managed_recv_buffer::sptr& mrb, + size_t& offset_bytes, + const double timeout, + size_t& index) + { + if (not mrb or not _claimer.claim_with_wait(timeout)) + return sptr(); - index++; //advances the caller's buffer + index++; // advances the caller's buffer - //hold a copy of the buffer shared pointer + // hold a copy of the buffer shared pointer UHD_ASSERT_THROW(not _mrb); _mrb = mrb; - //extract this packet's memory address and length in bytes - char *mem = mrb->cast<char *>() + offset_bytes; - const uint32_t *mem32 = reinterpret_cast<const uint32_t *>(mem); - const size_t words32 = (uhd::wtohx(mem32[0]) & 0xffff); //length in words32 (from VRT header) - const size_t len = words32*sizeof(uint32_t); //length in bytes + // extract this packet's memory address and length in bytes + char* mem = mrb->cast<char*>() + offset_bytes; + const uint32_t* mem32 = reinterpret_cast<const uint32_t*>(mem); + const size_t words32 = + (uhd::wtohx(mem32[0]) & 0xffff); // length in words32 (from VRT header) + const size_t len = words32 * sizeof(uint32_t); // length in bytes - //check if this receive buffer has been exhausted + // check if this receive buffer has been exhausted offset_bytes += len; - if (offset_bytes >= mrb->size()) mrb.reset(); //drop caller's ref - else if (uhd::wtohx(mem32[words32]) == 0) mrb.reset(); + if (offset_bytes >= mrb->size()) + mrb.reset(); // drop caller's ref + else if (uhd::wtohx(mem32[words32]) == 0) + mrb.reset(); return make(this, mem, len); } @@ -69,10 +79,12 @@ private: /*********************************************************************** * USB zero copy wrapper - managed send buffer **********************************************************************/ -class usb_zero_copy_wrapper_msb : public managed_send_buffer{ +class usb_zero_copy_wrapper_msb : public managed_send_buffer +{ public: - usb_zero_copy_wrapper_msb(const zero_copy_if::sptr internal, const size_t fragmentation_size): - _internal(internal), _fragmentation_size(fragmentation_size) + usb_zero_copy_wrapper_msb( + const zero_copy_if::sptr internal, const size_t fragmentation_size) + : _internal(internal), _fragmentation_size(fragmentation_size) { _ok_to_auto_flush = false; _task = uhd::task::make(std::bind(&usb_zero_copy_wrapper_msb::auto_flush, this)); @@ -80,40 +92,46 @@ public: ~usb_zero_copy_wrapper_msb(void) { - //ensure the task has exited before anything auto deconstructs + // ensure the task has exited before anything auto deconstructs _task.reset(); } - void release(void){ + void release(void) + { boost::mutex::scoped_lock lock(_mutex); _ok_to_auto_flush = true; - //get a reference to the VITA header before incrementing - const uint32_t vita_header = reinterpret_cast<const uint32_t *>(_mem_buffer_tip)[0]; + // get a reference to the VITA header before incrementing + const uint32_t vita_header = + reinterpret_cast<const uint32_t*>(_mem_buffer_tip)[0]; _bytes_in_buffer += size(); _mem_buffer_tip += size(); - //extract VITA end of packet flag, we must force flush under eof conditions - const bool eop = (uhd::wtohx(vita_header) & (0x1 << 24)) != 0; - const bool full = _bytes_in_buffer >= (_last_send_buff->size() - _fragmentation_size); - if (eop or full){ + // extract VITA end of packet flag, we must force flush under eof conditions + const bool eop = (uhd::wtohx(vita_header) & (0x1 << 24)) != 0; + const bool full = _bytes_in_buffer + >= (_last_send_buff->size() - _fragmentation_size); + if (eop or full) { _last_send_buff->commit(_bytes_in_buffer); _last_send_buff.reset(); - //notify the auto-flusher to restart its timed_wait - lock.unlock(); _cond.notify_one(); + // notify the auto-flusher to restart its timed_wait + lock.unlock(); + _cond.notify_one(); } } - UHD_INLINE sptr get_new(const double timeout){ + UHD_INLINE sptr get_new(const double timeout) + { boost::mutex::scoped_lock lock(_mutex); _ok_to_auto_flush = false; - if (not _last_send_buff){ + if (not _last_send_buff) { _last_send_buff = _internal->get_send_buff(timeout); - if (not _last_send_buff) return sptr(); - _mem_buffer_tip = _last_send_buff->cast<char *>(); + if (not _last_send_buff) + return sptr(); + _mem_buffer_tip = _last_send_buff->cast<char*>(); _bytes_in_buffer = 0; } @@ -125,9 +143,9 @@ private: const size_t _fragmentation_size; managed_send_buffer::sptr _last_send_buff; size_t _bytes_in_buffer; - char *_mem_buffer_tip; + char* _mem_buffer_tip; - //private variables for auto flusher + // private variables for auto flusher boost::mutex _mutex; boost::condition_variable _cond; uhd::task::sptr _task; @@ -141,8 +159,7 @@ private: { boost::mutex::scoped_lock lock(_mutex); const bool timeout = not _cond.timed_wait(lock, AUTOFLUSH_TIMEOUT); - if (timeout and _ok_to_auto_flush and _last_send_buff and _bytes_in_buffer != 0) - { + if (timeout and _ok_to_auto_flush and _last_send_buff and _bytes_in_buffer != 0) { _last_send_buff->commit(_bytes_in_buffer); _last_send_buff.reset(); } @@ -152,69 +169,78 @@ private: /*********************************************************************** * USB zero copy wrapper implementation **********************************************************************/ -class usb_zero_copy_wrapper : public usb_zero_copy{ +class usb_zero_copy_wrapper : public usb_zero_copy +{ public: - usb_zero_copy_wrapper(zero_copy_if::sptr usb_zc, const size_t frame_boundary): - _internal_zc(usb_zc), - _frame_boundary(frame_boundary), - _last_recv_offset(0), - _next_recv_buff_index(0) + usb_zero_copy_wrapper(zero_copy_if::sptr usb_zc, const size_t frame_boundary) + : _internal_zc(usb_zc) + , _frame_boundary(frame_boundary) + , _last_recv_offset(0) + , _next_recv_buff_index(0) { - for (size_t i = 0; i < this->get_num_recv_frames(); i++){ + for (size_t i = 0; i < this->get_num_recv_frames(); i++) { _mrb_pool.push_back(std::make_shared<usb_zero_copy_wrapper_mrb>()); } - _the_only_msb = std::make_shared<usb_zero_copy_wrapper_msb>(usb_zc, frame_boundary); + _the_only_msb = + std::make_shared<usb_zero_copy_wrapper_msb>(usb_zc, frame_boundary); } - managed_recv_buffer::sptr get_recv_buff(double timeout){ - //lazy flush mechanism - negative timeout - if (timeout < 0.0) - { + managed_recv_buffer::sptr get_recv_buff(double timeout) + { + // lazy flush mechanism - negative timeout + if (timeout < 0.0) { _last_recv_buff.reset(); - while (_internal_zc->get_recv_buff()){} + while (_internal_zc->get_recv_buff()) { + } return managed_recv_buffer::sptr(); } - //attempt to get a managed recv buffer - if (not _last_recv_buff){ - _last_recv_buff = _internal_zc->get_recv_buff(timeout); - _last_recv_offset = 0; //reset offset into buffer + // attempt to get a managed recv buffer + if (not _last_recv_buff) { + _last_recv_buff = _internal_zc->get_recv_buff(timeout); + _last_recv_offset = 0; // reset offset into buffer } - //get the buffer to be returned to the user - if (_next_recv_buff_index == _mrb_pool.size()) _next_recv_buff_index = 0; + // get the buffer to be returned to the user + if (_next_recv_buff_index == _mrb_pool.size()) + _next_recv_buff_index = 0; return _mrb_pool[_next_recv_buff_index]->get_new( - _last_recv_buff, _last_recv_offset, timeout, _next_recv_buff_index - ); + _last_recv_buff, _last_recv_offset, timeout, _next_recv_buff_index); } - size_t get_num_recv_frames(void) const{ - return (_internal_zc->get_num_recv_frames()*_internal_zc->get_recv_frame_size())/this->get_recv_frame_size(); + size_t get_num_recv_frames(void) const + { + return (_internal_zc->get_num_recv_frames() * _internal_zc->get_recv_frame_size()) + / this->get_recv_frame_size(); } - size_t get_recv_frame_size(void) const{ + size_t get_recv_frame_size(void) const + { return std::min(_frame_boundary, _internal_zc->get_recv_frame_size()); } - managed_send_buffer::sptr get_send_buff(double timeout){ + managed_send_buffer::sptr get_send_buff(double timeout) + { return _the_only_msb->get_new(timeout); } - size_t get_num_send_frames(void) const{ + size_t get_num_send_frames(void) const + { return _internal_zc->get_num_send_frames(); } - size_t get_send_frame_size(void) const{ + size_t get_send_frame_size(void) const + { return std::min(_frame_boundary, _internal_zc->get_send_frame_size()); } private: zero_copy_if::sptr _internal_zc; size_t _frame_boundary; - std::vector<std::shared_ptr<usb_zero_copy_wrapper_mrb> > _mrb_pool; + std::vector<std::shared_ptr<usb_zero_copy_wrapper_mrb>> _mrb_pool; std::shared_ptr<usb_zero_copy_wrapper_msb> _the_only_msb; - //state for last recv buffer to create multiple managed buffers + // state for last recv buffer to create multiple managed buffers managed_recv_buffer::sptr _last_recv_buff; size_t _last_recv_offset; size_t _next_recv_buff_index; @@ -224,7 +250,7 @@ private: * USB zero copy wrapper factory function **********************************************************************/ zero_copy_if::sptr usb_zero_copy_make_wrapper( - zero_copy_if::sptr usb_zc, size_t usb_frame_boundary -){ + zero_copy_if::sptr usb_zc, size_t usb_frame_boundary) +{ return zero_copy_if::sptr(new usb_zero_copy_wrapper(usb_zc, usb_frame_boundary)); } diff --git a/host/lib/usrp/b200/b200_cores.cpp b/host/lib/usrp/b200/b200_cores.cpp index 688af2535..3c55d3995 100644 --- a/host/lib/usrp/b200/b200_cores.cpp +++ b/host/lib/usrp/b200/b200_cores.cpp @@ -6,23 +6,20 @@ // #include "b200_cores.hpp" -#include "b200_regs.hpp" #include "b200_impl.hpp" +#include "b200_regs.hpp" #include <mutex> -b200_local_spi_core::b200_local_spi_core( - uhd::wb_iface::sptr iface, - perif_t default_perif) : - _spi_core(spi_core_3000::make(iface, TOREG(SR_CORE_SPI), RB32_CORE_SPI)), - _current_perif(default_perif), - _last_perif(default_perif) +b200_local_spi_core::b200_local_spi_core(uhd::wb_iface::sptr iface, perif_t default_perif) + : _spi_core(spi_core_3000::make(iface, TOREG(SR_CORE_SPI), RB32_CORE_SPI)) + , _current_perif(default_perif) + , _last_perif(default_perif) { change_perif(default_perif); } -uint32_t b200_local_spi_core::transact_spi( - int which_slave, - const uhd::spi_config_t &config, +uint32_t b200_local_spi_core::transact_spi(int which_slave, + const uhd::spi_config_t& config, uint32_t data, size_t num_bits, bool readback) @@ -34,15 +31,15 @@ uint32_t b200_local_spi_core::transact_spi( void b200_local_spi_core::change_perif(perif_t perif) { std::lock_guard<std::mutex> lock(_mutex); - _last_perif = _current_perif; + _last_perif = _current_perif; _current_perif = perif; switch (_current_perif) { case CODEC: - _spi_core->set_divider(B200_BUS_CLOCK_RATE/AD9361_SPI_RATE); + _spi_core->set_divider(B200_BUS_CLOCK_RATE / AD9361_SPI_RATE); break; case PLL: - _spi_core->set_divider(B200_BUS_CLOCK_RATE/ADF4001_SPI_RATE); + _spi_core->set_divider(B200_BUS_CLOCK_RATE / ADF4001_SPI_RATE); break; } } @@ -52,9 +49,8 @@ void b200_local_spi_core::restore_perif() change_perif(_last_perif); } -b200_ref_pll_ctrl::b200_ref_pll_ctrl(b200_local_spi_core::sptr spi) : - uhd::usrp::adf4001_ctrl(spi, ADF4001_SLAVENO), - _spi(spi) +b200_ref_pll_ctrl::b200_ref_pll_ctrl(b200_local_spi_core::sptr spi) + : uhd::usrp::adf4001_ctrl(spi, ADF4001_SLAVENO), _spi(spi) { } @@ -71,4 +67,3 @@ b200_local_spi_core::sptr b200_local_spi_core::make( { return sptr(new b200_local_spi_core(iface, default_perif)); } - diff --git a/host/lib/usrp/b200/b200_cores.hpp b/host/lib/usrp/b200/b200_cores.hpp index 324938a73..7054fd068 100644 --- a/host/lib/usrp/b200/b200_cores.hpp +++ b/host/lib/usrp/b200/b200_cores.hpp @@ -10,25 +10,22 @@ #define INCLUDED_B200_CORES_HPP #include <uhd/utils/noncopyable.hpp> -#include <uhdlib/usrp/cores/spi_core_3000.hpp> #include <uhdlib/usrp/common/adf4001_ctrl.hpp> +#include <uhdlib/usrp/cores/spi_core_3000.hpp> #include <memory> #include <mutex> -class b200_local_spi_core : uhd::noncopyable, public uhd::spi_iface { - +class b200_local_spi_core : uhd::noncopyable, public uhd::spi_iface +{ public: typedef std::shared_ptr<b200_local_spi_core> sptr; - enum perif_t { - CODEC, PLL - }; + enum perif_t { CODEC, PLL }; b200_local_spi_core(uhd::wb_iface::sptr iface, perif_t default_perif); - virtual uint32_t transact_spi( - int which_slave, - const uhd::spi_config_t &config, + virtual uint32_t transact_spi(int which_slave, + const uhd::spi_config_t& config, uint32_t data, size_t num_bits, bool readback); @@ -39,13 +36,14 @@ public: static sptr make(uhd::wb_iface::sptr iface, perif_t default_perif = CODEC); private: - spi_core_3000::sptr _spi_core; - perif_t _current_perif; - perif_t _last_perif; - std::mutex _mutex; + spi_core_3000::sptr _spi_core; + perif_t _current_perif; + perif_t _last_perif; + std::mutex _mutex; }; -class b200_ref_pll_ctrl : public uhd::usrp::adf4001_ctrl { +class b200_ref_pll_ctrl : public uhd::usrp::adf4001_ctrl +{ public: typedef std::shared_ptr<b200_ref_pll_ctrl> sptr; diff --git a/host/lib/usrp/b200/b200_iface.cpp b/host/lib/usrp/b200/b200_iface.cpp index c2bd9bace..2efc9efb5 100644 --- a/host/lib/usrp/b200/b200_iface.cpp +++ b/host/lib/usrp/b200/b200_iface.cpp @@ -27,8 +27,7 @@ //! libusb_error_name is only in newer API #ifndef HAVE_LIBUSB_ERROR_NAME - #define libusb_error_name(code) \ - str(boost::format("LIBUSB_ERROR_CODE %d") % code) +# define libusb_error_name(code) str(boost::format("LIBUSB_ERROR_CODE %d") % code) #endif using namespace uhd; @@ -41,34 +40,32 @@ const static uint8_t FX3_FIRMWARE_LOAD = 0xA0; // 32 KB - 256 bytes for EEPROM storage constexpr size_t BOOTLOADER_MAX_SIZE = 32512; -const static uint8_t VRT_VENDOR_OUT = (LIBUSB_REQUEST_TYPE_VENDOR - | LIBUSB_ENDPOINT_OUT); -const static uint8_t VRT_VENDOR_IN = (LIBUSB_REQUEST_TYPE_VENDOR - | LIBUSB_ENDPOINT_IN); -const static uint8_t B200_VREQ_FPGA_START = 0x02; -const static uint8_t B200_VREQ_FPGA_DATA = 0x12; -const static uint8_t B200_VREQ_GET_COMPAT = 0x15; +const static uint8_t VRT_VENDOR_OUT = (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT); +const static uint8_t VRT_VENDOR_IN = (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN); +const static uint8_t B200_VREQ_FPGA_START = 0x02; +const static uint8_t B200_VREQ_FPGA_DATA = 0x12; +const static uint8_t B200_VREQ_GET_COMPAT = 0x15; const static uint8_t B200_VREQ_SET_FPGA_HASH = 0x1C; const static uint8_t B200_VREQ_GET_FPGA_HASH = 0x1D; -const static uint8_t B200_VREQ_SET_FW_HASH = 0x1E; -const static uint8_t B200_VREQ_GET_FW_HASH = 0x1F; -const static uint8_t B200_VREQ_LOOP = 0x22; -const static uint8_t B200_VREQ_FPGA_CONFIG = 0x55; -//const static uint8_t B200_VREQ_FPGA_RESET = 0x62; -const static uint8_t B200_VREQ_GPIF_RESET = 0x72; -const static uint8_t B200_VREQ_GET_USB = 0x80; -const static uint8_t B200_VREQ_GET_STATUS = 0x83; -const static uint8_t B200_VREQ_FX3_RESET = 0x99; +const static uint8_t B200_VREQ_SET_FW_HASH = 0x1E; +const static uint8_t B200_VREQ_GET_FW_HASH = 0x1F; +const static uint8_t B200_VREQ_LOOP = 0x22; +const static uint8_t B200_VREQ_FPGA_CONFIG = 0x55; +// const static uint8_t B200_VREQ_FPGA_RESET = 0x62; +const static uint8_t B200_VREQ_GPIF_RESET = 0x72; +const static uint8_t B200_VREQ_GET_USB = 0x80; +const static uint8_t B200_VREQ_GET_STATUS = 0x83; +const static uint8_t B200_VREQ_FX3_RESET = 0x99; const static uint8_t B200_VREQ_EEPROM_WRITE = 0xBA; -const static uint8_t B200_VREQ_EEPROM_READ = 0xBB; +const static uint8_t B200_VREQ_EEPROM_READ = 0xBB; -const static uint8_t FX3_STATE_UNDEFINED = 0x00; -const static uint8_t FX3_STATE_FPGA_READY = 0x01; +const static uint8_t FX3_STATE_UNDEFINED = 0x00; +const static uint8_t FX3_STATE_FPGA_READY = 0x01; const static uint8_t FX3_STATE_CONFIGURING_FPGA = 0x02; -const static uint8_t FX3_STATE_BUSY = 0x03; -const static uint8_t FX3_STATE_RUNNING = 0x04; -const static uint8_t FX3_STATE_UNCONFIGURED = 0x05; -const static uint8_t FX3_STATE_ERROR = 0x06; +const static uint8_t FX3_STATE_BUSY = 0x03; +const static uint8_t FX3_STATE_RUNNING = 0x04; +const static uint8_t FX3_STATE_UNCONFIGURED = 0x05; +const static uint8_t FX3_STATE_ERROR = 0x06; const static int VREQ_MAX_SIZE_USB2 = 64; const static int VREQ_MAX_SIZE_USB3 = 512; @@ -87,13 +84,13 @@ typedef uint32_t hash_type; * \param filename file used to generate hash value * \return hash value in a uint32_t type */ -static hash_type generate_hash(const char *filename) +static hash_type generate_hash(const char* filename) { if (filename == NULL) return hash_type(0); std::ifstream file(filename); - if (not file){ + if (not file) { throw uhd::io_error(std::string("cannot open input file ") + filename); } @@ -103,16 +100,16 @@ static hash_type generate_hash(const char *filename) long long count = 0; while (file.get(ch)) { count++; - //hash algorithm derived from boost hash_combine - //http://www.boost.org/doc/libs/1_35_0/doc/html/boost/hash_combine_id241013.html - hash ^= ch + 0x9e3779b9 + (hash<<6) + (hash>>2); + // hash algorithm derived from boost hash_combine + // http://www.boost.org/doc/libs/1_35_0/doc/html/boost/hash_combine_id241013.html + hash ^= ch + 0x9e3779b9 + (hash << 6) + (hash >> 2); } - if (count == 0){ + if (count == 0) { throw uhd::io_error(std::string("empty input file ") + filename); } - if (not file.eof()){ + if (not file.eof()) { throw uhd::io_error(std::string("file error ") + filename); } @@ -124,45 +121,47 @@ static hash_type generate_hash(const char *filename) /*********************************************************************** * The implementation class **********************************************************************/ -class b200_iface_impl : public b200_iface{ +class b200_iface_impl : public b200_iface +{ public: - - b200_iface_impl(usb_control::sptr usb_ctrl): - _usb_ctrl(usb_ctrl) { - //NOP + b200_iface_impl(usb_control::sptr usb_ctrl) : _usb_ctrl(usb_ctrl) + { + // NOP } int fx3_control_write(uint8_t request, - uint16_t value, - uint16_t index, - unsigned char *buff, - uint16_t length, - uint32_t timeout = 0) { - return _usb_ctrl->submit(VRT_VENDOR_OUT, // bmReqeustType - request, // bRequest - value, // wValue - index, // wIndex - buff, // data - length, // wLength - timeout); // timeout + uint16_t value, + uint16_t index, + unsigned char* buff, + uint16_t length, + uint32_t timeout = 0) + { + return _usb_ctrl->submit(VRT_VENDOR_OUT, // bmReqeustType + request, // bRequest + value, // wValue + index, // wIndex + buff, // data + length, // wLength + timeout); // timeout } int fx3_control_read(uint8_t request, - uint16_t value, - uint16_t index, - unsigned char *buff, - uint16_t length, - uint32_t timeout = 0) { - return _usb_ctrl->submit(VRT_VENDOR_IN, // bmReqeustType - request, // bRequest - value, // wValue - index, // wIndex - buff, // data - length, // wLength - timeout); // timeout + uint16_t value, + uint16_t index, + unsigned char* buff, + uint16_t length, + uint32_t timeout = 0) + { + return _usb_ctrl->submit(VRT_VENDOR_IN, // bmReqeustType + request, // bRequest + value, // wValue + index, // wIndex + buff, // data + length, // wLength + timeout); // timeout } - void write_i2c(UHD_UNUSED(uint16_t addr), UHD_UNUSED(const byte_vector_t &bytes)) + void write_i2c(UHD_UNUSED(uint16_t addr), UHD_UNUSED(const byte_vector_t& bytes)) { throw uhd::not_implemented_error("b200 write i2c"); } @@ -173,33 +172,43 @@ public: throw uhd::not_implemented_error("b200 read i2c"); } - void write_eeprom(uint16_t addr, uint16_t offset, - const byte_vector_t &bytes) { + void write_eeprom(uint16_t addr, uint16_t offset, const byte_vector_t& bytes) + { int ret = fx3_control_write(B200_VREQ_EEPROM_WRITE, - 0, offset | (uint16_t(addr) << 8), - (unsigned char *) &bytes[0], - bytes.size()); + 0, + offset | (uint16_t(addr) << 8), + (unsigned char*)&bytes[0], + bytes.size()); if (ret < 0) - throw uhd::io_error((boost::format("Failed to write EEPROM (%d: %s)") % ret % libusb_error_name(ret)).str()); + throw uhd::io_error((boost::format("Failed to write EEPROM (%d: %s)") % ret + % libusb_error_name(ret)) + .str()); else if ((size_t)ret != bytes.size()) - throw uhd::io_error((boost::format("Short write on write EEPROM (expecting: %d, returned: %d)") % bytes.size() % ret).str()); + throw uhd::io_error(( + boost::format("Short write on write EEPROM (expecting: %d, returned: %d)") + % bytes.size() % ret) + .str()); } - byte_vector_t read_eeprom( - uint16_t addr, - uint16_t offset, - size_t num_bytes) { + byte_vector_t read_eeprom(uint16_t addr, uint16_t offset, size_t num_bytes) + { byte_vector_t recv_bytes(num_bytes); int bytes_read = fx3_control_read(B200_VREQ_EEPROM_READ, - 0, offset | (uint16_t(addr) << 8), - (unsigned char*) &recv_bytes[0], - num_bytes); + 0, + offset | (uint16_t(addr) << 8), + (unsigned char*)&recv_bytes[0], + num_bytes); if (bytes_read < 0) - throw uhd::io_error((boost::format("Failed to read EEPROM (%d: %s)") % bytes_read % libusb_error_name(bytes_read)).str()); + throw uhd::io_error((boost::format("Failed to read EEPROM (%d: %s)") + % bytes_read % libusb_error_name(bytes_read)) + .str()); else if ((size_t)bytes_read != num_bytes) - throw uhd::io_error((boost::format("Short read on read EEPROM (expecting: %d, returned: %d)") % num_bytes % bytes_read).str()); + throw uhd::io_error( + (boost::format("Short read on read EEPROM (expecting: %d, returned: %d)") + % num_bytes % bytes_read) + .str()); return recv_bytes; } @@ -207,25 +216,27 @@ public: void load_firmware(const std::string filestring, UHD_UNUSED(bool force) = false) { if (load_img_msg) { - UHD_LOGGER_INFO("B200") << "Loading firmware image: " - << filestring << "..."; + UHD_LOGGER_INFO("B200") << "Loading firmware image: " << filestring << "..."; } ihex_reader file_reader(filestring); try { - file_reader.read( - std::bind( - &b200_iface_impl::fx3_control_write, this, - FX3_FIRMWARE_LOAD, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, 0 - ) - ); - } catch (const uhd::io_error &e) { - throw uhd::io_error(str(boost::format("Could not load firmware: \n%s") % e.what())); + file_reader.read(std::bind(&b200_iface_impl::fx3_control_write, + this, + FX3_FIRMWARE_LOAD, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + std::placeholders::_4, + 0)); + } catch (const uhd::io_error& e) { + throw uhd::io_error( + str(boost::format("Could not load firmware: \n%s") % e.what())); } - //TODO - //usrp_set_firmware_hash(hash); //set hash before reset + // TODO + // usrp_set_firmware_hash(hash); //set hash before reset /* Success! Let the system settle. */ // TODO: Replace this with a polling loop in the FX3, or find out @@ -233,33 +244,47 @@ public: std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } - void reset_fx3(void) { + void reset_fx3(void) + { unsigned char data[4]; memset(data, 0x00, sizeof(data)); const int bytes_to_send = sizeof(data); int ret = fx3_control_write(B200_VREQ_FX3_RESET, 0x00, 0x00, data, bytes_to_send); if (ret < 0) - throw uhd::io_error((boost::format("Failed to reset FX3 (%d: %s)") % ret % libusb_error_name(ret)).str()); + throw uhd::io_error((boost::format("Failed to reset FX3 (%d: %s)") % ret + % libusb_error_name(ret)) + .str()); else if (ret != bytes_to_send) - throw uhd::io_error((boost::format("Short write on reset FX3 (expecting: %d, returned: %d)") % bytes_to_send % ret).str()); + throw uhd::io_error( + (boost::format("Short write on reset FX3 (expecting: %d, returned: %d)") + % bytes_to_send % ret) + .str()); } - void reset_gpif(void) { + void reset_gpif(void) + { unsigned char data[4]; memset(data, 0x00, sizeof(data)); const int bytes_to_send = sizeof(data); - int ret = fx3_control_write(B200_VREQ_GPIF_RESET, 0x00, 0x00, data, bytes_to_send); + int ret = + fx3_control_write(B200_VREQ_GPIF_RESET, 0x00, 0x00, data, bytes_to_send); if (ret < 0) - throw uhd::io_error((boost::format("Failed to reset GPIF (%d: %s)") % ret % libusb_error_name(ret)).str()); + throw uhd::io_error((boost::format("Failed to reset GPIF (%d: %s)") % ret + % libusb_error_name(ret)) + .str()); else if (ret != bytes_to_send) - throw uhd::io_error((boost::format("Short write on reset GPIF (expecting: %d, returned: %d)") % bytes_to_send % ret).str()); + throw uhd::io_error( + (boost::format("Short write on reset GPIF (expecting: %d, returned: %d)") + % bytes_to_send % ret) + .str()); } - void set_fpga_reset_pin(const bool reset) { + void set_fpga_reset_pin(const bool reset) + { unsigned char data[4]; - memset(data, (reset)? 0xFF : 0x00, sizeof(data)); + memset(data, (reset) ? 0xFF : 0x00, sizeof(data)); UHD_THROW_INVALID_CODE_PATH(); @@ -268,113 +293,178 @@ public: /* const int bytes_to_send = sizeof(data); - int ret = fx3_control_write(B200_VREQ_FPGA_RESET, 0x00, 0x00, data, bytes_to_send); - if (ret < 0) - throw uhd::io_error((boost::format("Failed to reset FPGA (%d: %s)") % ret % libusb_error_name(ret)).str()); - else if (ret != bytes_to_send) - throw uhd::io_error((boost::format("Short write on reset FPGA (expecting: %d, returned: %d)") % bytes_to_send % ret).str()); + int ret = fx3_control_write(B200_VREQ_FPGA_RESET, 0x00, 0x00, data, + bytes_to_send); if (ret < 0) throw uhd::io_error((boost::format("Failed to reset + FPGA (%d: %s)") % ret % libusb_error_name(ret)).str()); else if (ret != + bytes_to_send) throw uhd::io_error((boost::format("Short write on reset FPGA + (expecting: %d, returned: %d)") % bytes_to_send % ret).str()); */ } - uint8_t get_usb_speed(void) { - + uint8_t get_usb_speed(void) + { unsigned char rx_data[1]; memset(rx_data, 0x00, sizeof(rx_data)); const int bytes_to_recv = sizeof(rx_data); int ret = fx3_control_read(B200_VREQ_GET_USB, 0x00, 0x00, rx_data, bytes_to_recv); if (ret < 0) - throw uhd::io_error((boost::format("Failed to get USB speed (%d: %s)") % ret % libusb_error_name(ret)).str()); + throw uhd::io_error((boost::format("Failed to get USB speed (%d: %s)") % ret + % libusb_error_name(ret)) + .str()); else if (ret != bytes_to_recv) - throw uhd::io_error((boost::format("Short read on get USB speed (expecting: %d, returned: %d)") % bytes_to_recv % ret).str()); + throw uhd::io_error(( + boost::format("Short read on get USB speed (expecting: %d, returned: %d)") + % bytes_to_recv % ret) + .str()); return boost::lexical_cast<uint8_t>(rx_data[0]); } - uint8_t get_fx3_status(void) { - + uint8_t get_fx3_status(void) + { unsigned char rx_data[1]; memset(rx_data, 0x00, sizeof(rx_data)); const int bytes_to_recv = sizeof(rx_data); - int ret = fx3_control_read(B200_VREQ_GET_STATUS, 0x00, 0x00, rx_data, bytes_to_recv); + int ret = + fx3_control_read(B200_VREQ_GET_STATUS, 0x00, 0x00, rx_data, bytes_to_recv); if (ret < 0) - throw uhd::io_error((boost::format("Failed to get FX3 status (%d: %s)") % ret % libusb_error_name(ret)).str()); + throw uhd::io_error((boost::format("Failed to get FX3 status (%d: %s)") % ret + % libusb_error_name(ret)) + .str()); else if (ret != bytes_to_recv) - throw uhd::io_error((boost::format("Short read on get FX3 status (expecting: %d, returned: %d)") % bytes_to_recv % ret).str()); + throw uhd::io_error( + (boost::format( + "Short read on get FX3 status (expecting: %d, returned: %d)") + % bytes_to_recv % ret) + .str()); return boost::lexical_cast<uint8_t>(rx_data[0]); } - uint16_t get_compat_num(void) { - + uint16_t get_compat_num(void) + { unsigned char rx_data[2]; memset(rx_data, 0x00, sizeof(rx_data)); const int bytes_to_recv = sizeof(rx_data); - int ret = fx3_control_read(B200_VREQ_GET_COMPAT , 0x00, 0x00, rx_data, bytes_to_recv); + int ret = + fx3_control_read(B200_VREQ_GET_COMPAT, 0x00, 0x00, rx_data, bytes_to_recv); if (ret < 0) - throw uhd::io_error((boost::format("Failed to get compat num (%d: %s)") % ret % libusb_error_name(ret)).str()); + throw uhd::io_error((boost::format("Failed to get compat num (%d: %s)") % ret + % libusb_error_name(ret)) + .str()); else if (ret != bytes_to_recv) - throw uhd::io_error((boost::format("Short read on get compat num (expecting: %d, returned: %d)") % bytes_to_recv % ret).str()); + throw uhd::io_error( + (boost::format( + "Short read on get compat num (expecting: %d, returned: %d)") + % bytes_to_recv % ret) + .str()); return (((uint16_t)rx_data[0]) << 8) | rx_data[1]; } - void usrp_get_firmware_hash(hash_type &hash) { + void usrp_get_firmware_hash(hash_type& hash) + { const int bytes_to_recv = 4; if (sizeof(hash_type) != bytes_to_recv) - throw uhd::type_error((boost::format("hash_type is %d bytes but transfer length is %d bytes") % sizeof(hash_type) % bytes_to_recv).str()); + throw uhd::type_error( + (boost::format("hash_type is %d bytes but transfer length is %d bytes") + % sizeof(hash_type) % bytes_to_recv) + .str()); - int ret = fx3_control_read(B200_VREQ_GET_FW_HASH, 0x00, 0x00, (unsigned char*) &hash, bytes_to_recv, 500); + int ret = fx3_control_read( + B200_VREQ_GET_FW_HASH, 0x00, 0x00, (unsigned char*)&hash, bytes_to_recv, 500); if (ret < 0) - throw uhd::io_error((boost::format("Failed to get firmware hash (%d: %s)") % ret % libusb_error_name(ret)).str()); + throw uhd::io_error((boost::format("Failed to get firmware hash (%d: %s)") + % ret % libusb_error_name(ret)) + .str()); else if (ret != bytes_to_recv) - throw uhd::io_error((boost::format("Short read on get firmware hash (expecting: %d, returned: %d)") % bytes_to_recv % ret).str()); + throw uhd::io_error( + (boost::format( + "Short read on get firmware hash (expecting: %d, returned: %d)") + % bytes_to_recv % ret) + .str()); } - void usrp_set_firmware_hash(hash_type hash) { + void usrp_set_firmware_hash(hash_type hash) + { const int bytes_to_send = 4; if (sizeof(hash_type) != bytes_to_send) - throw uhd::type_error((boost::format("hash_type is %d bytes but transfer length is %d bytes") % sizeof(hash_type) % bytes_to_send).str()); + throw uhd::type_error( + (boost::format("hash_type is %d bytes but transfer length is %d bytes") + % sizeof(hash_type) % bytes_to_send) + .str()); - int ret = fx3_control_write(B200_VREQ_SET_FW_HASH, 0x00, 0x00, (unsigned char*) &hash, bytes_to_send); + int ret = fx3_control_write( + B200_VREQ_SET_FW_HASH, 0x00, 0x00, (unsigned char*)&hash, bytes_to_send); if (ret < 0) - throw uhd::io_error((boost::format("Failed to set firmware hash (%d: %s)") % ret % libusb_error_name(ret)).str()); + throw uhd::io_error((boost::format("Failed to set firmware hash (%d: %s)") + % ret % libusb_error_name(ret)) + .str()); else if (ret != bytes_to_send) - throw uhd::io_error((boost::format("Short write on set firmware hash (expecting: %d, returned: %d)") % bytes_to_send % ret).str()); + throw uhd::io_error( + (boost::format( + "Short write on set firmware hash (expecting: %d, returned: %d)") + % bytes_to_send % ret) + .str()); } - void usrp_get_fpga_hash(hash_type &hash) { + void usrp_get_fpga_hash(hash_type& hash) + { const int bytes_to_recv = 4; if (sizeof(hash_type) != bytes_to_recv) - throw uhd::type_error((boost::format("hash_type is %d bytes but transfer length is %d bytes") % sizeof(hash_type) % bytes_to_recv).str()); + throw uhd::type_error( + (boost::format("hash_type is %d bytes but transfer length is %d bytes") + % sizeof(hash_type) % bytes_to_recv) + .str()); - int ret = fx3_control_read(B200_VREQ_GET_FPGA_HASH, 0x00, 0x00, (unsigned char*) &hash, bytes_to_recv, 500); + int ret = fx3_control_read(B200_VREQ_GET_FPGA_HASH, + 0x00, + 0x00, + (unsigned char*)&hash, + bytes_to_recv, + 500); if (ret < 0) - throw uhd::io_error((boost::format("Failed to get FPGA hash (%d: %s)") % ret % libusb_error_name(ret)).str()); + throw uhd::io_error((boost::format("Failed to get FPGA hash (%d: %s)") % ret + % libusb_error_name(ret)) + .str()); else if (ret != bytes_to_recv) - throw uhd::io_error((boost::format("Short read on get FPGA hash (expecting: %d, returned: %d)") % bytes_to_recv % ret).str()); + throw uhd::io_error(( + boost::format("Short read on get FPGA hash (expecting: %d, returned: %d)") + % bytes_to_recv % ret) + .str()); } - void usrp_set_fpga_hash(hash_type hash) { + void usrp_set_fpga_hash(hash_type hash) + { const int bytes_to_send = 4; if (sizeof(hash_type) != bytes_to_send) - throw uhd::type_error((boost::format("hash_type is %d bytes but transfer length is %d bytes") % sizeof(hash_type) % bytes_to_send).str()); + throw uhd::type_error( + (boost::format("hash_type is %d bytes but transfer length is %d bytes") + % sizeof(hash_type) % bytes_to_send) + .str()); - int ret = fx3_control_write(B200_VREQ_SET_FPGA_HASH, 0x00, 0x00, (unsigned char*) &hash, bytes_to_send); + int ret = fx3_control_write( + B200_VREQ_SET_FPGA_HASH, 0x00, 0x00, (unsigned char*)&hash, bytes_to_send); if (ret < 0) - throw uhd::io_error((boost::format("Failed to set FPGA hash (%d: %s)") % ret % libusb_error_name(ret)).str()); + throw uhd::io_error((boost::format("Failed to set FPGA hash (%d: %s)") % ret + % libusb_error_name(ret)) + .str()); else if (ret != bytes_to_send) - throw uhd::io_error((boost::format("Short write on set FPGA hash (expecting: %d, returned: %d)") % bytes_to_send % ret).str()); + throw uhd::io_error( + (boost::format( + "Short write on set FPGA hash (expecting: %d, returned: %d)") + % bytes_to_send % ret) + .str()); } - // Establish default largest possible control request transfer size based on operating + // Establish default largest possible control request transfer size based on operating // USB speed int _get_transfer_size() { - switch (get_usb_speed()) - { + switch (get_usb_speed()) { case 2: return VREQ_DEFAULT_SIZE; case 3: @@ -385,25 +475,27 @@ public: } } - size_t _get_file_size(const char * filename) + size_t _get_file_size(const char* filename) { boost::filesystem::path path(filename); auto filesize = boost::filesystem::file_size(path); return static_cast<size_t>(filesize); } - uint32_t load_fpga(const std::string filestring, bool force) { - + uint32_t load_fpga(const std::string filestring, bool force) + { uint8_t fx3_state = 0; uint32_t wait_count; - int ret = 0; + int ret = 0; int bytes_to_xfer = 0; - const char *filename = filestring.c_str(); + const char* filename = filestring.c_str(); hash_type hash = generate_hash(filename); - hash_type loaded_hash; usrp_get_fpga_hash(loaded_hash); - if (hash == loaded_hash and !force) return 0; + hash_type loaded_hash; + usrp_get_fpga_hash(loaded_hash); + if (hash == loaded_hash and !force) + return 0; const int transfer_size = _get_transfer_size(); @@ -411,12 +503,21 @@ public: unsigned char out_buff[VREQ_MAX_SIZE]; - // Request loopback read, which will indicate the firmware's current control request buffer size + // Request loopback read, which will indicate the firmware's current control + // request buffer size int nread = fx3_control_read(B200_VREQ_LOOP, 0, 0, out_buff, transfer_size, 1000); if (nread < 0) - throw uhd::io_error((boost::format("load_fpga: unable to complete firmware loopback request (%d: %s)") % nread % libusb_error_name(nread)).str()); + throw uhd::io_error( + (boost::format( + "load_fpga: unable to complete firmware loopback request (%d: %s)") + % nread % libusb_error_name(nread)) + .str()); else if (nread != transfer_size) - throw uhd::io_error((boost::format("load_fpga: short read on firmware loopback request (expecting: %d, returned: %d)") % transfer_size % nread).str()); + throw uhd::io_error( + (boost::format("load_fpga: short read on firmware loopback request " + "(expecting: %d, returned: %d)") + % transfer_size % nread) + .str()); const size_t file_size = _get_file_size(filename); @@ -427,84 +528,107 @@ public: throw uhd::io_error("load_fpga: cannot open FPGA input file."); } - // Zero the hash, in case we abort programming another image and revert to the previously programmed image + // Zero the hash, in case we abort programming another image and revert to the + // previously programmed image usrp_set_fpga_hash(0); memset(out_buff, 0x00, sizeof(out_buff)); bytes_to_xfer = 1; - ret = fx3_control_write(B200_VREQ_FPGA_CONFIG, 0, 0, out_buff, bytes_to_xfer, 1000); + ret = + fx3_control_write(B200_VREQ_FPGA_CONFIG, 0, 0, out_buff, bytes_to_xfer, 1000); if (ret < 0) - throw uhd::io_error((boost::format("Failed to start FPGA config (%d: %s)") % ret % libusb_error_name(ret)).str()); + throw uhd::io_error((boost::format("Failed to start FPGA config (%d: %s)") + % ret % libusb_error_name(ret)) + .str()); else if (ret != bytes_to_xfer) - throw uhd::io_error((boost::format("Short write on start FPGA config (expecting: %d, returned: %d)") % bytes_to_xfer % ret).str()); + throw uhd::io_error( + (boost::format( + "Short write on start FPGA config (expecting: %d, returned: %d)") + % bytes_to_xfer % ret) + .str()); wait_count = 0; do { fx3_state = get_fx3_status(); - if((wait_count >= 500) || (fx3_state == FX3_STATE_ERROR) || (fx3_state == FX3_STATE_UNDEFINED)) { + if ((wait_count >= 500) || (fx3_state == FX3_STATE_ERROR) + || (fx3_state == FX3_STATE_UNDEFINED)) { return fx3_state; } std::this_thread::sleep_for(std::chrono::milliseconds(10)); wait_count++; - } while(fx3_state != FX3_STATE_FPGA_READY); + } while (fx3_state != FX3_STATE_FPGA_READY); if (load_img_msg) { - UHD_LOGGER_INFO("B200") << "Loading FPGA image: " - << filestring << "..."; + UHD_LOGGER_INFO("B200") << "Loading FPGA image: " << filestring << "..."; } bytes_to_xfer = 1; - ret = fx3_control_write(B200_VREQ_FPGA_START, 0, 0, out_buff, bytes_to_xfer, 1000); + ret = + fx3_control_write(B200_VREQ_FPGA_START, 0, 0, out_buff, bytes_to_xfer, 1000); if (ret < 0) - throw uhd::io_error((boost::format("Failed to start FPGA bitstream (%d: %s)") % ret % libusb_error_name(ret)).str()); + throw uhd::io_error((boost::format("Failed to start FPGA bitstream (%d: %s)") + % ret % libusb_error_name(ret)) + .str()); else if (ret != bytes_to_xfer) - throw uhd::io_error((boost::format("Short write on start FPGA bitstream (expecting: %d, returned: %d)") % bytes_to_xfer % ret).str()); + throw uhd::io_error( + (boost::format( + "Short write on start FPGA bitstream (expecting: %d, returned: %d)") + % bytes_to_xfer % ret) + .str()); wait_count = 0; do { fx3_state = get_fx3_status(); - if((wait_count >= 1000) || (fx3_state == FX3_STATE_ERROR) || (fx3_state == FX3_STATE_UNDEFINED)) { + if ((wait_count >= 1000) || (fx3_state == FX3_STATE_ERROR) + || (fx3_state == FX3_STATE_UNDEFINED)) { return fx3_state; } std::this_thread::sleep_for(std::chrono::milliseconds(10)); wait_count++; - } while(fx3_state != FX3_STATE_CONFIGURING_FPGA); + } while (fx3_state != FX3_STATE_CONFIGURING_FPGA); size_t bytes_sent = 0; while (!file.eof()) { - file.read((char *) out_buff, transfer_size); + file.read((char*)out_buff, transfer_size); const std::streamsize n = file.gcount(); - if(n == 0) + if (n == 0) continue; uint16_t transfer_count = uint16_t(n); /* Send the data to the device. */ - int nwritten = fx3_control_write(B200_VREQ_FPGA_DATA, 0, 0, out_buff, transfer_count, 5000); + int nwritten = fx3_control_write( + B200_VREQ_FPGA_DATA, 0, 0, out_buff, transfer_count, 5000); if (nwritten < 0) - throw uhd::io_error((boost::format("load_fpga: cannot write bitstream to FX3 (%d: %s)") % nwritten % libusb_error_name(nwritten)).str()); + throw uhd::io_error( + (boost::format("load_fpga: cannot write bitstream to FX3 (%d: %s)") + % nwritten % libusb_error_name(nwritten)) + .str()); else if (nwritten != transfer_count) - throw uhd::io_error((boost::format("load_fpga: short write while transferring bitstream to FX3 (expecting: %d, returned: %d)") % transfer_count % nwritten).str()); + throw uhd::io_error( + (boost::format("load_fpga: short write while transferring bitstream " + "to FX3 (expecting: %d, returned: %d)") + % transfer_count % nwritten) + .str()); const size_t LOG_GRANULARITY = 10; // %. Keep this an integer divisor of 100. - if (load_img_msg) - { - if (bytes_sent == 0) UHD_LOGGER_DEBUG("B200") << "FPGA load: 0%" << std::flush; + if (load_img_msg) { + if (bytes_sent == 0) + UHD_LOGGER_DEBUG("B200") << "FPGA load: 0%" << std::flush; const size_t percent_before = - size_t((bytes_sent*100)/file_size) - - (size_t((bytes_sent*100)/file_size) % LOG_GRANULARITY); + size_t((bytes_sent * 100) / file_size) + - (size_t((bytes_sent * 100) / file_size) % LOG_GRANULARITY); bytes_sent += transfer_count; const size_t percent_after = - size_t((bytes_sent*100)/file_size) - - (size_t((bytes_sent*100)/file_size) % LOG_GRANULARITY); - if (percent_before != percent_after) - { + size_t((bytes_sent * 100) / file_size) + - (size_t((bytes_sent * 100) / file_size) % LOG_GRANULARITY); + if (percent_before != percent_after) { UHD_LOGGER_DEBUG("B200") << "FPGA load: " << std::setw(3) << percent_after << "%"; } @@ -517,14 +641,15 @@ public: do { fx3_state = get_fx3_status(); - if((wait_count >= 500) || (fx3_state == FX3_STATE_ERROR) || (fx3_state == FX3_STATE_UNDEFINED)) { + if ((wait_count >= 500) || (fx3_state == FX3_STATE_ERROR) + || (fx3_state == FX3_STATE_UNDEFINED)) { return fx3_state; } std::this_thread::sleep_for(std::chrono::milliseconds(10)); wait_count++; - } while(fx3_state != FX3_STATE_RUNNING); + } while (fx3_state != FX3_STATE_RUNNING); usrp_set_fpga_hash(hash); @@ -598,8 +723,12 @@ public: uint16_t transfer_count = uint16_t(n); // Send the data to the device - int nwritten = fx3_control_write( - B200_VREQ_EEPROM_WRITE, 0, bytes_sent, out_buff.data(), transfer_count, 5000); + int nwritten = fx3_control_write(B200_VREQ_EEPROM_WRITE, + 0, + bytes_sent, + out_buff.data(), + transfer_count, + 5000); if (nwritten < 0) { throw uhd::io_error( (boost::format( @@ -627,7 +756,8 @@ public: size_t((bytes_sent * 100) / file_size) - (size_t((bytes_sent * 100) / file_size) % LOG_GRANULARITY); if (percent_before != percent_after) { - UHD_LOGGER_DEBUG("B200") << "Bootloader load: " << std::setw(3) << percent_after << "%"; + UHD_LOGGER_DEBUG("B200") + << "Bootloader load: " << std::setw(3) << percent_after << "%"; } } @@ -654,22 +784,21 @@ private: std::string b200_iface::fx3_state_string(uint8_t state) { - switch (state) - { - case FX3_STATE_FPGA_READY: - return std::string("Ready"); - case FX3_STATE_CONFIGURING_FPGA: - return std::string("Configuring FPGA"); - case FX3_STATE_BUSY: - return std::string("Busy"); - case FX3_STATE_RUNNING: - return std::string("Running"); - case FX3_STATE_UNCONFIGURED: - return std::string("Unconfigured"); - case FX3_STATE_ERROR: - return std::string("Error"); - default: - break; + switch (state) { + case FX3_STATE_FPGA_READY: + return std::string("Ready"); + case FX3_STATE_CONFIGURING_FPGA: + return std::string("Configuring FPGA"); + case FX3_STATE_BUSY: + return std::string("Busy"); + case FX3_STATE_RUNNING: + return std::string("Running"); + case FX3_STATE_UNCONFIGURED: + return std::string("Unconfigured"); + case FX3_STATE_ERROR: + return std::string("Error"); + default: + break; } return std::string("Unknown"); } diff --git a/host/lib/usrp/b200/b200_iface.hpp b/host/lib/usrp/b200/b200_iface.hpp index a3059bacf..7d7e169d4 100644 --- a/host/lib/usrp/b200/b200_iface.hpp +++ b/host/lib/usrp/b200/b200_iface.hpp @@ -9,75 +9,54 @@ #define INCLUDED_B200_IFACE_HPP #include <uhd/transport/usb_control.hpp> -#include <uhd/types/serial.hpp> //i2c iface #include <uhd/types/dict.hpp> +#include <uhd/types/serial.hpp> //i2c iface +#include <uhd/utils/noncopyable.hpp> #include <uhdlib/usrp/common/ad9361_ctrl.hpp> +#include <stdint.h> #include <boost/assign/list_of.hpp> #include <memory> -#include <uhd/utils/noncopyable.hpp> -#include <stdint.h> -enum b200_product_t { - B200, - B210, - B200MINI, - B205MINI -}; +enum b200_product_t { B200, B210, B200MINI, B205MINI }; // These are actual USB PIDs (not Ettus Product IDs) -const static uint16_t B200_VENDOR_ID = 0x2500; -const static uint16_t B200_VENDOR_NI_ID = 0x3923; -const static uint16_t B200_PRODUCT_ID = 0x0020; -const static uint16_t B200MINI_PRODUCT_ID = 0x0021; -const static uint16_t B205MINI_PRODUCT_ID = 0x0022; -const static uint16_t B200_PRODUCT_NI_ID = 0x7813; -const static uint16_t B210_PRODUCT_NI_ID = 0x7814; -const static uint16_t FX3_VID = 0x04b4; -const static uint16_t FX3_DEFAULT_PID = 0x00f3; -const static uint16_t FX3_REENUM_PID = 0x00f0; +const static uint16_t B200_VENDOR_ID = 0x2500; +const static uint16_t B200_VENDOR_NI_ID = 0x3923; +const static uint16_t B200_PRODUCT_ID = 0x0020; +const static uint16_t B200MINI_PRODUCT_ID = 0x0021; +const static uint16_t B205MINI_PRODUCT_ID = 0x0022; +const static uint16_t B200_PRODUCT_NI_ID = 0x7813; +const static uint16_t B210_PRODUCT_NI_ID = 0x7814; +const static uint16_t FX3_VID = 0x04b4; +const static uint16_t FX3_DEFAULT_PID = 0x00f3; +const static uint16_t FX3_REENUM_PID = 0x00f0; //! Map the USB PID to the product (only for PIDs that map to a single product) -static const uhd::dict<uint16_t, b200_product_t> B2XX_PID_TO_PRODUCT = boost::assign::map_list_of - (B200_PRODUCT_NI_ID, B200) - (B210_PRODUCT_NI_ID, B210) - (B200MINI_PRODUCT_ID, B200MINI) - (B205MINI_PRODUCT_ID, B205MINI) -; +static const uhd::dict<uint16_t, b200_product_t> B2XX_PID_TO_PRODUCT = + boost::assign::map_list_of(B200_PRODUCT_NI_ID, B200)(B210_PRODUCT_NI_ID, B210)( + B200MINI_PRODUCT_ID, B200MINI)(B205MINI_PRODUCT_ID, B205MINI); -static const std::string B200_FW_FILE_NAME = "usrp_b200_fw.hex"; -static const std::string B200_BL_FILE_NAME = "usrp_b200_bl.img"; +static const std::string B200_FW_FILE_NAME = "usrp_b200_fw.hex"; +static const std::string B200_BL_FILE_NAME = "usrp_b200_bl.img"; //! Map the EEPROM product ID codes to the product -static const uhd::dict<uint16_t, b200_product_t> B2XX_PRODUCT_ID = boost::assign::map_list_of - (0x0001, B200) - (0x7737, B200) - (B200_PRODUCT_NI_ID, B200) - (0x0002, B210) - (0x7738, B210) - (B210_PRODUCT_NI_ID, B210) - (0x0003, B200MINI) - (0x7739, B200MINI) - (0x0004, B205MINI) - (0x773a, B205MINI) -; - - -static const uhd::dict<b200_product_t, std::string> B2XX_STR_NAMES = boost::assign::map_list_of - (B200, "B200") - (B210, "B210") - (B200MINI, "B200mini") - (B205MINI, "B205mini") -; - -static const uhd::dict<b200_product_t, std::string> B2XX_FPGA_FILE_NAME = boost::assign::map_list_of - (B200, "usrp_b200_fpga.bin") - (B210, "usrp_b210_fpga.bin") - (B200MINI, "usrp_b200mini_fpga.bin") - (B205MINI, "usrp_b205mini_fpga.bin") -; - - -class UHD_API b200_iface: uhd::noncopyable, public virtual uhd::i2c_iface { +static const uhd::dict<uint16_t, b200_product_t> B2XX_PRODUCT_ID = + boost::assign::map_list_of(0x0001, B200)(0x7737, B200)(B200_PRODUCT_NI_ID, B200)( + 0x0002, B210)(0x7738, B210)(B210_PRODUCT_NI_ID, B210)(0x0003, B200MINI)( + 0x7739, B200MINI)(0x0004, B205MINI)(0x773a, B205MINI); + + +static const uhd::dict<b200_product_t, std::string> B2XX_STR_NAMES = + boost::assign::map_list_of(B200, "B200")(B210, "B210")(B200MINI, "B200mini")( + B205MINI, "B205mini"); + +static const uhd::dict<b200_product_t, std::string> B2XX_FPGA_FILE_NAME = + boost::assign::map_list_of(B200, "usrp_b200_fpga.bin")(B210, "usrp_b210_fpga.bin")( + B200MINI, "usrp_b200mini_fpga.bin")(B205MINI, "usrp_b205mini_fpga.bin"); + + +class UHD_API b200_iface : uhd::noncopyable, public virtual uhd::i2c_iface +{ public: typedef std::shared_ptr<b200_iface> sptr; @@ -98,7 +77,7 @@ public: virtual uint16_t get_compat_num(void) = 0; //! load a firmware image - virtual void load_firmware(const std::string filestring, bool force=false) = 0; + virtual void load_firmware(const std::string filestring, bool force = false) = 0; //! reset the FX3 virtual void reset_fx3(void) = 0; @@ -110,14 +89,16 @@ public: virtual void set_fpga_reset_pin(const bool reset) = 0; //! load an FPGA image - virtual uint32_t load_fpga(const std::string filestring, bool force=false) = 0; + virtual uint32_t load_fpga(const std::string filestring, bool force = false) = 0; //! load a bootloader image onto device EEPROM virtual uint32_t load_bootloader(const std::string filestring) = 0; - virtual void write_eeprom(uint16_t addr, uint16_t offset, const uhd::byte_vector_t &bytes) = 0; + virtual void write_eeprom( + uint16_t addr, uint16_t offset, const uhd::byte_vector_t& bytes) = 0; - virtual uhd::byte_vector_t read_eeprom(uint16_t addr, uint16_t offset, size_t num_bytes) = 0; + virtual uhd::byte_vector_t read_eeprom( + uint16_t addr, uint16_t offset, size_t num_bytes) = 0; static std::string fx3_state_string(uint8_t state); }; diff --git a/host/lib/usrp/b200/b200_image_loader.cpp b/host/lib/usrp/b200/b200_image_loader.cpp index cf61ecb88..25bf7ce2f 100644 --- a/host/lib/usrp/b200/b200_image_loader.cpp +++ b/host/lib/usrp/b200/b200_image_loader.cpp @@ -5,77 +5,80 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/assign.hpp> -#include <boost/lexical_cast.hpp> - +#include "b200_iface.hpp" +#include "b200_impl.hpp" #include <uhd/exception.hpp> #include <uhd/image_loader.hpp> #include <uhd/types/dict.hpp> #include <uhd/usrp/mboard_eeprom.hpp> #include <uhd/utils/paths.hpp> #include <uhd/utils/static.hpp> - -#include "b200_iface.hpp" -#include "b200_impl.hpp" +#include <boost/assign.hpp> +#include <boost/lexical_cast.hpp> using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; -namespace uhd{ - -static b200_iface::sptr get_b200_iface(const image_loader::image_loader_args_t& image_loader_args, - mboard_eeprom_t &mb_eeprom, usb_device_handle::sptr& handle, - bool user_specified){ +namespace uhd { - std::vector<usb_device_handle::sptr> dev_handles = get_b200_device_handles(image_loader_args.args); +static b200_iface::sptr get_b200_iface( + const image_loader::image_loader_args_t& image_loader_args, + mboard_eeprom_t& mb_eeprom, + usb_device_handle::sptr& handle, + bool user_specified) +{ + std::vector<usb_device_handle::sptr> dev_handles = + get_b200_device_handles(image_loader_args.args); std::vector<usb_device_handle::sptr> applicable_dev_handles; b200_iface::sptr iface; mboard_eeprom_t eeprom; // Internal use - if(dev_handles.size() > 0){ - for(usb_device_handle::sptr dev_handle: dev_handles){ - if(dev_handle->firmware_loaded()){ - iface = b200_iface::make(usb_control::make(dev_handle, 0)); + if (dev_handles.size() > 0) { + for (usb_device_handle::sptr dev_handle : dev_handles) { + if (dev_handle->firmware_loaded()) { + iface = b200_iface::make(usb_control::make(dev_handle, 0)); eeprom = b200_impl::get_mb_eeprom(iface); - if(user_specified){ - if(image_loader_args.args.has_key("serial") and - eeprom.get("serial") != image_loader_args.args.get("serial")){ - continue; + if (user_specified) { + if (image_loader_args.args.has_key("serial") + and eeprom.get("serial") + != image_loader_args.args.get("serial")) { + continue; } - if(image_loader_args.args.has_key("name") and - eeprom.get("name") != image_loader_args.args.get("name")){ - continue; + if (image_loader_args.args.has_key("name") + and eeprom.get("name") != image_loader_args.args.get("name")) { + continue; } applicable_dev_handles.push_back(dev_handle); - } - else applicable_dev_handles.push_back(dev_handle); + } else + applicable_dev_handles.push_back(dev_handle); } } // At this point, we should have a single B2XX - if(applicable_dev_handles.size() == 1){ + if (applicable_dev_handles.size() == 1) { mb_eeprom = eeprom; - handle = applicable_dev_handles[0]; + handle = applicable_dev_handles[0]; return iface; - } - else if(applicable_dev_handles.size() > 1){ - std::string err_msg = "Could not resolve given args to a single B2XX device.\n" - "Applicable devices:\n"; + } else if (applicable_dev_handles.size() > 1) { + std::string err_msg = + "Could not resolve given args to a single B2XX device.\n" + "Applicable devices:\n"; - for (usb_device_handle::sptr dev_handle: applicable_dev_handles) { + for (usb_device_handle::sptr dev_handle : applicable_dev_handles) { eeprom = b200_impl::get_mb_eeprom( - b200_iface::make(usb_control::make(dev_handle, 0)) - ); - err_msg += str(boost::format(" * %s (serial=%s)\n") - % B2XX_STR_NAMES.get(get_b200_product(dev_handle, mb_eeprom), "B2XX") - % mb_eeprom.get("serial")); + b200_iface::make(usb_control::make(dev_handle, 0))); + err_msg += str( + boost::format(" * %s (serial=%s)\n") + % B2XX_STR_NAMES.get(get_b200_product(dev_handle, mb_eeprom), "B2XX") + % mb_eeprom.get("serial")); } - err_msg += "\nSpecify one of these devices with the given args to load an image onto it."; + err_msg += "\nSpecify one of these devices with the given args to load an " + "image onto it."; throw uhd::runtime_error(err_msg); - } + } } // No applicable devices found, return empty sptr so we can exit @@ -84,45 +87,48 @@ static b200_iface::sptr get_b200_iface(const image_loader::image_loader_args_t& return iface; } -static bool b200_image_loader(const image_loader::image_loader_args_t &image_loader_args){ - if(!image_loader_args.load_fpga) +static bool b200_image_loader(const image_loader::image_loader_args_t& image_loader_args) +{ + if (!image_loader_args.load_fpga) return false; - bool user_specified = (image_loader_args.args.has_key("serial") or - image_loader_args.args.has_key("name")); + bool user_specified = (image_loader_args.args.has_key("serial") + or image_loader_args.args.has_key("name")); // See if a B2x0 with the given args is found mboard_eeprom_t mb_eeprom; usb_device_handle::sptr handle; - b200_iface::sptr iface = get_b200_iface(image_loader_args, mb_eeprom, handle, user_specified); - if(!iface) return false; // No initialized B2x0 found + b200_iface::sptr iface = + get_b200_iface(image_loader_args, mb_eeprom, handle, user_specified); + if (!iface) + return false; // No initialized B2x0 found std::string fpga_path; - if(image_loader_args.fpga_path == ""){ + if (image_loader_args.fpga_path == "") { /* * Normally, we can auto-generate the FPGA filename from what's in the EEPROM, * but if the applicable value is not in the EEPROM, the user must give a specific * filename for us to use. */ std::string product = mb_eeprom.get("product"); - if(not B2XX_PRODUCT_ID.has_key(boost::lexical_cast<uint16_t>(product))){ - if(user_specified){ + if (not B2XX_PRODUCT_ID.has_key(boost::lexical_cast<uint16_t>(product))) { + if (user_specified) { // The user specified a bad device but expects us to know what it is - throw uhd::runtime_error("Could not determine model. You must manually specify an FPGA image filename."); - } - else{ + throw uhd::runtime_error("Could not determine model. You must manually " + "specify an FPGA image filename."); + } else { return false; } + } else { + fpga_path = find_image_path( + B2XX_FPGA_FILE_NAME.get(get_b200_product(handle, mb_eeprom))); } - else{ - fpga_path = find_image_path(B2XX_FPGA_FILE_NAME.get(get_b200_product(handle, mb_eeprom))); - } - } - else fpga_path = image_loader_args.fpga_path; + } else + fpga_path = image_loader_args.fpga_path; std::cout << boost::format("Unit: USRP %s (%s)") - % B2XX_STR_NAMES.get(get_b200_product(handle, mb_eeprom), "B2XX") - % mb_eeprom.get("serial") + % B2XX_STR_NAMES.get(get_b200_product(handle, mb_eeprom), "B2XX") + % mb_eeprom.get("serial") << std::endl; iface->load_fpga(fpga_path, true); @@ -130,10 +136,12 @@ static bool b200_image_loader(const image_loader::image_loader_args_t &image_loa return true; } -UHD_STATIC_BLOCK(register_b200_image_loader){ - std::string recovery_instructions = "This device is likely in an unusable state. Power-cycle the\n" - "device, and the firmware/FPGA will be reloaded the next time\n" - "UHD uses the device."; +UHD_STATIC_BLOCK(register_b200_image_loader) +{ + std::string recovery_instructions = + "This device is likely in an unusable state. Power-cycle the\n" + "device, and the firmware/FPGA will be reloaded the next time\n" + "UHD uses the device."; image_loader::register_image_loader("b200", b200_image_loader, recovery_instructions); } diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp index bf95d8e6b..1da682349 100644 --- a/host/lib/usrp/b200/b200_impl.cpp +++ b/host/lib/usrp/b200/b200_impl.cpp @@ -34,60 +34,78 @@ using namespace uhd::usrp::gpio_atr; using namespace uhd::transport; namespace { - constexpr int64_t REENUMERATION_TIMEOUT_MS = 3000; +constexpr int64_t REENUMERATION_TIMEOUT_MS = 3000; } // B200 + B210: -class b200_ad9361_client_t : public ad9361_params { +class b200_ad9361_client_t : public ad9361_params +{ public: ~b200_ad9361_client_t() {} - double get_band_edge(frequency_band_t band) { + double get_band_edge(frequency_band_t band) + { switch (band) { - case AD9361_RX_BAND0: return 2.2e9; // Port C - case AD9361_RX_BAND1: return 4.0e9; // Port B - case AD9361_TX_BAND0: return 2.5e9; // Port B - default: return 0; + case AD9361_RX_BAND0: + return 2.2e9; // Port C + case AD9361_RX_BAND1: + return 4.0e9; // Port B + case AD9361_TX_BAND0: + return 2.5e9; // Port B + default: + return 0; } } - clocking_mode_t get_clocking_mode() { + clocking_mode_t get_clocking_mode() + { return clocking_mode_t::AD9361_XTAL_N_CLK_PATH; } - digital_interface_mode_t get_digital_interface_mode() { + digital_interface_mode_t get_digital_interface_mode() + { return AD9361_DDR_FDD_LVCMOS; } - digital_interface_delays_t get_digital_interface_timing() { + digital_interface_delays_t get_digital_interface_timing() + { digital_interface_delays_t delays; - delays.rx_clk_delay = 0; + delays.rx_clk_delay = 0; delays.rx_data_delay = 0xF; - delays.tx_clk_delay = 0; + delays.tx_clk_delay = 0; delays.tx_data_delay = 0xF; return delays; } }; // B205 -class b2xxmini_ad9361_client_t : public ad9361_params { +class b2xxmini_ad9361_client_t : public ad9361_params +{ public: ~b2xxmini_ad9361_client_t() {} - double get_band_edge(frequency_band_t band) { + double get_band_edge(frequency_band_t band) + { switch (band) { - case AD9361_RX_BAND0: return 0; // Set these all to - case AD9361_RX_BAND1: return 0; // zero, so RF port A - case AD9361_TX_BAND0: return 0; // is used all the time - default: return 0; // On both Rx and Tx + case AD9361_RX_BAND0: + return 0; // Set these all to + case AD9361_RX_BAND1: + return 0; // zero, so RF port A + case AD9361_TX_BAND0: + return 0; // is used all the time + default: + return 0; // On both Rx and Tx } } - clocking_mode_t get_clocking_mode() { + clocking_mode_t get_clocking_mode() + { return clocking_mode_t::AD9361_XTAL_N_CLK_PATH; } - digital_interface_mode_t get_digital_interface_mode() { + digital_interface_mode_t get_digital_interface_mode() + { return AD9361_DDR_FDD_LVCMOS; } - digital_interface_delays_t get_digital_interface_timing() { + digital_interface_delays_t get_digital_interface_timing() + { digital_interface_delays_t delays; - delays.rx_clk_delay = 0; + delays.rx_clk_delay = 0; delays.rx_data_delay = 0xF; - delays.tx_clk_delay = 0; + delays.tx_clk_delay = 0; delays.tx_data_delay = 0xF; return delays; } @@ -96,16 +114,14 @@ public: /*********************************************************************** * Helpers **********************************************************************/ -std::string check_option_valid( - const std::string &name, - const std::vector<std::string> &valid_options, - const std::string &option -) { - if (std::find(valid_options.begin(), valid_options.end(), option) == valid_options.end()) { - throw uhd::runtime_error(str( - boost::format("Invalid option chosen for: %s") - % name - )); +std::string check_option_valid(const std::string& name, + const std::vector<std::string>& valid_options, + const std::string& option) +{ + if (std::find(valid_options.begin(), valid_options.end(), option) + == valid_options.end()) { + throw uhd::runtime_error( + str(boost::format("Invalid option chosen for: %s") % name)); } return option; @@ -117,7 +133,8 @@ std::string check_option_valid( //! Look up the type of B-Series device we're currently running. // Throws a uhd::runtime_error if the USB PID and the product ID stored // in the MB EEPROM are invalid, -b200_product_t get_b200_product(const usb_device_handle::sptr& handle, const mboard_eeprom_t &mb_eeprom) +b200_product_t get_b200_product( + const usb_device_handle::sptr& handle, const mboard_eeprom_t& mb_eeprom) { // Try USB PID first uint16_t product_id = handle->get_product_id(); @@ -130,40 +147,42 @@ b200_product_t get_b200_product(const usb_device_handle::sptr& handle, const mbo } product_id = boost::lexical_cast<uint16_t>(mb_eeprom["product"]); if (not B2XX_PRODUCT_ID.has_key(product_id)) { - throw uhd::runtime_error(str( - boost::format("B200 unknown product code: 0x%04x") - % product_id - )); + throw uhd::runtime_error( + str(boost::format("B200 unknown product code: 0x%04x") % product_id)); } return B2XX_PRODUCT_ID[product_id]; } -std::vector<usb_device_handle::sptr> get_b200_device_handles(const device_addr_t &hint) +std::vector<usb_device_handle::sptr> get_b200_device_handles(const device_addr_t& hint) { std::vector<usb_device_handle::vid_pid_pair_t> vid_pid_pair_list; - if(hint.has_key("vid") && hint.has_key("pid") && hint.has_key("type") && hint["type"] == "b200") { - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(uhd::cast::hexstr_cast<uint16_t>(hint.get("vid")), - uhd::cast::hexstr_cast<uint16_t>(hint.get("pid")))); + if (hint.has_key("vid") && hint.has_key("pid") && hint.has_key("type") + && hint["type"] == "b200") { + vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t( + uhd::cast::hexstr_cast<uint16_t>(hint.get("vid")), + uhd::cast::hexstr_cast<uint16_t>(hint.get("pid")))); } else { vid_pid_pair_list = b200_vid_pid_pairs; } - //find the usrps and load firmware + // find the usrps and load firmware return usb_device_handle::get_device_list(vid_pid_pair_list); } -static device_addrs_t b200_find(const device_addr_t &hint) +static device_addrs_t b200_find(const device_addr_t& hint) { device_addrs_t b200_addrs; - //return an empty list of addresses when type is set to non-b200 - if (hint.has_key("type") and hint["type"] != "b200") return b200_addrs; + // return an empty list of addresses when type is set to non-b200 + if (hint.has_key("type") and hint["type"] != "b200") + return b200_addrs; - //Return an empty list of addresses when an address or resource is specified, - //since an address and resource is intended for a different, non-USB, device. - for(device_addr_t hint_i: separate_device_addr(hint)) { - if (hint_i.has_key("addr") || hint_i.has_key("resource")) return b200_addrs; + // Return an empty list of addresses when an address or resource is specified, + // since an address and resource is intended for a different, non-USB, device. + for (device_addr_t hint_i : separate_device_addr(hint)) { + if (hint_i.has_key("addr") || hint_i.has_key("resource")) + return b200_addrs; } // Important note: @@ -172,64 +191,66 @@ static device_addrs_t b200_find(const device_addr_t &hint) // so that re-enumeration after fw load can occur successfully. // This requirement is a courtesy of libusb1.0 on windows. size_t found = 0; - for(usb_device_handle::sptr handle: get_b200_device_handles(hint)) { - //extract the firmware path for the b200 + for (usb_device_handle::sptr handle : get_b200_device_handles(hint)) { + // extract the firmware path for the b200 std::string b200_fw_image; - try{ + try { b200_fw_image = hint.get("fw", B200_FW_FILE_NAME); - b200_fw_image = uhd::find_image_path(b200_fw_image, STR(UHD_IMAGES_DIR)); // FIXME - } - catch(uhd::exception &e){ + b200_fw_image = + uhd::find_image_path(b200_fw_image, STR(UHD_IMAGES_DIR)); // FIXME + } catch (uhd::exception& e) { UHD_LOGGER_WARNING("B200") << e.what(); return b200_addrs; } - UHD_LOGGER_DEBUG("B200") << "the firmware image: " << b200_fw_image ; + UHD_LOGGER_DEBUG("B200") << "the firmware image: " << b200_fw_image; usb_control::sptr control; - try{control = usb_control::make(handle, 0);} - catch(const uhd::exception &){continue;} //ignore claimed + try { + control = usb_control::make(handle, 0); + } catch (const uhd::exception&) { + continue; + } // ignore claimed - //check if fw was already loaded - if (!(handle->firmware_loaded())) - { + // check if fw was already loaded + if (!(handle->firmware_loaded())) { b200_iface::make(control)->load_firmware(b200_fw_image); } found++; } - const auto timeout_time = - std::chrono::steady_clock::now() - + std::chrono::milliseconds(REENUMERATION_TIMEOUT_MS); - //search for the device until found or timeout - while (std::chrono::steady_clock::now() < timeout_time - and b200_addrs.empty() - and found != 0) { - for(usb_device_handle::sptr handle: get_b200_device_handles(hint)) { + const auto timeout_time = std::chrono::steady_clock::now() + + std::chrono::milliseconds(REENUMERATION_TIMEOUT_MS); + // search for the device until found or timeout + while (std::chrono::steady_clock::now() < timeout_time and b200_addrs.empty() + and found != 0) { + for (usb_device_handle::sptr handle : get_b200_device_handles(hint)) { usb_control::sptr control; - try{control = usb_control::make(handle, 0);} - catch(const uhd::exception &){continue;} //ignore claimed + try { + control = usb_control::make(handle, 0); + } catch (const uhd::exception&) { + continue; + } // ignore claimed - b200_iface::sptr iface = b200_iface::make(control); + b200_iface::sptr iface = b200_iface::make(control); const mboard_eeprom_t mb_eeprom = b200_impl::get_mb_eeprom(iface); device_addr_t new_addr; - new_addr["type"] = "b200"; - new_addr["name"] = mb_eeprom["name"]; + new_addr["type"] = "b200"; + new_addr["name"] = mb_eeprom["name"]; new_addr["serial"] = handle->get_serial(); try { // Turn the 16-Bit product ID into a string representation new_addr["product"] = B2XX_STR_NAMES[get_b200_product(handle, mb_eeprom)]; - } catch (const uhd::runtime_error &) { + } catch (const uhd::runtime_error&) { // No problem if this fails -- this is just device discovery, after all. new_addr["product"] = "B2??"; } - //this is a found b200 when the hint serial and name match or blank - if ( - (not hint.has_key("name") or hint["name"] == new_addr["name"]) and - (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) - ){ + // this is a found b200 when the hint serial and name match or blank + if ((not hint.has_key("name") or hint["name"] == new_addr["name"]) + and (not hint.has_key("serial") + or hint["serial"] == new_addr["serial"])) { b200_addrs.push_back(new_addr); } } @@ -241,7 +262,7 @@ static device_addrs_t b200_find(const device_addr_t &hint) /*********************************************************************** * Make **********************************************************************/ -static device::sptr b200_make(const device_addr_t &device_addr) +static device::sptr b200_make(const device_addr_t& device_addr) { uhd::transport::usb_device_handle::sptr handle; @@ -250,14 +271,14 @@ static device::sptr b200_make(const device_addr_t &device_addr) // a third time is pointless. try { return device::sptr(new b200_impl(device_addr, handle)); - } - catch (const uhd::usb_error &) { - UHD_LOGGER_INFO("B200") << "Detected bad USB state; resetting." ; + } catch (const uhd::usb_error&) { + UHD_LOGGER_INFO("B200") << "Detected bad USB state; resetting."; libusb::device_handle::sptr dev_handle(libusb::device_handle::get_cached_handle( - std::static_pointer_cast<libusb::special_handle>(handle)->get_device() - )); - dev_handle->clear_endpoints(B200_USB_CTRL_RECV_ENDPOINT, B200_USB_CTRL_SEND_ENDPOINT); - dev_handle->clear_endpoints(B200_USB_DATA_RECV_ENDPOINT, B200_USB_DATA_SEND_ENDPOINT); + std::static_pointer_cast<libusb::special_handle>(handle)->get_device())); + dev_handle->clear_endpoints( + B200_USB_CTRL_RECV_ENDPOINT, B200_USB_CTRL_SEND_ENDPOINT); + dev_handle->clear_endpoints( + B200_USB_DATA_RECV_ENDPOINT, B200_USB_DATA_SEND_ENDPOINT); dev_handle->reset_device(); } @@ -272,84 +293,96 @@ UHD_STATIC_BLOCK(register_b200_device) /*********************************************************************** * Structors **********************************************************************/ -b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::sptr &handle) : - _product(B200), // Some safe value - _revision(0), - _enable_user_regs(device_addr.has_key("enable_user_regs")), - _time_source(UNKNOWN), - _tick_rate(0.0) // Forces a clock initialization at startup +b200_impl::b200_impl( + const uhd::device_addr_t& device_addr, usb_device_handle::sptr& handle) + : _product(B200) + , // Some safe value + _revision(0) + , _enable_user_regs(device_addr.has_key("enable_user_regs")) + , _time_source(UNKNOWN) + , _tick_rate(0.0) // Forces a clock initialization at startup { - _tree = property_tree::make(); - _type = device::USRP; + _tree = property_tree::make(); + _type = device::USRP; const fs_path mb_path = "/mboards/0"; - //try to match the given device address with something on the USB bus - uint16_t vid = B200_VENDOR_ID; - uint16_t pid = B200_PRODUCT_ID; + // try to match the given device address with something on the USB bus + uint16_t vid = B200_VENDOR_ID; + uint16_t pid = B200_PRODUCT_ID; bool specified_vid = false; bool specified_pid = false; - if (device_addr.has_key("vid")) - { - vid = uhd::cast::hexstr_cast<uint16_t>(device_addr.get("vid")); + if (device_addr.has_key("vid")) { + vid = uhd::cast::hexstr_cast<uint16_t>(device_addr.get("vid")); specified_vid = true; } - if (device_addr.has_key("pid")) - { - pid = uhd::cast::hexstr_cast<uint16_t>(device_addr.get("pid")); + if (device_addr.has_key("pid")) { + pid = uhd::cast::hexstr_cast<uint16_t>(device_addr.get("pid")); specified_pid = true; } - std::vector<usb_device_handle::vid_pid_pair_t> vid_pid_pair_list;//search list for devices. + std::vector<usb_device_handle::vid_pid_pair_t> + vid_pid_pair_list; // search list for devices. // Search only for specified VID and PID if both specified - if (specified_vid && specified_pid) - { - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid,pid)); + if (specified_vid && specified_pid) { + vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid, pid)); } // Search for all supported PIDs limited to specified VID if only VID specified - else if (specified_vid) - { - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid, B200_PRODUCT_ID)); - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid, B200MINI_PRODUCT_ID)); - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid, B205MINI_PRODUCT_ID)); - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid, B200_PRODUCT_NI_ID)); - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid, B210_PRODUCT_NI_ID)); + else if (specified_vid) { + vid_pid_pair_list.push_back( + usb_device_handle::vid_pid_pair_t(vid, B200_PRODUCT_ID)); + vid_pid_pair_list.push_back( + usb_device_handle::vid_pid_pair_t(vid, B200MINI_PRODUCT_ID)); + vid_pid_pair_list.push_back( + usb_device_handle::vid_pid_pair_t(vid, B205MINI_PRODUCT_ID)); + vid_pid_pair_list.push_back( + usb_device_handle::vid_pid_pair_t(vid, B200_PRODUCT_NI_ID)); + vid_pid_pair_list.push_back( + usb_device_handle::vid_pid_pair_t(vid, B210_PRODUCT_NI_ID)); } // Search for all supported VIDs limited to specified PID if only PID specified - else if (specified_pid) - { - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID,pid)); - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID,pid)); + else if (specified_pid) { + vid_pid_pair_list.push_back( + usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, pid)); + vid_pid_pair_list.push_back( + usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, pid)); } // Search for all supported devices if neither VID nor PID specified - else - { - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B200_PRODUCT_ID)); - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B200MINI_PRODUCT_ID)); - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B205MINI_PRODUCT_ID)); - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B200_PRODUCT_NI_ID)); - vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B210_PRODUCT_NI_ID)); + else { + vid_pid_pair_list.push_back( + usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B200_PRODUCT_ID)); + vid_pid_pair_list.push_back( + usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B200MINI_PRODUCT_ID)); + vid_pid_pair_list.push_back( + usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B205MINI_PRODUCT_ID)); + vid_pid_pair_list.push_back( + usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B200_PRODUCT_NI_ID)); + vid_pid_pair_list.push_back( + usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B210_PRODUCT_NI_ID)); } - std::vector<usb_device_handle::sptr> device_list = usb_device_handle::get_device_list(vid_pid_pair_list); + std::vector<usb_device_handle::sptr> device_list = + usb_device_handle::get_device_list(vid_pid_pair_list); - //locate the matching handle in the device list - for(usb_device_handle::sptr dev_handle: device_list) { + // locate the matching handle in the device list + for (usb_device_handle::sptr dev_handle : device_list) { try { - if (dev_handle->get_serial() == device_addr["serial"]){ + if (dev_handle->get_serial() == device_addr["serial"]) { handle = dev_handle; break; } - } catch (const uhd::exception&) { continue; } + } catch (const uhd::exception&) { + continue; + } } - UHD_ASSERT_THROW(handle.get() != NULL); //better be found + UHD_ASSERT_THROW(handle.get() != NULL); // better be found - //create control objects + // create control objects usb_control::sptr control = usb_control::make(handle, 0); - _iface = b200_iface::make(control); - this->check_fw_compat(); //check after making + _iface = b200_iface::make(control); + this->check_fw_compat(); // check after making //////////////////////////////////////////////////////////////////// // setup the mboard eeprom @@ -357,7 +390,8 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s const mboard_eeprom_t mb_eeprom = get_mb_eeprom(_iface); _tree->create<mboard_eeprom_t>(mb_path / "eeprom") .set(mb_eeprom) - .add_coerced_subscriber(std::bind(&b200_impl::set_mb_eeprom, this, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b200_impl::set_mb_eeprom, this, std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // Identify the device type @@ -366,10 +400,10 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s std::string product_name; try { // This will throw if the product ID is invalid: - _product = get_b200_product(handle, mb_eeprom); + _product = get_b200_product(handle, mb_eeprom); default_file_name = B2XX_FPGA_FILE_NAME.get(_product); product_name = B2XX_STR_NAMES.get(_product); - } catch (const uhd::runtime_error &e) { + } catch (const uhd::runtime_error& e) { // The only reason we may let this pass is if the user specified // the FPGA file name: if (not device_addr.has_key("fpga")) { @@ -382,9 +416,9 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s _revision = boost::lexical_cast<size_t>(mb_eeprom["revision"]); } - UHD_LOGGER_INFO("B200") << "Detected Device: " << B2XX_STR_NAMES[_product] ; + UHD_LOGGER_INFO("B200") << "Detected Device: " << B2XX_STR_NAMES[_product]; - _gpsdo_capable = (not (_product == B200MINI or _product == B205MINI)); + _gpsdo_capable = (not(_product == B200MINI or _product == B205MINI)); //////////////////////////////////////////////////////////////////// // Set up frontend mapping @@ -399,27 +433,27 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s // does not have an FE2, so we don't swap FEs. // Swapped setup: - _fe1 = 1; - _fe2 = 0; + _fe1 = 1; + _fe2 = 0; _gpio_state.swap_atr = 1; // Unswapped setup: - if (_product == B200MINI or _product == B205MINI or (_product == B200 and _revision >= 5)) { - _fe1 = 0; //map radio0 to FE1 - _fe2 = 1; //map radio1 to FE2 + if (_product == B200MINI or _product == B205MINI + or (_product == B200 and _revision >= 5)) { + _fe1 = 0; // map radio0 to FE1 + _fe2 = 1; // map radio1 to FE2 _gpio_state.swap_atr = 0; // ATRs for radio0 are mapped to FE1 } //////////////////////////////////////////////////////////////////// // Load the FPGA image, then reset GPIF //////////////////////////////////////////////////////////////////// - //extract the FPGA path for the B200 + // extract the FPGA path for the B200 std::string b200_fpga_image = find_image_path( - device_addr.has_key("fpga")? device_addr["fpga"] : default_file_name - ); + device_addr.has_key("fpga") ? device_addr["fpga"] : default_file_name); uint32_t status = _iface->load_fpga(b200_fpga_image); - if(status != 0) { + if (status != 0) { throw uhd::runtime_error(str(boost::format("fx3 is in state %1%") % status)); } @@ -429,7 +463,7 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s // Create control transport //////////////////////////////////////////////////////////////////// uint8_t usb_speed = _iface->get_usb_speed(); - UHD_LOGGER_INFO("B200") << "Operating over USB " << (int) usb_speed << "." ; + UHD_LOGGER_INFO("B200") << "Operating over USB " << (int)usb_speed << "."; const std::string min_frame_size = (usb_speed == 3) ? "1024" : "512"; device_addr_t ctrl_xport_args; @@ -439,32 +473,38 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s ctrl_xport_args["num_send_frames"] = "16"; // This may throw a uhd::usb_error, which will be caught by b200_make(). - _ctrl_transport = usb_zero_copy::make( - handle, - B200_USB_CTRL_RECV_INTERFACE, B200_USB_CTRL_RECV_ENDPOINT, //interface, endpoint - B200_USB_CTRL_SEND_INTERFACE, B200_USB_CTRL_SEND_ENDPOINT, //interface, endpoint - ctrl_xport_args - ); - while (_ctrl_transport->get_recv_buff(0.0)){} //flush ctrl xport - _tree->create<double>(mb_path / "link_max_rate").set((usb_speed == 3) ? B200_MAX_RATE_USB3 : B200_MAX_RATE_USB2); + _ctrl_transport = usb_zero_copy::make(handle, + B200_USB_CTRL_RECV_INTERFACE, + B200_USB_CTRL_RECV_ENDPOINT, // interface, endpoint + B200_USB_CTRL_SEND_INTERFACE, + B200_USB_CTRL_SEND_ENDPOINT, // interface, endpoint + ctrl_xport_args); + while (_ctrl_transport->get_recv_buff(0.0)) { + } // flush ctrl xport + _tree->create<double>(mb_path / "link_max_rate") + .set((usb_speed == 3) ? B200_MAX_RATE_USB3 : B200_MAX_RATE_USB2); //////////////////////////////////////////////////////////////////// // Async task structure //////////////////////////////////////////////////////////////////// _async_task_data.reset(new AsyncTaskData()); - _async_task_data->async_md.reset(new async_md_type(1000/*messages deep*/)); - if (_gpsdo_capable) - { - _async_task_data->gpsdo_uart = b200_uart::make(_ctrl_transport, B200_TX_GPS_UART_SID); + _async_task_data->async_md.reset(new async_md_type(1000 /*messages deep*/)); + if (_gpsdo_capable) { + _async_task_data->gpsdo_uart = + b200_uart::make(_ctrl_transport, B200_TX_GPS_UART_SID); } - _async_task = uhd::msg_task::make(std::bind(&b200_impl::handle_async_task, this, _ctrl_transport, _async_task_data)); + _async_task = uhd::msg_task::make(std::bind( + &b200_impl::handle_async_task, this, _ctrl_transport, _async_task_data)); //////////////////////////////////////////////////////////////////// // Local control endpoint //////////////////////////////////////////////////////////////////// - _local_ctrl = radio_ctrl_core_3000::make(false/*lilE*/, _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 + _async_task_data->local_ctrl = _local_ctrl; // weak this->check_fpga_compat(); /* Initialize the GPIOs, set the default bandsels to the lower range. Note @@ -475,30 +515,21 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s //////////////////////////////////////////////////////////////////// // Create the GPSDO control //////////////////////////////////////////////////////////////////// - if (_gpsdo_capable) - { - - if ((_local_ctrl->peek32(RB32_CORE_STATUS) & 0xff) != B200_GPSDO_ST_NONE) - { + if (_gpsdo_capable) { + if ((_local_ctrl->peek32(RB32_CORE_STATUS) & 0xff) != B200_GPSDO_ST_NONE) { UHD_LOGGER_INFO("B200") << "Detecting internal GPSDO.... " << std::flush; - try - { + try { _gps = gps_ctrl::make(_async_task_data->gpsdo_uart); + } catch (std::exception& e) { + UHD_LOGGER_ERROR("B200") + << "An error occurred making GPSDO control: " << e.what(); } - catch(std::exception &e) - { - UHD_LOGGER_ERROR("B200") << "An error occurred making GPSDO control: " << e.what(); - } - if (_gps and _gps->gps_detected()) - { - for(const std::string &name: _gps->get_sensors()) - { + if (_gps and _gps->gps_detected()) { + for (const std::string& name : _gps->get_sensors()) { _tree->create<sensor_value_t>(mb_path / "sensors" / name) .set_publisher(std::bind(&gps_ctrl::get_sensor, _gps, name)); } - } - else - { + } else { _local_ctrl->poke32(TOREG(SR_CORE_GPSDO_ST), B200_GPSDO_ST_NONE); } } @@ -509,7 +540,8 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s //////////////////////////////////////////////////////////////////// _tree->create<std::string>("/name").set("B-Series Device"); _tree->create<std::string>(mb_path / "name").set(product_name); - _tree->create<std::string>(mb_path / "codename").set((_product == B200MINI or _product == B205MINI) ? "Pixie" : "Sasquatch"); + _tree->create<std::string>(mb_path / "codename") + .set((_product == B200MINI or _product == B205MINI) ? "Pixie" : "Sasquatch"); //////////////////////////////////////////////////////////////////// // Create data transport @@ -519,22 +551,18 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s //////////////////////////////////////////////////////////////////// device_addr_t data_xport_args; const int max_transfer = usb_speed == 3 ? 1024 : 512; - int recv_frame_size = device_addr.cast<int>( - "recv_frame_size", - B200_USB_DATA_DEFAULT_FRAME_SIZE - ); + int recv_frame_size = + device_addr.cast<int>("recv_frame_size", B200_USB_DATA_DEFAULT_FRAME_SIZE); // Check that recv_frame_size limits. if (recv_frame_size < B200_USB_DATA_MIN_RECV_FRAME_SIZE) { - UHD_LOGGER_WARNING("B200") - << "Requested recv_frame_size of " << recv_frame_size - << " is too small. It will be set to " - << B200_USB_DATA_MIN_RECV_FRAME_SIZE << "."; + UHD_LOGGER_WARNING("B200") << "Requested recv_frame_size of " << recv_frame_size + << " is too small. It will be set to " + << B200_USB_DATA_MIN_RECV_FRAME_SIZE << "."; recv_frame_size = B200_USB_DATA_MIN_RECV_FRAME_SIZE; } else if (recv_frame_size > B200_USB_DATA_MAX_RECV_FRAME_SIZE) { - UHD_LOGGER_WARNING("B200") - << "Requested recv_frame_size of " << recv_frame_size - << " is too large. It will be set to " - << B200_USB_DATA_MAX_RECV_FRAME_SIZE << "."; + UHD_LOGGER_WARNING("B200") << "Requested recv_frame_size of " << recv_frame_size + << " is too large. It will be set to " + << B200_USB_DATA_MAX_RECV_FRAME_SIZE << "."; recv_frame_size = B200_USB_DATA_MAX_RECV_FRAME_SIZE; } else if (recv_frame_size % max_transfer == 0 or recv_frame_size % 8 != 0) { // The Cypress FX3 does not properly handle recv_frame_sizes that are @@ -553,37 +581,39 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s UHD_LOGGER_WARNING("B200") << "The recv_frame_size must be a multiple of 8 bytes and not a multiple of " << max_transfer << " bytes. Requested recv_frame_size of " - << device_addr["recv_frame_size"] - << " coerced to " << recv_frame_size << "."; + << device_addr["recv_frame_size"] << " coerced to " << recv_frame_size << "."; } data_xport_args["recv_frame_size"] = std::to_string(recv_frame_size); data_xport_args["num_recv_frames"] = device_addr.get("num_recv_frames", "16"); - data_xport_args["send_frame_size"] = device_addr.get("send_frame_size", std::to_string(B200_USB_DATA_DEFAULT_FRAME_SIZE)); + data_xport_args["send_frame_size"] = device_addr.get( + "send_frame_size", std::to_string(B200_USB_DATA_DEFAULT_FRAME_SIZE)); data_xport_args["num_send_frames"] = device_addr.get("num_send_frames", "16"); // This may throw a uhd::usb_error, which will be caught by b200_make(). - _data_transport = usb_zero_copy::make( - handle, // identifier - B200_USB_DATA_RECV_INTERFACE, B200_USB_DATA_RECV_ENDPOINT, //interface, endpoint - B200_USB_DATA_SEND_INTERFACE, B200_USB_DATA_SEND_ENDPOINT, //interface, endpoint - data_xport_args // param hints + _data_transport = usb_zero_copy::make(handle, // identifier + B200_USB_DATA_RECV_INTERFACE, + B200_USB_DATA_RECV_ENDPOINT, // interface, endpoint + B200_USB_DATA_SEND_INTERFACE, + B200_USB_DATA_SEND_ENDPOINT, // interface, endpoint + data_xport_args // param hints ); - while (_data_transport->get_recv_buff(0.0)){} //flush ctrl xport + while (_data_transport->get_recv_buff(0.0)) { + } // flush ctrl xport _demux = recv_packet_demuxer_3000::make(_data_transport); //////////////////////////////////////////////////////////////////// // create time and clock control objects //////////////////////////////////////////////////////////////////// _spi_iface = b200_local_spi_core::make(_local_ctrl); - if (not (_product == B200MINI or _product == B205MINI)) { + if (not(_product == B200MINI or _product == B205MINI)) { _adf4001_iface = std::make_shared<b200_ref_pll_ctrl>(_spi_iface); } //////////////////////////////////////////////////////////////////// // Init codec - turns on clocks //////////////////////////////////////////////////////////////////// - UHD_LOGGER_INFO("B200") << "Initialize CODEC control..." ; + UHD_LOGGER_INFO("B200") << "Initialize CODEC control..."; reset_codec(); ad9361_params::sptr client_settings; if (_product == B200MINI or _product == B205MINI) { @@ -598,13 +628,15 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s //////////////////////////////////////////////////////////////////// { const fs_path codec_path = mb_path / ("rx_codecs") / "A"; - _tree->create<std::string>(codec_path / "name").set(product_name+" RX dual ADC"); - _tree->create<int>(codec_path / "gains"); //empty cuz gains are in frontend + _tree->create<std::string>(codec_path / "name") + .set(product_name + " RX dual ADC"); + _tree->create<int>(codec_path / "gains"); // empty cuz gains are in frontend } { const fs_path codec_path = mb_path / ("tx_codecs") / "A"; - _tree->create<std::string>(codec_path / "name").set(product_name+" TX dual DAC"); - _tree->create<int>(codec_path / "gains"); //empty cuz gains are in frontend + _tree->create<std::string>(codec_path / "name") + .set(product_name + " TX dual DAC"); + _tree->create<int>(codec_path / "gains"); // empty cuz gains are in frontend } //////////////////////////////////////////////////////////////////// @@ -613,12 +645,11 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s _tree->create<double>(mb_path / "tick_rate") .set_coercer(std::bind(&b200_impl::set_tick_rate, this, std::placeholders::_1)) .set_publisher(std::bind(&b200_impl::get_tick_rate, this)) - .add_coerced_subscriber(std::bind(&b200_impl::update_tick_rate, this, std::placeholders::_1)); - _tree->create<meta_range_t>(mb_path / "tick_rate/range") - .set_publisher([this](){ - return this->_codec_ctrl->get_clock_rate_range(); - }) - ; + .add_coerced_subscriber( + std::bind(&b200_impl::update_tick_rate, this, std::placeholders::_1)); + _tree->create<meta_range_t>(mb_path / "tick_rate/range").set_publisher([this]() { + return this->_codec_ctrl->get_clock_rate_range(); + }); _tree->create<time_spec_t>(mb_path / "time" / "cmd"); _tree->create<bool>(mb_path / "auto_tick_rate").set(false); @@ -631,22 +662,27 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s //////////////////////////////////////////////////////////////////// // create frontend mapping //////////////////////////////////////////////////////////////////// - std::vector<size_t> default_map(2, 0); default_map[1] = 1; // Set this to A->0 B->1 even if there's only A - _tree->create<std::vector<size_t> >(mb_path / "rx_chan_dsp_mapping").set(default_map); - _tree->create<std::vector<size_t> >(mb_path / "tx_chan_dsp_mapping").set(default_map); + std::vector<size_t> default_map(2, 0); + default_map[1] = 1; // Set this to A->0 B->1 even if there's only A + _tree->create<std::vector<size_t>>(mb_path / "rx_chan_dsp_mapping").set(default_map); + _tree->create<std::vector<size_t>>(mb_path / "tx_chan_dsp_mapping").set(default_map); _tree->create<subdev_spec_t>(mb_path / "rx_subdev_spec") - .set_coercer(std::bind(&b200_impl::coerce_subdev_spec, this, std::placeholders::_1)) + .set_coercer( + std::bind(&b200_impl::coerce_subdev_spec, this, std::placeholders::_1)) .set(subdev_spec_t()) - .add_coerced_subscriber(std::bind(&b200_impl::update_subdev_spec, this, "rx", std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b200_impl::update_subdev_spec, this, "rx", std::placeholders::_1)); _tree->create<subdev_spec_t>(mb_path / "tx_subdev_spec") - .set_coercer(std::bind(&b200_impl::coerce_subdev_spec, this, std::placeholders::_1)) + .set_coercer( + std::bind(&b200_impl::coerce_subdev_spec, this, std::placeholders::_1)) .set(subdev_spec_t()) - .add_coerced_subscriber(std::bind(&b200_impl::update_subdev_spec, this, "tx", std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b200_impl::update_subdev_spec, this, "tx", std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // setup radio control //////////////////////////////////////////////////////////////////// - UHD_LOGGER_INFO("B200") << "Initialize Radio control..." ; + UHD_LOGGER_INFO("B200") << "Initialize Radio control..."; const size_t num_radio_chains = ((_local_ctrl->peek32(RB32_CORE_STATUS) >> 8) & 0xff); UHD_ASSERT_THROW(num_radio_chains > 0); UHD_ASSERT_THROW(num_radio_chains <= 2); @@ -656,141 +692,162 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s for (size_t i = 0; i < _radio_perifs.size(); i++) this->setup_radio(i); - //now test each radio module's connection to the codec interface - for (radio_perifs_t &perif : _radio_perifs) { + // now test each radio module's connection to the codec interface + for (radio_perifs_t& perif : _radio_perifs) { _codec_mgr->loopback_self_test( - [&perif](const uint32_t value){ + [&perif](const uint32_t value) { perif.ctrl->poke32(TOREG(SR_CODEC_IDLE), value); }, - [&perif](){ - return perif.ctrl->peek64(RB64_CODEC_READBACK); - } - ); + [&perif]() { return perif.ctrl->peek64(RB64_CODEC_READBACK); }); } - //register time now and pps onto available radio cores + // register time now and pps onto available radio cores _tree->create<time_spec_t>(mb_path / "time" / "now") .set_publisher(std::bind(&time_core_3000::get_time_now, _radio_perifs[0].time64)) - .add_coerced_subscriber(std::bind(&b200_impl::set_time, this, std::placeholders::_1)) + .add_coerced_subscriber( + std::bind(&b200_impl::set_time, this, std::placeholders::_1)) .set(0.0); - //re-sync the times when the tick rate changes + // re-sync the times when the tick rate changes _tree->access<double>(mb_path / "tick_rate") .add_coerced_subscriber(std::bind(&b200_impl::sync_times, this)); _tree->create<time_spec_t>(mb_path / "time" / "pps") - .set_publisher(std::bind(&time_core_3000::get_time_last_pps, _radio_perifs[0].time64)); - for(radio_perifs_t &perif: _radio_perifs) - { + .set_publisher( + std::bind(&time_core_3000::get_time_last_pps, _radio_perifs[0].time64)); + for (radio_perifs_t& perif : _radio_perifs) { _tree->access<time_spec_t>(mb_path / "time" / "pps") - .add_coerced_subscriber(std::bind(&time_core_3000::set_time_next_pps, perif.time64, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &time_core_3000::set_time_next_pps, perif.time64, std::placeholders::_1)); } - //setup time source props + // setup time source props const std::vector<std::string> time_sources = - (_gpsdo_capable) ? - std::vector<std::string>{"none", "internal", "external", "gpsdo"} : - std::vector<std::string>{"none", "internal", "external"}; - _tree->create<std::vector<std::string> >(mb_path / "time_source" / "options") + (_gpsdo_capable) + ? std::vector<std::string>{"none", "internal", "external", "gpsdo"} + : std::vector<std::string>{"none", "internal", "external"}; + _tree->create<std::vector<std::string>>(mb_path / "time_source" / "options") .set(time_sources); _tree->create<std::string>(mb_path / "time_source" / "value") - .set_coercer(std::bind(&check_option_valid, "time source", time_sources, std::placeholders::_1)) - .add_coerced_subscriber(std::bind(&b200_impl::update_time_source, this, std::placeholders::_1)); - //setup reference source props + .set_coercer(std::bind( + &check_option_valid, "time source", time_sources, std::placeholders::_1)) + .add_coerced_subscriber( + std::bind(&b200_impl::update_time_source, this, std::placeholders::_1)); + // setup reference source props const std::vector<std::string> clock_sources = - (_gpsdo_capable) ? - std::vector<std::string>{"internal", "external", "gpsdo"} : - std::vector<std::string>{"internal", "external"}; - _tree->create<std::vector<std::string> >(mb_path / "clock_source" / "options") + (_gpsdo_capable) ? std::vector<std::string>{"internal", "external", "gpsdo"} + : std::vector<std::string>{"internal", "external"}; + _tree->create<std::vector<std::string>>(mb_path / "clock_source" / "options") .set(clock_sources); _tree->create<std::string>(mb_path / "clock_source" / "value") - .set_coercer(std::bind(&check_option_valid, "clock source", clock_sources, std::placeholders::_1)) - .add_coerced_subscriber(std::bind(&b200_impl::update_clock_source, this, std::placeholders::_1)); + .set_coercer(std::bind( + &check_option_valid, "clock source", clock_sources, std::placeholders::_1)) + .add_coerced_subscriber( + std::bind(&b200_impl::update_clock_source, this, std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // front panel gpio //////////////////////////////////////////////////////////////////// - _radio_perifs[0].fp_gpio = gpio_atr_3000::make(_radio_perifs[0].ctrl, TOREG(SR_FP_GPIO), RB32_FP_GPIO); - for(const gpio_attr_map_t::value_type attr: gpio_attr_map) - { switch (attr.first){ - case usrp::gpio_atr::GPIO_SRC: - _tree->create<std::vector<std::string>>(mb_path / "gpio" / "FP0" / attr.second) - .set(std::vector<std::string>(32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) - .add_coerced_subscriber([this](const std::vector<std::string>&){ - throw uhd::runtime_error("This device does not support setting the GPIO_SRC attribute."); - }); - break; - case usrp::gpio_atr::GPIO_CTRL: - case usrp::gpio_atr::GPIO_DDR: - _tree->create<std::vector<std::string>>(mb_path / "gpio" / "FP0" / attr.second) - .set(std::vector<std::string>(32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) - .add_coerced_subscriber([this, attr](const std::vector<std::string> str_val){ - uint32_t val = 0; - for(size_t i = 0 ; i < str_val.size() ; i++){ - val += usrp::gpio_atr::gpio_attr_value_pair.at(attr.second).at(str_val[i])<<i; - } - _radio_perifs[0].fp_gpio->set_gpio_attr(attr.first, val); - }); - break; - case usrp::gpio_atr::GPIO_READBACK: - _tree->create<uint32_t>(mb_path / "gpio" / "FP0" / "READBACK") - .set_publisher(std::bind(&gpio_atr_3000::read_gpio, _radio_perifs[0].fp_gpio)); - break; - default: - _tree->create<uint32_t>(mb_path / "gpio" / "FP0" / attr.second) + _radio_perifs[0].fp_gpio = + gpio_atr_3000::make(_radio_perifs[0].ctrl, TOREG(SR_FP_GPIO), RB32_FP_GPIO); + for (const gpio_attr_map_t::value_type attr : gpio_attr_map) { + switch (attr.first) { + case usrp::gpio_atr::GPIO_SRC: + _tree + ->create<std::vector<std::string>>( + mb_path / "gpio" / "FP0" / attr.second) + .set(std::vector<std::string>( + 32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) + .add_coerced_subscriber([this](const std::vector<std::string>&) { + throw uhd::runtime_error("This device does not support setting " + "the GPIO_SRC attribute."); + }); + break; + case usrp::gpio_atr::GPIO_CTRL: + case usrp::gpio_atr::GPIO_DDR: + _tree + ->create<std::vector<std::string>>( + mb_path / "gpio" / "FP0" / attr.second) + .set(std::vector<std::string>( + 32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) + .add_coerced_subscriber([this, attr]( + const std::vector<std::string> str_val) { + uint32_t val = 0; + for (size_t i = 0; i < str_val.size(); i++) { + val += usrp::gpio_atr::gpio_attr_value_pair.at(attr.second) + .at(str_val[i]) + << i; + } + _radio_perifs[0].fp_gpio->set_gpio_attr(attr.first, val); + }); + break; + case usrp::gpio_atr::GPIO_READBACK: + _tree->create<uint32_t>(mb_path / "gpio" / "FP0" / "READBACK") + .set_publisher( + std::bind(&gpio_atr_3000::read_gpio, _radio_perifs[0].fp_gpio)); + break; + default: + _tree->create<uint32_t>(mb_path / "gpio" / "FP0" / attr.second) .set(0) - .add_coerced_subscriber(std::bind(&gpio_atr_3000::set_gpio_attr, _radio_perifs[0].fp_gpio, attr.first, std::placeholders::_1)); - } + .add_coerced_subscriber(std::bind(&gpio_atr_3000::set_gpio_attr, + _radio_perifs[0].fp_gpio, + attr.first, + std::placeholders::_1)); + } } //////////////////////////////////////////////////////////////////// // dboard eeproms but not really //////////////////////////////////////////////////////////////////// dboard_eeprom_t db_eeprom; - _tree->create<dboard_eeprom_t>(mb_path / "dboards" / "A" / "rx_eeprom").set(db_eeprom); - _tree->create<dboard_eeprom_t>(mb_path / "dboards" / "A" / "tx_eeprom").set(db_eeprom); - _tree->create<dboard_eeprom_t>(mb_path / "dboards" / "A" / "gdb_eeprom").set(db_eeprom); + _tree->create<dboard_eeprom_t>(mb_path / "dboards" / "A" / "rx_eeprom") + .set(db_eeprom); + _tree->create<dboard_eeprom_t>(mb_path / "dboards" / "A" / "tx_eeprom") + .set(db_eeprom); + _tree->create<dboard_eeprom_t>(mb_path / "dboards" / "A" / "gdb_eeprom") + .set(db_eeprom); //////////////////////////////////////////////////////////////////// // do some post-init tasks //////////////////////////////////////////////////////////////////// // Init the clock rate and the auto mcr appropriately if (not device_addr.has_key("master_clock_rate")) { - UHD_LOGGER_INFO("B200") << "Setting master clock rate selection to 'automatic'." ; + UHD_LOGGER_INFO("B200") << "Setting master clock rate selection to 'automatic'."; } // We can automatically choose a master clock rate, but not if the user specifies one - const double default_tick_rate = device_addr.cast<double>("master_clock_rate", ad936x_manager::DEFAULT_TICK_RATE); + const double default_tick_rate = + device_addr.cast<double>("master_clock_rate", ad936x_manager::DEFAULT_TICK_RATE); _tree->access<double>(mb_path / "tick_rate").set(default_tick_rate); - _tree->access<bool>(mb_path / "auto_tick_rate").set(not device_addr.has_key("master_clock_rate")); + _tree->access<bool>(mb_path / "auto_tick_rate") + .set(not device_addr.has_key("master_clock_rate")); - //subdev spec contains full width of selections + // subdev spec contains full width of selections subdev_spec_t rx_spec, tx_spec; - for(const std::string &fe: _tree->list(mb_path / "dboards" / "A" / "rx_frontends")) - { + for (const std::string& fe : + _tree->list(mb_path / "dboards" / "A" / "rx_frontends")) { rx_spec.push_back(subdev_spec_pair_t("A", fe)); } - for(const std::string &fe: _tree->list(mb_path / "dboards" / "A" / "tx_frontends")) - { + for (const std::string& fe : + _tree->list(mb_path / "dboards" / "A" / "tx_frontends")) { tx_spec.push_back(subdev_spec_pair_t("A", fe)); } _tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(rx_spec); _tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(tx_spec); - //init to internal clock and time source + // init to internal clock and time source _tree->access<std::string>(mb_path / "clock_source/value").set("internal"); _tree->access<std::string>(mb_path / "time_source/value").set("internal"); // Set the DSP chains to some safe value for (size_t i = 0; i < _radio_perifs.size(); i++) { - _radio_perifs[i].ddc->set_host_rate(default_tick_rate / ad936x_manager::DEFAULT_DECIM); - _radio_perifs[i].duc->set_host_rate(default_tick_rate / ad936x_manager::DEFAULT_INTERP); + _radio_perifs[i].ddc->set_host_rate( + default_tick_rate / ad936x_manager::DEFAULT_DECIM); + _radio_perifs[i].duc->set_host_rate( + default_tick_rate / ad936x_manager::DEFAULT_INTERP); } } b200_impl::~b200_impl(void) { - UHD_SAFE_CALL - ( - _async_task.reset(); - ) + UHD_SAFE_CALL(_async_task.reset();) } /*********************************************************************** @@ -798,7 +855,7 @@ b200_impl::~b200_impl(void) **********************************************************************/ void b200_impl::setup_radio(const size_t dspno) { - radio_perifs_t &perif = _radio_perifs[dspno]; + radio_perifs_t& perif = _radio_perifs[dspno]; const fs_path mb_path = "/mboards/0"; //////////////////////////////////////////////////////////////////// @@ -810,16 +867,15 @@ void b200_impl::setup_radio(const size_t dspno) // radio control //////////////////////////////////////////////////////////////////// perif.ctrl = radio_ctrl_core_3000::make( - false/*lilE*/, - _ctrl_transport, - zero_copy_if::sptr()/*null*/, - sid); + 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 + _async_task_data->radio_ctrl[dspno] = perif.ctrl; // weak _tree->access<time_spec_t>(mb_path / "time" / "cmd") - .add_coerced_subscriber(std::bind(&radio_ctrl_core_3000::set_time, perif.ctrl, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &radio_ctrl_core_3000::set_time, perif.ctrl, std::placeholders::_1)); _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber(std::bind(&radio_ctrl_core_3000::set_tick_rate, perif.ctrl, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &radio_ctrl_core_3000::set_tick_rate, perif.ctrl, std::placeholders::_1)); this->register_loopback_self_test(perif.ctrl); //////////////////////////////////////////////////////////////////// @@ -830,19 +886,17 @@ void b200_impl::setup_radio(const size_t dspno) // create rx dsp control objects perif.framer = rx_vita_core_3000::make(perif.ctrl, TOREG(SR_RX_CTRL)); perif.ddc = rx_dsp_core_3000::make(perif.ctrl, TOREG(SR_RX_DSP), true /*is_b200?*/); - perif.ddc->set_link_rate(10e9/8); //whatever + perif.ddc->set_link_rate(10e9 / 8); // whatever perif.ddc->set_mux(usrp::fe_connection_t(dspno == 1 ? "IbQb" : "IQ")); perif.ddc->set_freq(rx_dsp_core_3000::DEFAULT_CORDIC_FREQ); perif.deframer = tx_vita_core_3000::make_no_radio_buff(perif.ctrl, TOREG(SR_TX_CTRL)); - perif.duc = tx_dsp_core_3000::make(perif.ctrl, TOREG(SR_TX_DSP)); - perif.duc->set_link_rate(10e9/8); //whatever + perif.duc = tx_dsp_core_3000::make(perif.ctrl, TOREG(SR_TX_DSP)); + perif.duc->set_link_rate(10e9 / 8); // whatever perif.duc->set_freq(tx_dsp_core_3000::DEFAULT_CORDIC_FREQ); if (_enable_user_regs) { UHD_LOG_DEBUG("B200", "Enabling user settings registers"); - perif.user_settings = user_settings_core_3000::make(perif.ctrl, - TOREG(SR_USER_SR_BASE), - TOREG(SR_USER_RB_ADDR) - ); + perif.user_settings = user_settings_core_3000::make( + perif.ctrl, TOREG(SR_USER_SR_BASE), TOREG(SR_USER_RB_ADDR)); if (!perif.user_settings) { const std::string error_msg = "Failed to create user settings bus!"; UHD_LOG_ERROR("B200", error_msg); @@ -865,21 +919,30 @@ void b200_impl::setup_radio(const size_t dspno) perif.ddc->populate_subtree(_tree->subtree(rx_dsp_path)); _tree->create<bool>(rx_dsp_path / "rate" / "set").set(false); _tree->access<double>(rx_dsp_path / "rate" / "value") - .set_coercer(std::bind(&b200_impl::coerce_rx_samp_rate, this, perif.ddc, dspno, std::placeholders::_1)) - .add_coerced_subscriber([this, rx_dsp_path](const double){ + .set_coercer(std::bind(&b200_impl::coerce_rx_samp_rate, + this, + perif.ddc, + dspno, + std::placeholders::_1)) + .add_coerced_subscriber([this, rx_dsp_path](const double) { if (this->_tree) { - this->_tree->access<bool>(rx_dsp_path / "rate" / "set") - .set(true); + this->_tree->access<bool>(rx_dsp_path / "rate" / "set").set(true); } }) - .add_coerced_subscriber(std::bind(&b200_impl::update_rx_samp_rate, this, dspno, std::placeholders::_1)) - ; + .add_coerced_subscriber(std::bind( + &b200_impl::update_rx_samp_rate, this, dspno, std::placeholders::_1)); _tree->create<stream_cmd_t>(rx_dsp_path / "stream_cmd") - .add_coerced_subscriber(std::bind(&rx_vita_core_3000::issue_stream_command, perif.framer, std::placeholders::_1)); + .add_coerced_subscriber(std::bind(&rx_vita_core_3000::issue_stream_command, + perif.framer, + std::placeholders::_1)); _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber(std::bind(&rx_vita_core_3000::set_tick_rate, perif.framer, std::placeholders::_1)) - .add_coerced_subscriber(std::bind(&b200_impl::update_rx_dsp_tick_rate, this, std::placeholders::_1, perif.ddc, rx_dsp_path)) - ; + .add_coerced_subscriber(std::bind( + &rx_vita_core_3000::set_tick_rate, perif.framer, std::placeholders::_1)) + .add_coerced_subscriber(std::bind(&b200_impl::update_rx_dsp_tick_rate, + this, + std::placeholders::_1, + perif.ddc, + rx_dsp_path)); //////////////////////////////////////////////////////////////////// // create tx dsp control objects @@ -888,54 +951,58 @@ void b200_impl::setup_radio(const size_t dspno) perif.duc->populate_subtree(_tree->subtree(tx_dsp_path)); _tree->create<bool>(tx_dsp_path / "rate" / "set").set(false); _tree->access<double>(tx_dsp_path / "rate" / "value") - .set_coercer(std::bind(&b200_impl::coerce_tx_samp_rate, this, perif.duc, dspno, std::placeholders::_1)) - .add_coerced_subscriber([this, tx_dsp_path](const double){ + .set_coercer(std::bind(&b200_impl::coerce_tx_samp_rate, + this, + perif.duc, + dspno, + std::placeholders::_1)) + .add_coerced_subscriber([this, tx_dsp_path](const double) { if (this->_tree) { - this->_tree->access<bool>(tx_dsp_path / "rate" / "set") - .set(true); + this->_tree->access<bool>(tx_dsp_path / "rate" / "set").set(true); } }) - .add_coerced_subscriber(std::bind(&b200_impl::update_tx_samp_rate, this, dspno, std::placeholders::_1)) - ; + .add_coerced_subscriber(std::bind( + &b200_impl::update_tx_samp_rate, this, dspno, std::placeholders::_1)); _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber(std::bind(&b200_impl::update_tx_dsp_tick_rate, this, std::placeholders::_1, perif.duc, tx_dsp_path)) - ; + .add_coerced_subscriber(std::bind(&b200_impl::update_tx_dsp_tick_rate, + this, + std::placeholders::_1, + perif.duc, + tx_dsp_path)); //////////////////////////////////////////////////////////////////// // create RF frontend interfacing //////////////////////////////////////////////////////////////////// for (direction_t dir : std::vector<direction_t>{RX_DIRECTION, TX_DIRECTION}) { - const std::string x = (dir == RX_DIRECTION) ? "rx" : "tx"; - const std::string key = std::string(((dir == RX_DIRECTION) ? "RX" : "TX")) + std::string(((dspno == _fe1) ? "1" : "2")); - const fs_path rf_fe_path - = mb_path / "dboards" / "A" / (x + "_frontends") / (dspno ? "B" : "A"); + const std::string x = (dir == RX_DIRECTION) ? "rx" : "tx"; + const std::string key = std::string(((dir == RX_DIRECTION) ? "RX" : "TX")) + + std::string(((dspno == _fe1) ? "1" : "2")); + const fs_path rf_fe_path = + mb_path / "dboards" / "A" / (x + "_frontends") / (dspno ? "B" : "A"); // This will connect all the AD936x-specific items - _codec_mgr->populate_frontend_subtree( - _tree->subtree(rf_fe_path), key, dir - ); + _codec_mgr->populate_frontend_subtree(_tree->subtree(rf_fe_path), key, dir); // Now connect all the b200_impl-specific items _tree->create<sensor_value_t>(rf_fe_path / "sensors" / "lo_locked") - .set_publisher(std::bind(&b200_impl::get_fe_pll_locked, this, dir == TX_DIRECTION)) - ; + .set_publisher( + std::bind(&b200_impl::get_fe_pll_locked, this, dir == TX_DIRECTION)); _tree->access<double>(rf_fe_path / "freq" / "value") - .add_coerced_subscriber(std::bind(&b200_impl::update_bandsel, this, key, std::placeholders::_1)) - ; - if (dir == RX_DIRECTION) - { + .add_coerced_subscriber( + std::bind(&b200_impl::update_bandsel, this, key, std::placeholders::_1)); + if (dir == RX_DIRECTION) { static const std::vector<std::string> ants{"TX/RX", "RX2"}; - _tree->create<std::vector<std::string> >(rf_fe_path / "antenna" / "options").set(ants); + _tree->create<std::vector<std::string>>(rf_fe_path / "antenna" / "options") + .set(ants); _tree->create<std::string>(rf_fe_path / "antenna" / "value") - .add_coerced_subscriber(std::bind(&b200_impl::update_antenna_sel, this, dspno, std::placeholders::_1)) - .set("RX2") - ; + .add_coerced_subscriber(std::bind( + &b200_impl::update_antenna_sel, this, dspno, std::placeholders::_1)) + .set("RX2"); - } - else if (dir == TX_DIRECTION) - { + } else if (dir == TX_DIRECTION) { static const std::vector<std::string> ants(1, "TX/RX"); - _tree->create<std::vector<std::string> >(rf_fe_path / "antenna" / "options").set(ants); + _tree->create<std::vector<std::string>>(rf_fe_path / "antenna" / "options") + .set(ants); _tree->create<std::string>(rf_fe_path / "antenna" / "value").set("TX/RX"); } @@ -955,75 +1022,71 @@ void b200_impl::register_loopback_self_test(wb_iface::sptr iface) bool test_fail = false; UHD_LOGGER_INFO("B200") << "Performing register loopback test... "; size_t hash = size_t(time(NULL)); - for (size_t i = 0; i < 100; i++) - { + for (size_t i = 0; i < 100; i++) { boost::hash_combine(hash, i); iface->poke32(TOREG(SR_TEST), uint32_t(hash)); test_fail = iface->peek32(RB32_TEST) != uint32_t(hash); - if (test_fail) break; //exit loop on any failure + if (test_fail) + break; // exit loop on any failure } - UHD_LOGGER_INFO("B200") << "Register loopback test " << ((test_fail)? "failed" : "passed") ; + UHD_LOGGER_INFO("B200") << "Register loopback test " + << ((test_fail) ? "failed" : "passed"); } /*********************************************************************** * Sample and tick rate comprehension below **********************************************************************/ -void b200_impl::enforce_tick_rate_limits(size_t chan_count, double tick_rate, const std::string &direction /*= ""*/) +void b200_impl::enforce_tick_rate_limits( + size_t chan_count, double tick_rate, const std::string& direction /*= ""*/) { const size_t max_chans = 2; - if (chan_count > max_chans) - { + if (chan_count > max_chans) { throw uhd::value_error(boost::str( - boost::format("cannot not setup %d %s channels (maximum is %d)") - % chan_count - % (direction.empty() ? "data" : direction) - % max_chans - )); - } - else - { - const double max_tick_rate = ad9361_device_t::AD9361_MAX_CLOCK_RATE / ((chan_count <= 1) ? 1 : 2); - if (tick_rate - max_tick_rate >= 1.0) - { + boost::format("cannot not setup %d %s channels (maximum is %d)") % chan_count + % (direction.empty() ? "data" : direction) % max_chans)); + } else { + const double max_tick_rate = + ad9361_device_t::AD9361_MAX_CLOCK_RATE / ((chan_count <= 1) ? 1 : 2); + if (tick_rate - max_tick_rate >= 1.0) { throw uhd::value_error(boost::str( - boost::format("current master clock rate (%.6f MHz) exceeds maximum possible master clock rate (%.6f MHz) when using %d %s channels") - % (tick_rate/1e6) - % (max_tick_rate/1e6) - % chan_count - % (direction.empty() ? "data" : direction) - )); + boost::format( + "current master clock rate (%.6f MHz) exceeds maximum possible " + "master clock rate (%.6f MHz) when using %d %s channels") + % (tick_rate / 1e6) % (max_tick_rate / 1e6) % chan_count + % (direction.empty() ? "data" : direction))); } - const double min_tick_rate = ad9361_device_t::AD9361_MIN_CLOCK_RATE / ((chan_count <= 1) ? 1 : 2); - if (min_tick_rate - tick_rate >= 1.0) - { + const double min_tick_rate = + ad9361_device_t::AD9361_MIN_CLOCK_RATE / ((chan_count <= 1) ? 1 : 2); + if (min_tick_rate - tick_rate >= 1.0) { throw uhd::value_error(boost::str( - boost::format("current master clock rate (%.6f MHz) is less than minimum possible master clock rate (%.6f MHz) when using %d %s channels") - % (tick_rate/1e6) - % (min_tick_rate/1e6) - % chan_count - % (direction.empty() ? "data" : direction) - )); + boost::format( + "current master clock rate (%.6f MHz) is less than minimum possible " + "master clock rate (%.6f MHz) when using %d %s channels") + % (tick_rate / 1e6) % (min_tick_rate / 1e6) % chan_count + % (direction.empty() ? "data" : direction))); } } } double b200_impl::set_tick_rate(const double new_tick_rate) { - UHD_LOGGER_INFO("B200") << (boost::format("Asking for clock rate %.6f MHz... ") % (new_tick_rate/1e6)) << std::flush; - check_tick_rate_with_current_streamers(new_tick_rate); // Defined in b200_io_impl.cpp + UHD_LOGGER_INFO("B200") << (boost::format("Asking for clock rate %.6f MHz... ") + % (new_tick_rate / 1e6)) + << std::flush; + check_tick_rate_with_current_streamers(new_tick_rate); // Defined in b200_io_impl.cpp // Make sure the clock rate is actually changed before doing // the full Monty of setting regs and loopback tests etc. if (std::abs(new_tick_rate - _tick_rate) < 1.0) { - UHD_LOGGER_INFO("B200") << "OK" ; + UHD_LOGGER_INFO("B200") << "OK"; return _tick_rate; } _tick_rate = _codec_ctrl->set_clock_rate(new_tick_rate); - UHD_LOGGER_INFO("B200") << (boost::format("Actually got clock rate %.6f MHz.") % (_tick_rate/1e6)) ; + UHD_LOGGER_INFO("B200") << (boost::format("Actually got clock rate %.6f MHz.") + % (_tick_rate / 1e6)); - for(radio_perifs_t &perif: _radio_perifs) - { + for (radio_perifs_t& perif : _radio_perifs) { perif.time64->set_tick_rate(_tick_rate); perif.time64->self_test(); } @@ -1036,76 +1099,72 @@ double b200_impl::set_tick_rate(const double new_tick_rate) void b200_impl::check_fw_compat(void) { - uint16_t compat_num = _iface->get_compat_num(); - uint32_t compat_major = (uint32_t) (compat_num >> 8); - uint32_t compat_minor = (uint32_t) (compat_num & 0xFF); - - if (compat_major != B200_FW_COMPAT_NUM_MAJOR){ - throw uhd::runtime_error(str(boost::format( - "Expected firmware compatibility number %d.%d, but got %d.%d:\n" - "The firmware build is not compatible with the host code build.\n" - "%s" - ) % int(B200_FW_COMPAT_NUM_MAJOR) % int(B200_FW_COMPAT_NUM_MINOR) - % compat_major % compat_minor % print_utility_error("uhd_images_downloader.py"))); + uint16_t compat_num = _iface->get_compat_num(); + uint32_t compat_major = (uint32_t)(compat_num >> 8); + uint32_t compat_minor = (uint32_t)(compat_num & 0xFF); + + if (compat_major != B200_FW_COMPAT_NUM_MAJOR) { + throw uhd::runtime_error(str( + boost::format( + "Expected firmware compatibility number %d.%d, but got %d.%d:\n" + "The firmware build is not compatible with the host code build.\n" + "%s") + % int(B200_FW_COMPAT_NUM_MAJOR) % int(B200_FW_COMPAT_NUM_MINOR) % compat_major + % compat_minor % print_utility_error("uhd_images_downloader.py"))); } - _tree->create<std::string>("/mboards/0/fw_version").set(str(boost::format("%u.%u") - % compat_major % compat_minor)); + _tree->create<std::string>("/mboards/0/fw_version") + .set(str(boost::format("%u.%u") % compat_major % compat_minor)); } void b200_impl::check_fpga_compat(void) { - const uint64_t compat = _local_ctrl->peek64(0); - const uint32_t signature = uint32_t(compat >> 32); + const uint64_t compat = _local_ctrl->peek64(0); + const uint32_t signature = uint32_t(compat >> 32); const uint16_t compat_major = uint16_t(compat >> 16); const uint16_t compat_minor = uint16_t(compat & 0xffff); - if (signature != 0xACE0BA5E) throw uhd::runtime_error( - "b200::check_fpga_compat signature register readback failed"); - - const uint16_t expected = ((_product == B200MINI or _product == B205MINI) ? B205_FPGA_COMPAT_NUM : B200_FPGA_COMPAT_NUM); - if (compat_major != expected) - { - throw uhd::runtime_error(str(boost::format( - "Expected FPGA compatibility number %d, but got %d:\n" - "The FPGA build is not compatible with the host code build.\n" - "%s" - ) % int(expected) % compat_major % print_utility_error("uhd_images_downloader.py"))); + if (signature != 0xACE0BA5E) + throw uhd::runtime_error( + "b200::check_fpga_compat signature register readback failed"); + + const uint16_t expected = ((_product == B200MINI or _product == B205MINI) + ? B205_FPGA_COMPAT_NUM + : B200_FPGA_COMPAT_NUM); + if (compat_major != expected) { + throw uhd::runtime_error(str( + boost::format("Expected FPGA compatibility number %d, but got %d:\n" + "The FPGA build is not compatible with the host code build.\n" + "%s") + % int(expected) % compat_major + % print_utility_error("uhd_images_downloader.py"))); } - _tree->create<std::string>("/mboards/0/fpga_version").set(str(boost::format("%u.%u") - % compat_major % compat_minor)); + _tree->create<std::string>("/mboards/0/fpga_version") + .set(str(boost::format("%u.%u") % compat_major % compat_minor)); } /*********************************************************************** * Reference time and clock **********************************************************************/ -void b200_impl::update_clock_source(const std::string &source) +void b200_impl::update_clock_source(const std::string& source) { // For B205, ref_sel selects whether or not to lock to the external clock source - if (_product == B200MINI or _product == B205MINI) - { - if (source == "external" and _time_source == EXTERNAL) - { - throw uhd::value_error("external reference cannot be both a clock source and a time source"); + if (_product == B200MINI or _product == B205MINI) { + if (source == "external" and _time_source == EXTERNAL) { + throw uhd::value_error( + "external reference cannot be both a clock source and a time source"); } - if (source == "internal") - { - if (_gpio_state.ref_sel != 0) - { + if (source == "internal") { + if (_gpio_state.ref_sel != 0) { _gpio_state.ref_sel = 0; this->update_gpio_state(); } - } - else if (source == "external") - { - if (_gpio_state.ref_sel != 1) - { + } else if (source == "external") { + if (_gpio_state.ref_sel != 1) { _gpio_state.ref_sel = 1; this->update_gpio_state(); } - } - else - { + } else { throw uhd::key_error("update_clock_source: unknown source: " + source); } return; @@ -1113,42 +1172,35 @@ void b200_impl::update_clock_source(const std::string &source) // For all other devices, ref_sel selects the external or gpsdo clock source // and the ADF4001 selects whether to lock to it or not - if (source == "internal") - { + if (source == "internal") { _adf4001_iface->set_lock_to_ext_ref(false); - } - else if (source == "external") - { - if (_gpio_state.ref_sel != 0) - { + } else if (source == "external") { + if (_gpio_state.ref_sel != 0) { _gpio_state.ref_sel = 0; this->update_gpio_state(); } _adf4001_iface->set_lock_to_ext_ref(true); - } - else if (source == "gpsdo") - { + } else if (source == "gpsdo") { if (not _gps or not _gps->gps_detected()) { - throw uhd::key_error("update_clock_source: gpsdo selected, but no gpsdo detected!"); + throw uhd::key_error( + "update_clock_source: gpsdo selected, but no gpsdo detected!"); } - if (_gpio_state.ref_sel != 1) - { + if (_gpio_state.ref_sel != 1) { _gpio_state.ref_sel = 1; this->update_gpio_state(); } _adf4001_iface->set_lock_to_ext_ref(true); - } - else - { + } else { throw uhd::key_error("update_clock_source: unknown source: " + source); } } -void b200_impl::update_time_source(const std::string &source) +void b200_impl::update_time_source(const std::string& source) { - if ((_product == B200MINI or _product == B205MINI) and source == "external" and _gpio_state.ref_sel == 1) - { - throw uhd::value_error("external reference cannot be both a time source and a clock source"); + if ((_product == B200MINI or _product == B205MINI) and source == "external" + and _gpio_state.ref_sel == 1) { + throw uhd::value_error( + "external reference cannot be both a time source and a clock source"); } // We assume source is valid for this device (if it's gone through @@ -1164,8 +1216,7 @@ void b200_impl::update_time_source(const std::string &source) value = GPSDO; else throw uhd::key_error("update_time_source: unknown source: " + source); - if (_time_source != value) - { + if (_time_source != value) { _local_ctrl->poke32(TOREG(SR_CORE_SYNC), value); _time_source = value; } @@ -1173,7 +1224,7 @@ void b200_impl::update_time_source(const std::string &source) void b200_impl::set_time(const uhd::time_spec_t& t) { - for(radio_perifs_t &perif: _radio_perifs) + for (radio_perifs_t& perif : _radio_perifs) perif.time64->set_time_sync(t); _local_ctrl->poke32(TOREG(SR_CORE_SYNC), 1 << 2 | uint32_t(_time_source)); _local_ctrl->poke32(TOREG(SR_CORE_SYNC), _time_source); @@ -1195,27 +1246,27 @@ void b200_impl::update_bandsel(const std::string& which, double freq) return; } - if(which[0] == 'R') { - if(freq < 2.2e9) { + if (which[0] == 'R') { + if (freq < 2.2e9) { _gpio_state.rx_bandsel_a = 0; _gpio_state.rx_bandsel_b = 0; _gpio_state.rx_bandsel_c = 1; - } else if((freq >= 2.2e9) && (freq < 4e9)) { + } else if ((freq >= 2.2e9) && (freq < 4e9)) { _gpio_state.rx_bandsel_a = 0; _gpio_state.rx_bandsel_b = 1; _gpio_state.rx_bandsel_c = 0; - } else if((freq >= 4e9) && (freq <= 6e9)) { + } else if ((freq >= 4e9) && (freq <= 6e9)) { _gpio_state.rx_bandsel_a = 1; _gpio_state.rx_bandsel_b = 0; _gpio_state.rx_bandsel_c = 0; } else { UHD_THROW_INVALID_CODE_PATH(); } - } else if(which[0] == 'T') { - if(freq < 2.5e9) { + } else if (which[0] == 'T') { + if (freq < 2.5e9) { _gpio_state.tx_bandsel_a = 0; _gpio_state.tx_bandsel_b = 1; - } else if((freq >= 2.5e9) && (freq <= 6e9)) { + } else if ((freq >= 2.5e9) && (freq <= 6e9)) { _gpio_state.tx_bandsel_a = 1; _gpio_state.tx_bandsel_b = 0; } else { @@ -1238,53 +1289,54 @@ void b200_impl::reset_codec() void b200_impl::update_gpio_state(void) { - const uint32_t misc_word = 0 - | (_gpio_state.swap_atr << 8) - | (_gpio_state.tx_bandsel_a << 7) - | (_gpio_state.tx_bandsel_b << 6) - | (_gpio_state.rx_bandsel_a << 5) - | (_gpio_state.rx_bandsel_b << 4) - | (_gpio_state.rx_bandsel_c << 3) - | (_gpio_state.codec_arst << 2) - | (_gpio_state.mimo << 1) - | (_gpio_state.ref_sel << 0) - ; + const uint32_t misc_word = + 0 | (_gpio_state.swap_atr << 8) | (_gpio_state.tx_bandsel_a << 7) + | (_gpio_state.tx_bandsel_b << 6) | (_gpio_state.rx_bandsel_a << 5) + | (_gpio_state.rx_bandsel_b << 4) | (_gpio_state.rx_bandsel_c << 3) + | (_gpio_state.codec_arst << 2) | (_gpio_state.mimo << 1) + | (_gpio_state.ref_sel << 0); _local_ctrl->poke32(TOREG(SR_CORE_MISC), misc_word); } void b200_impl::update_atrs(void) { - if (_radio_perifs.size() > _fe1 and _radio_perifs[_fe1].atr) - { - radio_perifs_t &perif = _radio_perifs[_fe1]; - const bool enb_rx = bool(perif.rx_streamer.lock()); - const bool enb_tx = bool(perif.tx_streamer.lock()); - const bool is_rx2 = perif.ant_rx2; - const uint32_t rxonly = (enb_rx)? ((is_rx2)? STATE_RX1_RX2 : STATE_RX1_TXRX) : STATE_OFF; - const uint32_t txonly = (enb_tx)? (STATE_TX1_TXRX) : STATE_OFF; - uint32_t fd = STATE_OFF; - if (enb_rx and enb_tx) fd = STATE_FDX1_TXRX; - if (enb_rx and not enb_tx) fd = rxonly; - if (not enb_rx and enb_tx) fd = txonly; + if (_radio_perifs.size() > _fe1 and _radio_perifs[_fe1].atr) { + radio_perifs_t& perif = _radio_perifs[_fe1]; + const bool enb_rx = bool(perif.rx_streamer.lock()); + const bool enb_tx = bool(perif.tx_streamer.lock()); + const bool is_rx2 = perif.ant_rx2; + const uint32_t rxonly = (enb_rx) ? ((is_rx2) ? STATE_RX1_RX2 : STATE_RX1_TXRX) + : STATE_OFF; + const uint32_t txonly = (enb_tx) ? (STATE_TX1_TXRX) : STATE_OFF; + uint32_t fd = STATE_OFF; + if (enb_rx and enb_tx) + fd = STATE_FDX1_TXRX; + if (enb_rx and not enb_tx) + fd = rxonly; + if (not enb_rx and enb_tx) + fd = txonly; gpio_atr_3000::sptr atr = perif.atr; atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF); atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly); atr->set_atr_reg(ATR_REG_TX_ONLY, txonly); atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd); } - if (_radio_perifs.size() > _fe2 and _radio_perifs[_fe2].atr) - { - radio_perifs_t &perif = _radio_perifs[_fe2]; - const bool enb_rx = bool(perif.rx_streamer.lock()); - const bool enb_tx = bool(perif.tx_streamer.lock()); - const bool is_rx2 = perif.ant_rx2; - const uint32_t rxonly = (enb_rx)? ((is_rx2)? STATE_RX2_RX2 : STATE_RX2_TXRX) : STATE_OFF; - const uint32_t txonly = (enb_tx)? (STATE_TX2_TXRX) : STATE_OFF; - uint32_t fd = STATE_OFF; - if (enb_rx and enb_tx) fd = STATE_FDX2_TXRX; - if (enb_rx and not enb_tx) fd = rxonly; - if (not enb_rx and enb_tx) fd = txonly; + if (_radio_perifs.size() > _fe2 and _radio_perifs[_fe2].atr) { + radio_perifs_t& perif = _radio_perifs[_fe2]; + const bool enb_rx = bool(perif.rx_streamer.lock()); + const bool enb_tx = bool(perif.tx_streamer.lock()); + const bool is_rx2 = perif.ant_rx2; + const uint32_t rxonly = (enb_rx) ? ((is_rx2) ? STATE_RX2_RX2 : STATE_RX2_TXRX) + : STATE_OFF; + const uint32_t txonly = (enb_tx) ? (STATE_TX2_TXRX) : STATE_OFF; + uint32_t fd = STATE_OFF; + if (enb_rx and enb_tx) + fd = STATE_FDX2_TXRX; + if (enb_rx and not enb_tx) + fd = rxonly; + if (not enb_rx and enb_tx) + fd = txonly; gpio_atr_3000::sptr atr = perif.atr; atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF); atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly); @@ -1293,38 +1345,44 @@ void b200_impl::update_atrs(void) } } -void b200_impl::update_antenna_sel(const size_t which, const std::string &ant) +void b200_impl::update_antenna_sel(const size_t which, const std::string& ant) { - if (ant != "TX/RX" and ant != "RX2") throw uhd::value_error("b200: unknown RX antenna option: " + ant); + if (ant != "TX/RX" and ant != "RX2") + throw uhd::value_error("b200: unknown RX antenna option: " + ant); _radio_perifs[which].ant_rx2 = (ant == "RX2"); this->update_atrs(); } void b200_impl::update_enables(void) { - //extract settings from state variables - const bool enb_tx1 = (_radio_perifs.size() > _fe1) and bool(_radio_perifs[_fe1].tx_streamer.lock()); - const bool enb_rx1 = (_radio_perifs.size() > _fe1) and bool(_radio_perifs[_fe1].rx_streamer.lock()); - const bool enb_tx2 = (_radio_perifs.size() > _fe2) and bool(_radio_perifs[_fe2].tx_streamer.lock()); - const bool enb_rx2 = (_radio_perifs.size() > _fe2) and bool(_radio_perifs[_fe2].rx_streamer.lock()); - const size_t num_rx = (enb_rx1?1:0) + (enb_rx2?1:0); - const size_t num_tx = (enb_tx1?1:0) + (enb_tx2?1:0); - const bool mimo = num_rx == 2 or num_tx == 2; - - if ((num_rx + num_tx) == 3) - { - throw uhd::runtime_error("b200: 2 RX 1 TX and 1 RX 2 TX configurations not possible"); + // extract settings from state variables + const bool enb_tx1 = (_radio_perifs.size() > _fe1) + and bool(_radio_perifs[_fe1].tx_streamer.lock()); + const bool enb_rx1 = (_radio_perifs.size() > _fe1) + and bool(_radio_perifs[_fe1].rx_streamer.lock()); + const bool enb_tx2 = (_radio_perifs.size() > _fe2) + and bool(_radio_perifs[_fe2].tx_streamer.lock()); + const bool enb_rx2 = (_radio_perifs.size() > _fe2) + and bool(_radio_perifs[_fe2].rx_streamer.lock()); + const size_t num_rx = (enb_rx1 ? 1 : 0) + (enb_rx2 ? 1 : 0); + const size_t num_tx = (enb_tx1 ? 1 : 0) + (enb_tx2 ? 1 : 0); + const bool mimo = num_rx == 2 or num_tx == 2; + + if ((num_rx + num_tx) == 3) { + throw uhd::runtime_error( + "b200: 2 RX 1 TX and 1 RX 2 TX configurations not possible"); } - //setup the active chains in the codec + // setup the active chains in the codec _codec_ctrl->set_active_chains(enb_tx1, enb_tx2, enb_rx1, enb_rx2); - if ((num_rx + num_tx) == 0) _codec_ctrl->set_active_chains(true, false, true, false); //enable something + if ((num_rx + num_tx) == 0) + _codec_ctrl->set_active_chains(true, false, true, false); // enable something - //figure out if mimo is enabled based on new state - _gpio_state.mimo = (mimo)? 1 : 0; + // figure out if mimo is enabled based on new state + _gpio_state.mimo = (mimo) ? 1 : 0; update_gpio_state(); - //atrs change based on enables + // atrs change based on enables this->update_atrs(); } diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp index bd44aa14f..d151bc59d 100644 --- a/host/lib/usrp/b200/b200_impl.hpp +++ b/host/lib/usrp/b200/b200_impl.hpp @@ -8,47 +8,47 @@ #ifndef INCLUDED_B200_IMPL_HPP #define INCLUDED_B200_IMPL_HPP +#include "b200_cores.hpp" #include "b200_iface.hpp" #include "b200_uart.hpp" -#include "b200_cores.hpp" #include <uhd/device.hpp> #include <uhd/property_tree.hpp> -#include <uhd/utils/pimpl.hpp> -#include <uhd/utils/tasks.hpp> +#include <uhd/transport/bounded_buffer.hpp> +#include <uhd/transport/usb_zero_copy.hpp> #include <uhd/types/dict.hpp> #include <uhd/types/sensors.hpp> #include <uhd/types/stream_cmd.hpp> +#include <uhd/usrp/gps_ctrl.hpp> #include <uhd/usrp/mboard_eeprom.hpp> #include <uhd/usrp/subdev_spec.hpp> -#include <uhd/usrp/gps_ctrl.hpp> -#include <uhd/transport/usb_zero_copy.hpp> -#include <uhd/transport/bounded_buffer.hpp> +#include <uhd/utils/pimpl.hpp> +#include <uhd/utils/tasks.hpp> #include <uhdlib/usrp/common/ad9361_ctrl.hpp> -#include <uhdlib/usrp/cores/rx_vita_core_3000.hpp> -#include <uhdlib/usrp/cores/tx_vita_core_3000.hpp> -#include <uhdlib/usrp/cores/time_core_3000.hpp> +#include <uhdlib/usrp/common/ad936x_manager.hpp> +#include <uhdlib/usrp/common/adf4001_ctrl.hpp> +#include <uhdlib/usrp/common/recv_packet_demuxer_3000.hpp> #include <uhdlib/usrp/cores/gpio_atr_3000.hpp> #include <uhdlib/usrp/cores/radio_ctrl_core_3000.hpp> #include <uhdlib/usrp/cores/rx_dsp_core_3000.hpp> +#include <uhdlib/usrp/cores/rx_vita_core_3000.hpp> +#include <uhdlib/usrp/cores/time_core_3000.hpp> #include <uhdlib/usrp/cores/tx_dsp_core_3000.hpp> +#include <uhdlib/usrp/cores/tx_vita_core_3000.hpp> #include <uhdlib/usrp/cores/user_settings_core_3000.hpp> -#include <uhdlib/usrp/common/recv_packet_demuxer_3000.hpp> -#include <uhdlib/usrp/common/ad936x_manager.hpp> -#include <uhdlib/usrp/common/adf4001_ctrl.hpp> #include <boost/assign.hpp> -#include <mutex> #include <memory> +#include <mutex> -static const uint8_t B200_FW_COMPAT_NUM_MAJOR = 8; -static const uint8_t B200_FW_COMPAT_NUM_MINOR = 0; -static const uint16_t B200_FPGA_COMPAT_NUM = 16; -static const uint16_t B205_FPGA_COMPAT_NUM = 7; -static const double B200_BUS_CLOCK_RATE = 100e6; -static const uint32_t B200_GPSDO_ST_NONE = 0x83; -static constexpr double B200_MAX_RATE_USB2 = 53248000; // bytes/s -static constexpr double B200_MAX_RATE_USB3 = 500000000; // bytes/s +static const uint8_t B200_FW_COMPAT_NUM_MAJOR = 8; +static const uint8_t B200_FW_COMPAT_NUM_MINOR = 0; +static const uint16_t B200_FPGA_COMPAT_NUM = 16; +static const uint16_t B205_FPGA_COMPAT_NUM = 7; +static const double B200_BUS_CLOCK_RATE = 100e6; +static const uint32_t B200_GPSDO_ST_NONE = 0x83; +static constexpr double B200_MAX_RATE_USB2 = 53248000; // bytes/s +static constexpr double B200_MAX_RATE_USB3 = 500000000; // bytes/s -#define FLIP_SID(sid) (((sid)<<16)|((sid)>>16)) +#define FLIP_SID(sid) (((sid) << 16) | ((sid) >> 16)) static const uint32_t B200_CTRL0_MSG_SID = 0x00000010; static const uint32_t B200_RESP0_MSG_SID = FLIP_SID(B200_CTRL0_MSG_SID); @@ -57,10 +57,10 @@ static const uint32_t B200_CTRL1_MSG_SID = 0x00000020; static const uint32_t B200_RESP1_MSG_SID = FLIP_SID(B200_CTRL1_MSG_SID); static const uint32_t B200_TX_DATA0_SID = 0x00000050; -static const uint32_t B200_TX_MSG0_SID = FLIP_SID(B200_TX_DATA0_SID); +static const uint32_t B200_TX_MSG0_SID = FLIP_SID(B200_TX_DATA0_SID); static const uint32_t B200_TX_DATA1_SID = 0x00000060; -static const uint32_t B200_TX_MSG1_SID = FLIP_SID(B200_TX_DATA1_SID); +static const uint32_t B200_TX_MSG1_SID = FLIP_SID(B200_TX_DATA1_SID); static const uint32_t B200_RX_DATA0_SID = 0x000000A0; static const uint32_t B200_RX_DATA1_SID = 0x000000B0; @@ -91,48 +91,55 @@ static const int B200_USB_DATA_MAX_RECV_FRAME_SIZE = 16360; * VID/PID pairs for all B2xx products */ static std::vector<uhd::transport::usb_device_handle::vid_pid_pair_t> b200_vid_pid_pairs = - boost::assign::list_of - (uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B200_PRODUCT_ID)) - (uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B200MINI_PRODUCT_ID)) - (uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B205MINI_PRODUCT_ID)) - (uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B200_PRODUCT_NI_ID)) - (uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B210_PRODUCT_NI_ID)) - ; - -b200_product_t get_b200_product(const uhd::transport::usb_device_handle::sptr& handle, const uhd::usrp::mboard_eeprom_t &mb_eeprom); -std::vector<uhd::transport::usb_device_handle::sptr> get_b200_device_handles(const uhd::device_addr_t &hint); + boost::assign::list_of(uhd::transport::usb_device_handle::vid_pid_pair_t( + B200_VENDOR_ID, B200_PRODUCT_ID))( + uhd::transport::usb_device_handle::vid_pid_pair_t( + B200_VENDOR_ID, B200MINI_PRODUCT_ID))( + uhd::transport::usb_device_handle::vid_pid_pair_t( + B200_VENDOR_ID, B205MINI_PRODUCT_ID))( + uhd::transport::usb_device_handle::vid_pid_pair_t( + B200_VENDOR_NI_ID, B200_PRODUCT_NI_ID))( + uhd::transport::usb_device_handle::vid_pid_pair_t( + B200_VENDOR_NI_ID, B210_PRODUCT_NI_ID)); + +b200_product_t get_b200_product(const uhd::transport::usb_device_handle::sptr& handle, + const uhd::usrp::mboard_eeprom_t& mb_eeprom); +std::vector<uhd::transport::usb_device_handle::sptr> get_b200_device_handles( + const uhd::device_addr_t& hint); //! Implementation guts class b200_impl : public uhd::device { public: - //structors - b200_impl(const uhd::device_addr_t &, uhd::transport::usb_device_handle::sptr &handle); + // structors + b200_impl(const uhd::device_addr_t&, uhd::transport::usb_device_handle::sptr& handle); ~b200_impl(void); - //the io interface - uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t &args); - uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t &args); - bool recv_async_msg(uhd::async_metadata_t &, double); + // the io interface + uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t& args); + uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t& args); + bool recv_async_msg(uhd::async_metadata_t&, double); //! Check that the combination of stream args and tick rate are valid. // // Basically figures out the arguments for enforce_tick_rate_limits() // and calls said method. If arguments are invalid, throws a // uhd::value_error. - void check_streamer_args(const uhd::stream_args_t &args, double tick_rate, const std::string &direction = ""); + void check_streamer_args(const uhd::stream_args_t& args, + double tick_rate, + const std::string& direction = ""); static uhd::usrp::mboard_eeprom_t get_mb_eeprom(uhd::i2c_iface::sptr); private: - b200_product_t _product; - size_t _revision; - bool _gpsdo_capable; + b200_product_t _product; + size_t _revision; + bool _gpsdo_capable; //! This flag is true if the FPGA has custom (user) registers and access to // those needs to be enabled from software. - const bool _enable_user_regs; + const bool _enable_user_regs; - //controllers + // controllers b200_iface::sptr _iface; radio_ctrl_core_3000::sptr _local_ctrl; uhd::usrp::ad9361_ctrl::sptr _codec_ctrl; @@ -141,7 +148,7 @@ private: std::shared_ptr<uhd::usrp::adf4001_ctrl> _adf4001_iface; uhd::gps_ctrl::sptr _gps; - //transports + // transports uhd::transport::zero_copy_if::sptr _data_transport; uhd::transport::zero_copy_if::sptr _ctrl_transport; uhd::usrp::recv_packet_demuxer_3000::sptr _demux; @@ -151,7 +158,7 @@ private: std::mutex _transport_setup_mutex; - //async ctrl + msgs + // async ctrl + msgs uhd::msg_task::sptr _async_task; typedef uhd::transport::bounded_buffer<uhd::async_metadata_t> async_md_type; struct AsyncTaskData @@ -162,25 +169,26 @@ private: b200_uart::sptr gpsdo_uart; }; std::shared_ptr<AsyncTaskData> _async_task_data; - boost::optional<uhd::msg_task::msg_type_t> handle_async_task(uhd::transport::zero_copy_if::sptr, std::shared_ptr<AsyncTaskData>); + boost::optional<uhd::msg_task::msg_type_t> handle_async_task( + uhd::transport::zero_copy_if::sptr, std::shared_ptr<AsyncTaskData>); void register_loopback_self_test(uhd::wb_iface::sptr iface); - void set_mb_eeprom(const uhd::usrp::mboard_eeprom_t &); + void set_mb_eeprom(const uhd::usrp::mboard_eeprom_t&); void check_fw_compat(void); void check_fpga_compat(void); - uhd::usrp::subdev_spec_t coerce_subdev_spec(const uhd::usrp::subdev_spec_t &); - void update_subdev_spec(const std::string &tx_rx, const uhd::usrp::subdev_spec_t &); - void update_time_source(const std::string &); + uhd::usrp::subdev_spec_t coerce_subdev_spec(const uhd::usrp::subdev_spec_t&); + void update_subdev_spec(const std::string& tx_rx, const uhd::usrp::subdev_spec_t&); + void update_time_source(const std::string&); void set_time(const uhd::time_spec_t&); void sync_times(void); - void update_clock_source(const std::string &); + void update_clock_source(const std::string&); void update_bandsel(const std::string& which, double freq); void reset_codec(void); - void update_antenna_sel(const size_t which, const std::string &ant); + void update_antenna_sel(const size_t which, const std::string& ant); uhd::sensor_value_t get_ref_locked(void); uhd::sensor_value_t get_fe_pll_locked(const bool is_tx); - //perifs in the radio core + // perifs in the radio core struct radio_perifs_t { radio_ctrl_core_3000::sptr ctrl; @@ -198,10 +206,10 @@ private: }; std::vector<radio_perifs_t> _radio_perifs; - //mapping of AD936x frontends (FE1 and FE2) to radio perif index (0 and 1) - //FE1 corresponds to the ports labeled "RF B" on the B200/B210 - //FE2 corresponds to the ports labeled "RF A" on the B200/B210 - //the mapping is product and revision specific + // mapping of AD936x frontends (FE1 and FE2) to radio perif index (0 and 1) + // FE1 corresponds to the ports labeled "RF B" on the B200/B210 + // FE2 corresponds to the ports labeled "RF A" on the B200/B210 + // the mapping is product and revision specific size_t _fe1; size_t _fe2; @@ -211,23 +219,32 @@ private: void setup_radio(const size_t radio_index); void handle_overflow(const size_t radio_index); - struct gpio_state { - uint32_t tx_bandsel_a, tx_bandsel_b, rx_bandsel_a, rx_bandsel_b, rx_bandsel_c, codec_arst, mimo, ref_sel, swap_atr; + struct gpio_state + { + uint32_t tx_bandsel_a, tx_bandsel_b, rx_bandsel_a, rx_bandsel_b, rx_bandsel_c, + codec_arst, mimo, ref_sel, swap_atr; - gpio_state() { + gpio_state() + { tx_bandsel_a = 0; tx_bandsel_b = 0; rx_bandsel_a = 0; rx_bandsel_b = 0; rx_bandsel_c = 0; - codec_arst = 0; - mimo = 0; - ref_sel = 0; - swap_atr = 0; + codec_arst = 0; + mimo = 0; + ref_sel = 0; + swap_atr = 0; } } _gpio_state; - enum time_source_t {GPSDO=0,EXTERNAL=1,INTERNAL=2,NONE=3,UNKNOWN=4} _time_source; + enum time_source_t { + GPSDO = 0, + EXTERNAL = 1, + INTERNAL = 2, + NONE = 3, + UNKNOWN = 4 + } _time_source; void update_gpio_state(void); @@ -235,10 +252,14 @@ private: void update_atrs(void); double _tick_rate; - double get_tick_rate(void){return _tick_rate;} + double get_tick_rate(void) + { + return _tick_rate; + } double set_tick_rate(const double rate); - /*! \brief Choose a tick rate (master clock rate) that works well for the given sampling rate. + /*! \brief Choose a tick rate (master clock rate) that works well for the given + * sampling rate. * * This function will try and choose a master clock rate automatically. * See the function definition for details on the algorithm. @@ -257,30 +278,32 @@ private: * will be ignored. * \param num_chans If given, specifies the number of channels. */ - void set_auto_tick_rate( - const double rate=0, - const uhd::fs_path &tree_dsp_path="", - size_t num_chans=0 - ); + void set_auto_tick_rate(const double rate = 0, + const uhd::fs_path& tree_dsp_path = "", + size_t num_chans = 0); void update_tick_rate(const double); /*! Subscriber to the tick_rate property, updates DDCs after tick rate change. */ - void update_rx_dsp_tick_rate(const double, rx_dsp_core_3000::sptr, uhd::fs_path rx_dsp_path); + void update_rx_dsp_tick_rate( + const double, rx_dsp_core_3000::sptr, uhd::fs_path rx_dsp_path); /*! Subscriber to the tick_rate property, updates DUCs after tick rate change. */ - void update_tx_dsp_tick_rate(const double, tx_dsp_core_3000::sptr, uhd::fs_path tx_dsp_path); + void update_tx_dsp_tick_rate( + const double, tx_dsp_core_3000::sptr, uhd::fs_path tx_dsp_path); /*! Check if \p tick_rate works with \p chan_count channels. * * Throws a uhd::value_error if not. */ - void enforce_tick_rate_limits(size_t chan_count, double tick_rate, const std::string &direction = ""); + void enforce_tick_rate_limits( + size_t chan_count, double tick_rate, const std::string& direction = ""); void check_tick_rate_with_current_streamers(double rate); - /*! Return the max number of channels on active rx_streamer or tx_streamer objects associated with this device. + /*! Return the max number of channels on active rx_streamer or tx_streamer objects + * associated with this device. * * \param direction Set to "TX" to only check tx_streamers, "RX" to only check * rx_streamers. Any other value will check if \e any active @@ -288,7 +311,7 @@ private: * \return Return the number of tx streamers (direction=="TX"), the number of rx * streamers (direction=="RX") or the total number of streamers. */ - size_t max_chan_count(const std::string &direction=""); + size_t max_chan_count(const std::string& direction = ""); //! Coercer, attached to the "rate/value" property on the rx dsps. double coerce_rx_samp_rate(rx_dsp_core_3000::sptr, size_t, const double); diff --git a/host/lib/usrp/b200/b200_io_impl.cpp b/host/lib/usrp/b200/b200_io_impl.cpp index 6eb3631ab..57a1b18c7 100644 --- a/host/lib/usrp/b200/b200_io_impl.cpp +++ b/host/lib/usrp/b200/b200_io_impl.cpp @@ -458,12 +458,17 @@ rx_streamer::sptr b200_impl::get_rx_stream(const uhd::stream_args_t& args_) perif.ddc->setup(args); _demux->realloc_sid(sid); my_streamer->set_xport_chan_get_buff(stream_i, - std::bind(&recv_packet_demuxer_3000::get_recv_buff, _demux, sid, std::placeholders::_1), + std::bind(&recv_packet_demuxer_3000::get_recv_buff, + _demux, + sid, + std::placeholders::_1), true /*flush*/); my_streamer->set_overflow_handler( stream_i, std::bind(&b200_impl::handle_overflow, this, radio_index)); my_streamer->set_issue_stream_cmd(stream_i, - std::bind(&rx_vita_core_3000::issue_stream_command, perif.framer, std::placeholders::_1)); + std::bind(&rx_vita_core_3000::issue_stream_command, + perif.framer, + std::placeholders::_1)); perif.rx_streamer = my_streamer; // store weak pointer // sets all tick and samp rates on this streamer @@ -574,10 +579,13 @@ tx_streamer::sptr b200_impl::get_tx_stream(const uhd::stream_args_t& args_) perif.deframer->setup(args); perif.duc->setup(args); - my_streamer->set_xport_chan_get_buff( - stream_i, std::bind(&zero_copy_if::get_send_buff, _data_transport, std::placeholders::_1)); - my_streamer->set_async_receiver(std::bind( - &async_md_type::pop_with_timed_wait, _async_task_data->async_md, std::placeholders::_1, std::placeholders::_2)); + my_streamer->set_xport_chan_get_buff(stream_i, + std::bind( + &zero_copy_if::get_send_buff, _data_transport, std::placeholders::_1)); + my_streamer->set_async_receiver(std::bind(&async_md_type::pop_with_timed_wait, + _async_task_data->async_md, + std::placeholders::_1, + std::placeholders::_2)); my_streamer->set_xport_chan_sid( stream_i, true, radio_index ? B200_TX_DATA1_SID : B200_TX_DATA0_SID); my_streamer->set_enable_trailer(false); // TODO not implemented trailer support diff --git a/host/lib/usrp/b200/b200_mb_eeprom.cpp b/host/lib/usrp/b200/b200_mb_eeprom.cpp index 5a37cc9c1..a83dce189 100644 --- a/host/lib/usrp/b200/b200_mb_eeprom.cpp +++ b/host/lib/usrp/b200/b200_mb_eeprom.cpp @@ -7,7 +7,6 @@ #include "b200_impl.hpp" #include <uhd/usrp/mboard_eeprom.hpp> #include <uhdlib/utils/eeprom_utils.hpp> - #include <unordered_map> using namespace uhd; @@ -27,7 +26,7 @@ struct eeprom_field_t // firmware and bootloader code. // EEPROM map information is duplicated in b2xx_fx3_utils.cpp -constexpr uint16_t SIGNATURE_ADDR = 0x0000; +constexpr uint16_t SIGNATURE_ADDR = 0x0000; constexpr size_t SIGNATURE_LENGTH = 4; constexpr auto EXPECTED_MAGIC = "45568"; // 0xB200 @@ -38,15 +37,15 @@ constexpr uint16_t REV1_BASE_ADDR = 0x7F00; constexpr size_t REV1_LENGTH = 46; const std::unordered_map<std::string, eeprom_field_t> B200_REV1_MAP = { - {"magic", {0, 2}}, - {"eeprom_revision", {2, 2}}, - {"eeprom_compat", {4, 2}}, - {"vendor_id", {6, 2}}, - {"product_id", {8, 2}}, - {"revision", {10, 2}}, - {"product", {12, 2}}, - {"name", {14, NAME_MAX_LEN}}, - {"serial", {14 + NAME_MAX_LEN, SERIAL_LEN}}, + {"magic", {0, 2}}, + {"eeprom_revision", {2, 2}}, + {"eeprom_compat", {4, 2}}, + {"vendor_id", {6, 2}}, + {"product_id", {8, 2}}, + {"revision", {10, 2}}, + {"product", {12, 2}}, + {"name", {14, NAME_MAX_LEN}}, + {"serial", {14 + NAME_MAX_LEN, SERIAL_LEN}}, // pad of 210 bytes }; @@ -56,10 +55,10 @@ constexpr size_t REV0_LENGTH = 36; const std::unordered_map<std::string, eeprom_field_t> B200_REV0_MAP = { // front pad of 220 bytes - {"revision", {0, 2}}, - {"product", {2, 2}}, - {"name", {4, NAME_MAX_LEN}}, - {"serial", {4 + NAME_MAX_LEN, SERIAL_LEN}}, + {"revision", {0, 2}}, + {"product", {2, 2}}, + {"name", {4, NAME_MAX_LEN}}, + {"serial", {4 + NAME_MAX_LEN, SERIAL_LEN}}, }; constexpr int UNKNOWN_REV = -1; @@ -82,8 +81,7 @@ int _get_rev(uhd::i2c_iface::sptr iface) byte_vector_t _get_eeprom(uhd::i2c_iface::sptr iface) { const auto rev = _get_rev(iface); - if (rev == UNKNOWN_REV) - { + if (rev == UNKNOWN_REV) { return byte_vector_t(); } @@ -93,7 +91,7 @@ byte_vector_t _get_eeprom(uhd::i2c_iface::sptr iface) return iface->read_eeprom(addr >> 8, addr & 0xFF, length); } -} +} // namespace mboard_eeprom_t b200_impl::get_mb_eeprom(uhd::i2c_iface::sptr iface) { @@ -106,8 +104,7 @@ mboard_eeprom_t b200_impl::get_mb_eeprom(uhd::i2c_iface::sptr iface) auto eeprom_map = (rev == 0) ? B200_REV0_MAP : B200_REV1_MAP; - for (const auto &element : eeprom_map) - { + for (const auto& element : eeprom_map) { // There is an assumption here that fields of length 2 are uint16's and // lengths other than 2 are strings. Update this code if that // assumption changes. @@ -115,23 +112,22 @@ mboard_eeprom_t b200_impl::get_mb_eeprom(uhd::i2c_iface::sptr iface) bytes.begin() + element.second.offset + element.second.length); mb_eeprom[element.first] = (element.second.length == 2) - ? uint16_bytes_to_string(element_bytes) - : bytes_to_string(element_bytes); + ? uint16_bytes_to_string(element_bytes) + : bytes_to_string(element_bytes); } if (rev > 0) { - if (mb_eeprom["magic"] != EXPECTED_MAGIC) - { + if (mb_eeprom["magic"] != EXPECTED_MAGIC) { throw uhd::runtime_error( str(boost::format("EEPROM magic value mismatch. Device returns %s, but " "should have been %s.") - % mb_eeprom["magic"] % EXPECTED_MAGIC)); + % mb_eeprom["magic"] % EXPECTED_MAGIC)); } if (mb_eeprom["eeprom_compat"] != EXPECTED_COMPAT) { throw uhd::runtime_error( str(boost::format("EEPROM compat value mismatch. Device returns %s, but " "should have been %s.") - % mb_eeprom["eeprom_compat"] % EXPECTED_COMPAT)); + % mb_eeprom["eeprom_compat"] % EXPECTED_COMPAT)); } } @@ -140,13 +136,11 @@ mboard_eeprom_t b200_impl::get_mb_eeprom(uhd::i2c_iface::sptr iface) void b200_impl::set_mb_eeprom(const mboard_eeprom_t& mb_eeprom) { - const auto rev = _get_rev(_iface); + const auto rev = _get_rev(_iface); auto eeprom_map = (rev == 0) ? B200_REV0_MAP : B200_REV1_MAP; auto base_addr = (rev == 0) ? REV0_BASE_ADDR : REV1_BASE_ADDR; - for (const auto& key : mb_eeprom.keys()) - { - if (eeprom_map.find(key) == eeprom_map.end()) - { + for (const auto& key : mb_eeprom.keys()) { + if (eeprom_map.find(key) == eeprom_map.end()) { UHD_LOG_WARNING( LOG_ID, "Unknown key in mb_eeprom during set_mb_eeprom: " << key); continue; diff --git a/host/lib/usrp/b200/b200_regs.hpp b/host/lib/usrp/b200/b200_regs.hpp index cedbe0ff5..4554eb52c 100644 --- a/host/lib/usrp/b200/b200_regs.hpp +++ b/host/lib/usrp/b200/b200_regs.hpp @@ -14,60 +14,60 @@ #define localparam static const int -localparam SR_CORE_SPI = 8; -localparam SR_CORE_MISC = 16; -localparam SR_CORE_COMPAT = 24; -localparam SR_CORE_GPSDO_ST = 40; -localparam SR_CORE_SYNC = 48; -localparam RB32_CORE_SPI = 8; -localparam RB32_CORE_MISC = 16; -localparam RB32_CORE_STATUS = 20; -localparam RB32_CORE_PLL = 24; - -localparam SR_SPI = 8; -localparam SR_ATR = 12; -localparam SR_TEST = 21; -localparam SR_CODEC_IDLE = 22; -localparam SR_READBACK = 32; -localparam SR_TX_CTRL = 64; -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 SR_FP_GPIO = 200; +localparam SR_CORE_SPI = 8; +localparam SR_CORE_MISC = 16; +localparam SR_CORE_COMPAT = 24; +localparam SR_CORE_GPSDO_ST = 40; +localparam SR_CORE_SYNC = 48; +localparam RB32_CORE_SPI = 8; +localparam RB32_CORE_MISC = 16; +localparam RB32_CORE_STATUS = 20; +localparam RB32_CORE_PLL = 24; + +localparam SR_SPI = 8; +localparam SR_ATR = 12; +localparam SR_TEST = 21; +localparam SR_CODEC_IDLE = 22; +localparam SR_READBACK = 32; +localparam SR_TX_CTRL = 64; +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 SR_FP_GPIO = 200; localparam SR_USER_SR_BASE = 253; localparam SR_USER_RB_ADDR = 255; -localparam RB32_TEST = 0; -localparam RB64_TIME_NOW = 8; -localparam RB64_TIME_PPS = 16; -localparam RB64_CODEC_READBACK = 24; -localparam RB32_FP_GPIO = 32; +localparam RB32_TEST = 0; +localparam RB64_TIME_NOW = 8; +localparam RB64_TIME_PPS = 16; +localparam RB64_CODEC_READBACK = 24; +localparam RB32_FP_GPIO = 32; -//pll constants -static const int AD9361_SLAVENO = (1 << 0); -static const int ADF4001_SLAVENO = (1 << 1); -static const double AD9361_SPI_RATE = 1e6; -static const double ADF4001_SPI_RATE = 10e3; //slow for large time constant on spi lines +// pll constants +static const int AD9361_SLAVENO = (1 << 0); +static const int ADF4001_SLAVENO = (1 << 1); +static const double AD9361_SPI_RATE = 1e6; +static const double ADF4001_SPI_RATE = 10e3; // slow for large time constant on spi lines /* ATR Control Bits */ -static const uint32_t TX_ENABLE1 = (1 << 7); -static const uint32_t SFDX1_RX = (1 << 6); -static const uint32_t SFDX1_TX = (1 << 5); -static const uint32_t SRX1_RX = (1 << 4); -static const uint32_t SRX1_TX = (1 << 3); -static const uint32_t LED_RX1 = (1 << 2); +static const uint32_t TX_ENABLE1 = (1 << 7); +static const uint32_t SFDX1_RX = (1 << 6); +static const uint32_t SFDX1_TX = (1 << 5); +static const uint32_t SRX1_RX = (1 << 4); +static const uint32_t SRX1_TX = (1 << 3); +static const uint32_t LED_RX1 = (1 << 2); static const uint32_t LED_TXRX_RX1 = (1 << 1); static const uint32_t LED_TXRX_TX1 = (1 << 0); -static const uint32_t TX_ENABLE2 = (1 << 7); -static const uint32_t SFDX2_RX = (1 << 6); -static const uint32_t SFDX2_TX = (1 << 5); -static const uint32_t SRX2_RX = (1 << 4); -static const uint32_t SRX2_TX = (1 << 3); -static const uint32_t LED_RX2 = (1 << 2); +static const uint32_t TX_ENABLE2 = (1 << 7); +static const uint32_t SFDX2_RX = (1 << 6); +static const uint32_t SFDX2_TX = (1 << 5); +static const uint32_t SRX2_RX = (1 << 4); +static const uint32_t SRX2_TX = (1 << 3); +static const uint32_t LED_RX2 = (1 << 2); static const uint32_t LED_TXRX_RX2 = (1 << 1); static const uint32_t LED_TXRX_TX2 = (1 << 0); @@ -76,44 +76,24 @@ static const uint32_t LED_TXRX_TX2 = (1 << 0); static const uint32_t STATE_OFF = 0x00; ///////////////////////// side 1 /////////////////////////////////// -static const uint32_t STATE_RX1_RX2 = (SFDX1_RX - | SFDX1_TX - | LED_RX1); +static const uint32_t STATE_RX1_RX2 = (SFDX1_RX | SFDX1_TX | LED_RX1); -static const uint32_t STATE_RX1_TXRX = (SRX1_RX - | SRX1_TX - | LED_TXRX_RX1); +static const uint32_t STATE_RX1_TXRX = (SRX1_RX | SRX1_TX | LED_TXRX_RX1); -static const uint32_t STATE_FDX1_TXRX = (TX_ENABLE1 - | SFDX1_RX - | SFDX1_TX - | LED_TXRX_TX1 - | LED_RX1); +static const uint32_t STATE_FDX1_TXRX = + (TX_ENABLE1 | SFDX1_RX | SFDX1_TX | LED_TXRX_TX1 | LED_RX1); -static const uint32_t STATE_TX1_TXRX = (TX_ENABLE1 - | SFDX1_RX - | SFDX1_TX - | LED_TXRX_TX1); +static const uint32_t STATE_TX1_TXRX = (TX_ENABLE1 | SFDX1_RX | SFDX1_TX | LED_TXRX_TX1); ///////////////////////// side 2 /////////////////////////////////// -static const uint32_t STATE_RX2_RX2 = (SFDX2_RX - | SRX2_TX - | LED_RX2); - -static const uint32_t STATE_RX2_TXRX = (SRX2_TX - | SRX2_RX - | LED_TXRX_RX2); - -static const uint32_t STATE_FDX2_TXRX = (TX_ENABLE2 - | SFDX2_RX - | SFDX2_TX - | LED_TXRX_TX2 - | LED_RX2); - -static const uint32_t STATE_TX2_TXRX = (TX_ENABLE2 - | SFDX2_RX - | SFDX2_TX - | LED_TXRX_TX2); +static const uint32_t STATE_RX2_RX2 = (SFDX2_RX | SRX2_TX | LED_RX2); + +static const uint32_t STATE_RX2_TXRX = (SRX2_TX | SRX2_RX | LED_TXRX_RX2); + +static const uint32_t STATE_FDX2_TXRX = + (TX_ENABLE2 | SFDX2_RX | SFDX2_TX | LED_TXRX_TX2 | LED_RX2); + +static const uint32_t STATE_TX2_TXRX = (TX_ENABLE2 | SFDX2_RX | SFDX2_TX | LED_TXRX_TX2); #endif /* INCLUDED_B200_REGS_HPP */ diff --git a/host/lib/usrp/b200/b200_uart.cpp b/host/lib/usrp/b200/b200_uart.cpp index 8c8e2462a..b78690705 100644 --- a/host/lib/usrp/b200/b200_uart.cpp +++ b/host/lib/usrp/b200/b200_uart.cpp @@ -7,24 +7,24 @@ #include "b200_uart.hpp" #include "b200_impl.hpp" +#include <uhd/exception.hpp> #include <uhd/transport/bounded_buffer.hpp> #include <uhd/transport/vrt_if_packet.hpp> +#include <uhd/types/time_spec.hpp> #include <uhd/utils/byteswap.hpp> #include <uhd/utils/log.hpp> -#include <uhd/types/time_spec.hpp> -#include <uhd/exception.hpp> using namespace uhd; using namespace uhd::transport; struct b200_uart_impl : b200_uart { - b200_uart_impl(zero_copy_if::sptr xport, const uint32_t sid): - _xport(xport), - _sid(sid), - _count(0), - _baud_div(std::floor(B200_BUS_CLOCK_RATE/115200 + 0.5)), - _line_queue(4096) + b200_uart_impl(zero_copy_if::sptr xport, const uint32_t sid) + : _xport(xport) + , _sid(sid) + , _count(0) + , _baud_div(std::floor(B200_BUS_CLOCK_RATE / 115200 + 0.5)) + , _line_queue(4096) { /*NOP*/ } @@ -35,31 +35,31 @@ struct b200_uart_impl : b200_uart UHD_ASSERT_THROW(bool(buff)); vrt::if_packet_info_t packet_info; - packet_info.link_type = vrt::if_packet_info_t::LINK_TYPE_CHDR; - packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CONTEXT; + packet_info.link_type = vrt::if_packet_info_t::LINK_TYPE_CHDR; + packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CONTEXT; packet_info.num_payload_words32 = 2; - packet_info.num_payload_bytes = packet_info.num_payload_words32*sizeof(uint32_t); + packet_info.num_payload_bytes = + packet_info.num_payload_words32 * sizeof(uint32_t); packet_info.packet_count = _count++; - packet_info.sob = false; - packet_info.eob = false; - packet_info.sid = _sid; - packet_info.has_sid = true; - packet_info.has_cid = false; - packet_info.has_tsi = false; - packet_info.has_tsf = false; - packet_info.has_tlr = false; + packet_info.sob = false; + packet_info.eob = false; + packet_info.sid = _sid; + packet_info.has_sid = true; + packet_info.has_cid = false; + packet_info.has_tsi = false; + packet_info.has_tsf = false; + packet_info.has_tlr = false; - uint32_t *packet_buff = buff->cast<uint32_t *>(); + uint32_t* packet_buff = buff->cast<uint32_t*>(); vrt::if_hdr_pack_le(packet_buff, packet_info); - packet_buff[packet_info.num_header_words32+0] = uhd::htowx(uint32_t(_baud_div)); - packet_buff[packet_info.num_header_words32+1] = uhd::htowx(uint32_t(ch)); - buff->commit(packet_info.num_packet_words32*sizeof(uint32_t)); + packet_buff[packet_info.num_header_words32 + 0] = uhd::htowx(uint32_t(_baud_div)); + packet_buff[packet_info.num_header_words32 + 1] = uhd::htowx(uint32_t(ch)); + buff->commit(packet_info.num_packet_words32 * sizeof(uint32_t)); } - void write_uart(const std::string &buff) + void write_uart(const std::string& buff) { - for(const char ch: buff) - { + for (const char ch : buff) { this->send_char(ch); } } @@ -73,15 +73,14 @@ struct b200_uart_impl : b200_uart void handle_uart_packet(managed_recv_buffer::sptr buff) { - const uint32_t *packet_buff = buff->cast<const uint32_t *>(); + const uint32_t* packet_buff = buff->cast<const uint32_t*>(); vrt::if_packet_info_t packet_info; - packet_info.link_type = vrt::if_packet_info_t::LINK_TYPE_CHDR; - packet_info.num_packet_words32 = buff->size()/sizeof(uint32_t); + packet_info.link_type = vrt::if_packet_info_t::LINK_TYPE_CHDR; + packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t); vrt::if_hdr_unpack_le(packet_buff, packet_info); - const char ch = char(uhd::wtohx(packet_buff[packet_info.num_header_words32+1])); + const char ch = char(uhd::wtohx(packet_buff[packet_info.num_header_words32 + 1])); _line += ch; - if (ch == '\n') - { + if (ch == '\n') { _line_queue.push_with_pop_on_full(_line); _line.clear(); } diff --git a/host/lib/usrp/b200/b200_uart.hpp b/host/lib/usrp/b200/b200_uart.hpp index c6de5f844..b70cdfa89 100644 --- a/host/lib/usrp/b200/b200_uart.hpp +++ b/host/lib/usrp/b200/b200_uart.hpp @@ -14,7 +14,7 @@ #include <uhd/utils/noncopyable.hpp> #include <memory> -class b200_uart: uhd::noncopyable, public uhd::uart_iface +class b200_uart : uhd::noncopyable, public uhd::uart_iface { public: typedef std::shared_ptr<b200_uart> sptr; diff --git a/host/lib/usrp/common/ad9361_ctrl.cpp b/host/lib/usrp/common/ad9361_ctrl.cpp index 2c928efcc..a584ef0f7 100644 --- a/host/lib/usrp/common/ad9361_ctrl.cpp +++ b/host/lib/usrp/common/ad9361_ctrl.cpp @@ -9,8 +9,8 @@ #include <uhd/types/serial.hpp> #include <uhd/utils/log.hpp> #include <uhdlib/usrp/common/ad9361_ctrl.hpp> -#include <memory> #include <cstring> +#include <memory> #include <mutex> using namespace uhd; diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp index 44b650f52..784658cb0 100644 --- a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp +++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp @@ -5,22 +5,21 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include "ad9361_device.h" +#include "ad9361_client.h" #include "ad9361_filter_taps.h" #include "ad9361_gain_tables.h" #include "ad9361_synth_lut.h" -#include "ad9361_client.h" -#include "ad9361_device.h" #define _USE_MATH_DEFINES #include <uhd/exception.hpp> #include <uhd/utils/log.hpp> - -#include <boost/scoped_array.hpp> +#include <stdint.h> #include <boost/format.hpp> #include <boost/math/special_functions.hpp> +#include <boost/scoped_array.hpp> #include <chrono> -#include <thread> #include <cmath> -#include <stdint.h> +#include <thread> //////////////////////////////////////////////////////////// // the following macros evaluate to a compile time constant @@ -33,14 +32,11 @@ #define HEX__(n) 0x##n##LU /* 8-bit conversion function */ -#define B8__(x) ((x&0x0000000FLU)?1:0) \ -+((x&0x000000F0LU)?2:0) \ -+((x&0x00000F00LU)?4:0) \ -+((x&0x0000F000LU)?8:0) \ -+((x&0x000F0000LU)?16:0) \ -+((x&0x00F00000LU)?32:0) \ -+((x&0x0F000000LU)?64:0) \ -+((x&0xF0000000LU)?128:0) +#define B8__(x) \ + ((x & 0x0000000FLU) ? 1 : 0) + ((x & 0x000000F0LU) ? 2 : 0) \ + + ((x & 0x00000F00LU) ? 4 : 0) + ((x & 0x0000F000LU) ? 8 : 0) \ + + ((x & 0x000F0000LU) ? 16 : 0) + ((x & 0x00F00000LU) ? 32 : 0) \ + + ((x & 0x0F000000LU) ? 64 : 0) + ((x & 0xF0000000LU) ? 128 : 0) /* for upto 8-bit binary constants */ #define B8(d) ((unsigned char)B8__(HEX__(d))) @@ -53,8 +49,9 @@ namespace uhd { namespace usrp { * point numbers. It is used to prevent re-tunes for frequencies that are * the same but not 'exactly' because of data precision issues. */ // TODO: see if we can avoid the need for this function -int freq_is_nearly_equal(double a, double b) { - return std::max(a,b) - std::min(a,b) < 1; +int freq_is_nearly_equal(double a, double b) +{ + return std::max(a, b) - std::min(a, b) < 1; } /*********************************************************************** @@ -63,26 +60,29 @@ int freq_is_nearly_equal(double a, double b) { /* This function takes in the calculated maximum number of FIR taps, and * returns a number of taps that makes AD9361 happy. */ -int get_num_taps(int max_num_taps) { - - int num_taps = 0; +int get_num_taps(int max_num_taps) +{ + int num_taps = 0; int num_taps_list[] = {16, 32, 48, 64, 80, 96, 112, 128}; int i; - for(i = 1; i < 8; i++) { - if(max_num_taps >= num_taps_list[i]) { + for (i = 1; i < 8; i++) { + if (max_num_taps >= num_taps_list[i]) { continue; } else { num_taps = num_taps_list[i - 1]; break; } - } if(num_taps == 0) { num_taps = 128; } + } + if (num_taps == 0) { + num_taps = 128; + } return num_taps; } -const double ad9361_device_t::AD9361_MAX_GAIN = 89.75; -const double ad9361_device_t::AD9361_MIN_CLOCK_RATE = 220e3; -const double ad9361_device_t::AD9361_MAX_CLOCK_RATE = 61.44e6; +const double ad9361_device_t::AD9361_MAX_GAIN = 89.75; +const double ad9361_device_t::AD9361_MIN_CLOCK_RATE = 220e3; +const double ad9361_device_t::AD9361_MAX_CLOCK_RATE = 61.44e6; const double ad9361_device_t::AD9361_CAL_VALID_WINDOW = 100e6; // Max bandwdith is due to filter rolloff in analog filter stage const double ad9361_device_t::AD9361_MIN_BW = 200e3; @@ -98,7 +98,8 @@ const double ad9361_device_t::DEFAULT_TX_FREQ = 850e6; * how many taps are in the filter, and given a vector of the taps * themselves. */ -void ad9361_device_t::_program_fir_filter(direction_t direction, chain_t chain, int num_taps, uint16_t *coeffs) +void ad9361_device_t::_program_fir_filter( + direction_t direction, chain_t chain, int num_taps, uint16_t* coeffs) { uint16_t base; @@ -115,14 +116,14 @@ void ad9361_device_t::_program_fir_filter(direction_t direction, chain_t chain, uint8_t reg_chain = 0; switch (chain) { - case CHAIN_1: - reg_chain = 0x01 << 3; - break; - case CHAIN_2: - reg_chain = 0x02 << 3; - break; - default: - reg_chain = 0x03 << 3; + case CHAIN_1: + reg_chain = 0x01 << 3; + break; + case CHAIN_2: + reg_chain = 0x02 << 3; + break; + default: + reg_chain = 0x03 << 3; } /* Turn on the filter clock. */ @@ -140,7 +141,8 @@ void ad9361_device_t::_program_fir_filter(direction_t direction, chain_t chain, _io_iface->poke8(base + 4, 0x00); } - /* Iterate through indirect programming of filter coeffs using ADI recomended procedure */ + /* Iterate through indirect programming of filter coeffs using ADI recomended + * procedure */ for (addr = 0; addr < num_taps; addr++) { _io_iface->poke8(base + 0, addr); _io_iface->poke8(base + 1, (coeffs[addr]) & 0xff); @@ -151,23 +153,25 @@ void ad9361_device_t::_program_fir_filter(direction_t direction, chain_t chain, } /* UG-671 states (page 25) (paraphrased and clarified): - " After the table has been programmed, write to register BASE+5 with the write bit D2 cleared and D1 high. - Then, write to register BASE+5 again with D1 clear, thus ensuring that the write bit resets internally - before the clock stops. Wait 4 sample clock periods after setting D2 high while that data writes into the table" + " After the table has been programmed, write to register BASE+5 with the write bit D2 + cleared and D1 high. Then, write to register BASE+5 again with D1 clear, thus + ensuring that the write bit resets internally before the clock stops. Wait 4 sample + clock periods after setting D2 high while that data writes into the table" */ _io_iface->poke8(base + 5, reg_numtaps | reg_chain | (1 << 1)); if (direction == RX) { - _io_iface->poke8(base + 5, reg_numtaps | reg_chain ); + _io_iface->poke8(base + 5, reg_numtaps | reg_chain); /* Rx Gain, set to prevent digital overflow/saturation in filters 0:+6dB, 1:0dB, 2:-6dB, 3:-12dB page 35 of UG-671 */ - _io_iface->poke8(base + 6, 0x02); /* Also turn on -6dB Rx gain here, to stop filter overfow.*/ + _io_iface->poke8( + base + 6, 0x02); /* Also turn on -6dB Rx gain here, to stop filter overfow.*/ } else { /* Tx Gain. bit[0]. set to prevent digital overflow/saturation in filters 0: 0dB, 1:-6dB page 25 of UG-671 */ - _io_iface->poke8(base + 5, reg_numtaps | reg_chain ); + _io_iface->poke8(base + 5, reg_numtaps | reg_chain); } } @@ -175,26 +179,31 @@ void ad9361_device_t::_program_fir_filter(direction_t direction, chain_t chain, /* Program the RX FIR Filter. */ void ad9361_device_t::_setup_rx_fir(size_t num_taps, int32_t decimation) { - if (not (decimation == 1 or decimation == 2 or decimation == 4)) { + if (not(decimation == 1 or decimation == 2 or decimation == 4)) { throw uhd::runtime_error("[ad9361_device_t] Invalid Rx FIR decimation."); } boost::scoped_array<uint16_t> coeffs(new uint16_t[num_taps]); for (size_t i = 0; i < num_taps; i++) { switch (num_taps) { - case 128: - coeffs[i] = uint16_t((decimation==4) ? fir_128_x4_coeffs[i] : hb127_coeffs[i]); - break; - case 96: - coeffs[i] = uint16_t((decimation==4) ? fir_96_x4_coeffs[i] : hb95_coeffs[i]); - break; - case 64: - coeffs[i] = uint16_t((decimation==4) ? fir_64_x4_coeffs[i] : hb63_coeffs[i]); - break; - case 48: - coeffs[i] = uint16_t((decimation==4) ? fir_48_x4_coeffs[i] : hb47_coeffs[i]); - break; - default: - throw uhd::runtime_error("[ad9361_device_t] Unsupported number of Rx FIR taps."); + case 128: + coeffs[i] = + uint16_t((decimation == 4) ? fir_128_x4_coeffs[i] : hb127_coeffs[i]); + break; + case 96: + coeffs[i] = + uint16_t((decimation == 4) ? fir_96_x4_coeffs[i] : hb95_coeffs[i]); + break; + case 64: + coeffs[i] = + uint16_t((decimation == 4) ? fir_64_x4_coeffs[i] : hb63_coeffs[i]); + break; + case 48: + coeffs[i] = + uint16_t((decimation == 4) ? fir_48_x4_coeffs[i] : hb47_coeffs[i]); + break; + default: + throw uhd::runtime_error( + "[ad9361_device_t] Unsupported number of Rx FIR taps."); } } @@ -204,29 +213,35 @@ void ad9361_device_t::_setup_rx_fir(size_t num_taps, int32_t decimation) /* Program the TX FIR Filter. */ void ad9361_device_t::_setup_tx_fir(size_t num_taps, int32_t interpolation) { - if (not (interpolation == 1 or interpolation == 2 or interpolation == 4)) { + if (not(interpolation == 1 or interpolation == 2 or interpolation == 4)) { throw uhd::runtime_error("[ad9361_device_t] Invalid Tx FIR interpolation."); } if (interpolation == 1 and num_taps > 64) { - throw uhd::runtime_error("[ad9361_device_t] Too many Tx FIR taps for interpolation value."); + throw uhd::runtime_error( + "[ad9361_device_t] Too many Tx FIR taps for interpolation value."); } boost::scoped_array<uint16_t> coeffs(new uint16_t[num_taps]); for (size_t i = 0; i < num_taps; i++) { switch (num_taps) { - case 128: - coeffs[i] = uint16_t((interpolation==4) ? fir_128_x4_coeffs[i] : hb127_coeffs[i]); - break; - case 96: - coeffs[i] = uint16_t((interpolation==4) ? fir_96_x4_coeffs[i] : hb95_coeffs[i]); - break; - case 64: - coeffs[i] = uint16_t((interpolation==4) ? fir_64_x4_coeffs[i] : hb63_coeffs[i]); - break; - case 48: - coeffs[i] = uint16_t((interpolation==4) ? fir_48_x4_coeffs[i] : hb47_coeffs[i]); - break; - default: - throw uhd::runtime_error("[ad9361_device_t] Unsupported number of Tx FIR taps."); + case 128: + coeffs[i] = uint16_t( + (interpolation == 4) ? fir_128_x4_coeffs[i] : hb127_coeffs[i]); + break; + case 96: + coeffs[i] = + uint16_t((interpolation == 4) ? fir_96_x4_coeffs[i] : hb95_coeffs[i]); + break; + case 64: + coeffs[i] = + uint16_t((interpolation == 4) ? fir_64_x4_coeffs[i] : hb63_coeffs[i]); + break; + case 48: + coeffs[i] = + uint16_t((interpolation == 4) ? fir_48_x4_coeffs[i] : hb47_coeffs[i]); + break; + default: + throw uhd::runtime_error( + "[ad9361_device_t] Unsupported number of Tx FIR taps."); } } @@ -310,9 +325,10 @@ void ad9361_device_t::_calibrate_synth_charge_pumps() double ad9361_device_t::_calibrate_baseband_rx_analog_filter(double req_rfbw) { double bbbw = req_rfbw / 2.0; - if(bbbw > _baseband_bw / 2.0) - { - UHD_LOGGER_DEBUG("AD936X")<< "baseband bandwidth too large for current sample rate. Setting bandwidth to: "<<_baseband_bw; + if (bbbw > _baseband_bw / 2.0) { + UHD_LOGGER_DEBUG("AD936X") << "baseband bandwidth too large for current sample " + "rate. Setting bandwidth to: " + << _baseband_bw; bbbw = _baseband_bw / 2.0; } @@ -326,16 +342,17 @@ double ad9361_device_t::_calibrate_baseband_rx_analog_filter(double req_rfbw) } double rxtune_clk = ((1.4 * bbbw * 2 * M_PI) / M_LN2); - _rx_bbf_tunediv = std::min<uint16_t>(511, uint16_t(std::ceil(_bbpll_freq / rxtune_clk))); + _rx_bbf_tunediv = + std::min<uint16_t>(511, uint16_t(std::ceil(_bbpll_freq / rxtune_clk))); _regs.bbftune_config = (_regs.bbftune_config & 0xFE) - | ((_rx_bbf_tunediv >> 8) & 0x0001); + | ((_rx_bbf_tunediv >> 8) & 0x0001); - double bbbw_mhz = bbbw / 1e6; - double temp = ((bbbw_mhz - std::floor(bbbw_mhz)) * 1000) / 7.8125; + double bbbw_mhz = bbbw / 1e6; + double temp = ((bbbw_mhz - std::floor(bbbw_mhz)) * 1000) / 7.8125; uint8_t bbbw_khz = std::min<uint8_t>(127, uint8_t(std::floor(temp + 0.5))); /* Set corner frequencies and dividers. */ - _io_iface->poke8(0x1fb, (uint8_t) (bbbw_mhz)); + _io_iface->poke8(0x1fb, (uint8_t)(bbbw_mhz)); _io_iface->poke8(0x1fc, bbbw_khz); _io_iface->poke8(0x1f8, (_rx_bbf_tunediv & 0x00FF)); _io_iface->poke8(0x1f9, _regs.bbftune_config); @@ -377,9 +394,10 @@ double ad9361_device_t::_calibrate_baseband_tx_analog_filter(double req_rfbw) { double bbbw = req_rfbw / 2.0; - if(bbbw > _baseband_bw / 2.0) - { - UHD_LOGGER_DEBUG("AD936X")<< "baseband bandwidth too large for current sample rate. Setting bandwidth to: "<<_baseband_bw; + if (bbbw > _baseband_bw / 2.0) { + UHD_LOGGER_DEBUG("AD936X") << "baseband bandwidth too large for current sample " + "rate. Setting bandwidth to: " + << _baseband_bw; bbbw = _baseband_bw / 2.0; } @@ -393,9 +411,9 @@ double ad9361_device_t::_calibrate_baseband_tx_analog_filter(double req_rfbw) } double txtune_clk = ((1.6 * bbbw * 2 * M_PI) / M_LN2); - uint16_t txbbfdiv = std::min<uint16_t>(511, uint16_t(std::ceil(_bbpll_freq / txtune_clk))); - _regs.bbftune_mode = (_regs.bbftune_mode & 0xFE) - | ((txbbfdiv >> 8) & 0x0001); + uint16_t txbbfdiv = + std::min<uint16_t>(511, uint16_t(std::ceil(_bbpll_freq / txtune_clk))); + _regs.bbftune_mode = (_regs.bbftune_mode & 0xFE) | ((txbbfdiv >> 8) & 0x0001); /* Program the divider values. */ _io_iface->poke8(0x0d6, (txbbfdiv & 0x00FF)); @@ -432,9 +450,10 @@ double ad9361_device_t::_calibrate_secondary_tx_filter(double req_rfbw) { double bbbw = req_rfbw / 2.0; - if(bbbw > _baseband_bw / 2.0) - { - UHD_LOGGER_DEBUG("AD936X")<< "baseband bandwidth too large for current sample rate. Setting bandwidth to: "<<_baseband_bw; + if (bbbw > _baseband_bw / 2.0) { + UHD_LOGGER_DEBUG("AD936X") << "baseband bandwidth too large for current sample " + "rate. Setting bandwidth to: " + << _baseband_bw; bbbw = _baseband_bw / 2.0; } @@ -459,8 +478,9 @@ double ad9361_device_t::_calibrate_secondary_tx_filter(double req_rfbw) int cap = 0; int i; for (i = 0; i <= 3; i++) { - cap = static_cast<int>(std::floor(0.5 + ((1 / ((corner_freq * res) * 1e6)) * 1e12))) - - 12; + cap = + static_cast<int>(std::floor(0.5 + ((1 / ((corner_freq * res) * 1e6)) * 1e12))) + - 12; if (cap <= 63) { break; @@ -483,7 +503,8 @@ double ad9361_device_t::_calibrate_secondary_tx_filter(double req_rfbw) reg0d0 = 0x57; } else { reg0d0 = 0x00; - throw uhd::runtime_error("[ad9361_device_t] Cal2ndTxFil: INVALID_CODE_PATH bad bbbw_mhz"); + throw uhd::runtime_error( + "[ad9361_device_t] Cal2ndTxFil: INVALID_CODE_PATH bad bbbw_mhz"); } /* Translate resistor values to register settings. */ @@ -528,9 +549,10 @@ double ad9361_device_t::_calibrate_rx_TIAs(double req_rfbw) double bbbw = req_rfbw / 2.0; - if(bbbw > _baseband_bw / 2.0) - { - UHD_LOGGER_DEBUG("AD936X")<< "baseband bandwidth too large for current sample rate. Setting bandwidth to: "<<_baseband_bw; + if (bbbw > _baseband_bw / 2.0) { + UHD_LOGGER_DEBUG("AD936X") << "baseband bandwidth too large for current sample " + "rate. Setting bandwidth to: " + << _baseband_bw; bbbw = _baseband_bw / 2.0; } @@ -545,8 +567,8 @@ double ad9361_device_t::_calibrate_rx_TIAs(double req_rfbw) double ceil_bbbw_mhz = std::ceil(bbbw / 1e6); /* Do some crazy resistor and capacitor math. */ - int Cbbf = (reg1eb * 160) + (reg1ec * 10) + 140; - int R2346 = 18300 * (reg1e6 & 0x07); + int Cbbf = (reg1eb * 160) + (reg1ec * 10) + 140; + int R2346 = 18300 * (reg1e6 & 0x07); double CTIA_fF = (Cbbf * R2346 * 0.56) / 3500; /* Translate baseband BW to register settings. */ @@ -557,22 +579,23 @@ double ad9361_device_t::_calibrate_rx_TIAs(double req_rfbw) } else if (ceil_bbbw_mhz > 10) { reg1db = 0x20; } else { - throw uhd::runtime_error("[ad9361_device_t] CalRxTias: INVALID_CODE_PATH bad bbbw_mhz"); + throw uhd::runtime_error( + "[ad9361_device_t] CalRxTias: INVALID_CODE_PATH bad bbbw_mhz"); } if (CTIA_fF > 2920) { - reg1dc = 0x40; - reg1de = 0x40; - uint8_t temp = (uint8_t) std::min<uint8_t>(127, - uint8_t(std::floor(0.5 + ((CTIA_fF - 400.0) / 320.0)))); + reg1dc = 0x40; + reg1de = 0x40; + uint8_t temp = (uint8_t)std::min<uint8_t>( + 127, uint8_t(std::floor(0.5 + ((CTIA_fF - 400.0) / 320.0)))); reg1dd = temp; reg1df = temp; } else { uint8_t temp = uint8_t(std::floor(0.5 + ((CTIA_fF - 400.0) / 40.0)) + 0x40); - reg1dc = temp; - reg1de = temp; - reg1dd = 0; - reg1df = 0; + reg1dc = temp; + reg1de = temp; + reg1dd = 0; + reg1df = 0; } /* w00t. Settings calculated. Program them and roll out. */ @@ -593,12 +616,12 @@ double ad9361_device_t::_calibrate_rx_TIAs(double req_rfbw) * some of the 40 registers depend on the values in others. */ void ad9361_device_t::_setup_adc() { - double bbbw_mhz = (((_bbpll_freq / 1e6) / _rx_bbf_tunediv) * M_LN2) \ - / (1.4 * 2 * M_PI); + double bbbw_mhz = + (((_bbpll_freq / 1e6) / _rx_bbf_tunediv) * M_LN2) / (1.4 * 2 * M_PI); /* For calibration, baseband BW is half the complex BW, and must be * between 28e6 and 0.2e6. */ - if(bbbw_mhz > 28) { + if (bbbw_mhz > 28) { bbbw_mhz = 28; } else if (bbbw_mhz < 0.20) { bbbw_mhz = 0.20; @@ -606,101 +629,111 @@ void ad9361_device_t::_setup_adc() uint8_t rxbbf_c3_msb = _io_iface->peek8(0x1eb) & 0x3F; uint8_t rxbbf_c3_lsb = _io_iface->peek8(0x1ec) & 0x7F; - uint8_t rxbbf_r2346 = _io_iface->peek8(0x1e6) & 0x07; + uint8_t rxbbf_r2346 = _io_iface->peek8(0x1e6) & 0x07; double fsadc = _adcclock_freq / 1e6; /* Sort out the RC time constant for our baseband bandwidth... */ double rc_timeconst = 0.0; - if(bbbw_mhz < 18) { - rc_timeconst = (1 / ((1.4 * 2 * M_PI) \ - * (18300 * rxbbf_r2346) - * ((160e-15 * rxbbf_c3_msb) - + (10e-15 * rxbbf_c3_lsb) + 140e-15) - * (bbbw_mhz * 1e6))); + if (bbbw_mhz < 18) { + rc_timeconst = + (1 + / ((1.4 * 2 * M_PI) * (18300 * rxbbf_r2346) + * ((160e-15 * rxbbf_c3_msb) + (10e-15 * rxbbf_c3_lsb) + 140e-15) + * (bbbw_mhz * 1e6))); } else { - rc_timeconst = (1 / ((1.4 * 2 * M_PI) \ - * (18300 * rxbbf_r2346) - * ((160e-15 * rxbbf_c3_msb) - + (10e-15 * rxbbf_c3_lsb) + 140e-15) - * (bbbw_mhz * 1e6) * (1 + (0.01 * (bbbw_mhz - 18))))); + rc_timeconst = + (1 + / ((1.4 * 2 * M_PI) * (18300 * rxbbf_r2346) + * ((160e-15 * rxbbf_c3_msb) + (10e-15 * rxbbf_c3_lsb) + 140e-15) + * (bbbw_mhz * 1e6) * (1 + (0.01 * (bbbw_mhz - 18))))); } double scale_res = sqrt(1 / rc_timeconst); double scale_cap = sqrt(1 / rc_timeconst); double scale_snr = (_adcclock_freq < 80e6) ? 1.0 : 1.584893192; - double maxsnr = 640 / 160; + double maxsnr = 640 / 160; /* Calculate the values for all 40 settings registers. * * DO NOT TOUCH THIS UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING. kthx.*/ uint8_t data[40]; - data[0] = 0; data[1] = 0; data[2] = 0; data[3] = 0x24; - data[4] = 0x24; data[5] = 0; data[6] = 0; - data[7] = std::min<uint8_t>(124, uint8_t(std::floor(-0.5 - + (80.0 * scale_snr * scale_res - * std::min<double>(1.0, sqrt(maxsnr * fsadc / 640.0)))))); + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[3] = 0x24; + data[4] = 0x24; + data[5] = 0; + data[6] = 0; + data[7] = std::min<uint8_t>(124, + uint8_t( + std::floor(-0.5 + + (80.0 * scale_snr * scale_res + * std::min<double>(1.0, sqrt(maxsnr * fsadc / 640.0)))))); double data007 = data[7]; - data[8] = std::min<uint8_t>(255, uint8_t(std::floor(0.5 - + ((20.0 * (640.0 / fsadc) * ((data007 / 80.0)) - / (scale_res * scale_cap)))))); - data[10] = std::min<uint8_t>(127, uint8_t(std::floor(-0.5 + (77.0 * scale_res - * std::min<double>(1.0, sqrt(maxsnr * fsadc / 640.0)))))); + data[8] = std::min<uint8_t>(255, + uint8_t(std::floor(0.5 + + ((20.0 * (640.0 / fsadc) * ((data007 / 80.0)) + / (scale_res * scale_cap)))))); + data[10] = std::min<uint8_t>(127, + uint8_t(std::floor( + -0.5 + + (77.0 * scale_res * std::min<double>(1.0, sqrt(maxsnr * fsadc / 640.0)))))); double data010 = data[10]; - data[9] = std::min<uint8_t>(127, uint8_t(std::floor(0.8 * data010))); - data[11] = std::min<uint8_t>(255, uint8_t(std::floor(0.5 - + (20.0 * (640.0 / fsadc) * ((data010 / 77.0) - / (scale_res * scale_cap)))))); - data[12] = std::min<uint8_t>(127, uint8_t(std::floor(-0.5 - + (80.0 * scale_res * std::min<double>(1.0, - sqrt(maxsnr * fsadc / 640.0)))))); + data[9] = std::min<uint8_t>(127, uint8_t(std::floor(0.8 * data010))); + data[11] = std::min<uint8_t>(255, + uint8_t(std::floor( + 0.5 + + (20.0 * (640.0 / fsadc) * ((data010 / 77.0) / (scale_res * scale_cap)))))); + data[12] = std::min<uint8_t>(127, + uint8_t(std::floor( + -0.5 + + (80.0 * scale_res * std::min<double>(1.0, sqrt(maxsnr * fsadc / 640.0)))))); double data012 = data[12]; - data[13] = std::min<uint8_t>(255, uint8_t(std::floor(-1.5 - + (20.0 * (640.0 / fsadc) * ((data012 / 80.0) - / (scale_res * scale_cap)))))); - data[14] = 21 * uint8_t(std::floor(0.1 * 640.0 / fsadc)); - data[15] = std::min<uint8_t>(127, uint8_t(1.025 * data007)); + data[13] = std::min<uint8_t>(255, + uint8_t(std::floor( + -1.5 + + (20.0 * (640.0 / fsadc) * ((data012 / 80.0) / (scale_res * scale_cap)))))); + data[14] = 21 * uint8_t(std::floor(0.1 * 640.0 / fsadc)); + data[15] = std::min<uint8_t>(127, uint8_t(1.025 * data007)); double data015 = data[15]; - data[16] = std::min<uint8_t>(127, uint8_t(std::floor((data015 - * (0.98 + (0.02 * std::max<double>(1.0, - (640.0 / fsadc) / maxsnr))))))); - data[17] = data[15]; - data[18] = std::min<uint8_t>(127, uint8_t(0.975 * (data010))); + data[16] = std::min<uint8_t>(127, + uint8_t(std::floor( + (data015 + * (0.98 + (0.02 * std::max<double>(1.0, (640.0 / fsadc) / maxsnr))))))); + data[17] = data[15]; + data[18] = std::min<uint8_t>(127, uint8_t(0.975 * (data010))); double data018 = data[18]; - data[19] = std::min<uint8_t>(127, uint8_t(std::floor((data018 - * (0.98 + (0.02 * std::max<double>(1.0, - (640.0 / fsadc) / maxsnr))))))); - data[20] = data[18]; - data[21] = std::min<uint8_t>(127, uint8_t(0.975 * data012)); + data[19] = std::min<uint8_t>(127, + uint8_t(std::floor( + (data018 + * (0.98 + (0.02 * std::max<double>(1.0, (640.0 / fsadc) / maxsnr))))))); + data[20] = data[18]; + data[21] = std::min<uint8_t>(127, uint8_t(0.975 * data012)); double data021 = data[21]; - data[22] = std::min<uint8_t>(127, uint8_t(std::floor((data021 - * (0.98 + (0.02 * std::max<double>(1.0, - (640.0 / fsadc) / maxsnr))))))); - data[23] = data[21]; - data[24] = 0x2e; - data[25] = uint8_t(std::floor(128.0 + std::min<double>(63.0, - 63.0 * (fsadc / 640.0)))); - data[26] = uint8_t(std::floor(std::min<double>(63.0, 63.0 * (fsadc / 640.0) - * (0.92 + (0.08 * (640.0 / fsadc)))))); - data[27] = uint8_t(std::floor(std::min<double>(63.0, - 32.0 * sqrt(fsadc / 640.0)))); - data[28] = uint8_t(std::floor(128.0 + std::min<double>(63.0, - 63.0 * (fsadc / 640.0)))); - data[29] = uint8_t(std::floor(std::min<double>(63.0, - 63.0 * (fsadc / 640.0) - * (0.92 + (0.08 * (640.0 / fsadc)))))); - data[30] = uint8_t(std::floor(std::min<double>(63.0, - 32.0 * sqrt(fsadc / 640.0)))); - data[31] = uint8_t(std::floor(128.0 + std::min<double>(63.0, - 63.0 * (fsadc / 640.0)))); - data[32] = uint8_t(std::floor(std::min<double>(63.0, - 63.0 * (fsadc / 640.0) * (0.92 - + (0.08 * (640.0 / fsadc)))))); - data[33] = uint8_t(std::floor(std::min<double>(63.0, - 63.0 * sqrt(fsadc / 640.0)))); - data[34] = std::min<uint8_t>(127, uint8_t(std::floor(64.0 - * sqrt(fsadc / 640.0)))); + data[22] = std::min<uint8_t>(127, + uint8_t(std::floor( + (data021 + * (0.98 + (0.02 * std::max<double>(1.0, (640.0 / fsadc) / maxsnr))))))); + data[23] = data[21]; + data[24] = 0x2e; + data[25] = + uint8_t(std::floor(128.0 + std::min<double>(63.0, 63.0 * (fsadc / 640.0)))); + data[26] = uint8_t(std::floor(std::min<double>( + 63.0, 63.0 * (fsadc / 640.0) * (0.92 + (0.08 * (640.0 / fsadc)))))); + data[27] = uint8_t(std::floor(std::min<double>(63.0, 32.0 * sqrt(fsadc / 640.0)))); + data[28] = + uint8_t(std::floor(128.0 + std::min<double>(63.0, 63.0 * (fsadc / 640.0)))); + data[29] = uint8_t(std::floor(std::min<double>( + 63.0, 63.0 * (fsadc / 640.0) * (0.92 + (0.08 * (640.0 / fsadc)))))); + data[30] = uint8_t(std::floor(std::min<double>(63.0, 32.0 * sqrt(fsadc / 640.0)))); + data[31] = + uint8_t(std::floor(128.0 + std::min<double>(63.0, 63.0 * (fsadc / 640.0)))); + data[32] = uint8_t(std::floor(std::min<double>( + 63.0, 63.0 * (fsadc / 640.0) * (0.92 + (0.08 * (640.0 / fsadc)))))); + data[33] = uint8_t(std::floor(std::min<double>(63.0, 63.0 * sqrt(fsadc / 640.0)))); + data[34] = std::min<uint8_t>(127, uint8_t(std::floor(64.0 * sqrt(fsadc / 640.0)))); data[35] = 0x40; data[36] = 0x40; data[37] = 0x2c; @@ -708,8 +741,8 @@ void ad9361_device_t::_setup_adc() data[39] = 0x00; /* Program the registers! */ - for(size_t i = 0; i < 40; i++) { - _io_iface->poke8(0x200+i, data[i]); + for (size_t i = 0; i < 40; i++) { + _io_iface->poke8(0x200 + i, data[i]); } } @@ -718,11 +751,12 @@ void ad9361_device_t::_setup_adc() */ void ad9361_device_t::_calibrate_baseband_dc_offset() { - _io_iface->poke8(0x18b, 0x83); //Reset RF DC tracking flag + _io_iface->poke8(0x18b, 0x83); // Reset RF DC tracking flag _io_iface->poke8(0x193, 0x3f); // Calibration settings _io_iface->poke8(0x190, 0x0f); // Set tracking coefficient - //write_ad9361_reg(device, 0x190, /*0x0f*//*0xDF*/0x80*1 | 0x40*1 | (16+8/*+4*/)); // Set tracking coefficient: don't *4 counter, do decim /4, increased gain shift + // write_ad9361_reg(device, 0x190, /*0x0f*//*0xDF*/0x80*1 | 0x40*1 | (16+8/*+4*/)); // + // Set tracking coefficient: don't *4 counter, do decim /4, increased gain shift _io_iface->poke8(0x194, 0x01); // More calibration settings /* Start that calibration, baby. */ @@ -730,7 +764,8 @@ void ad9361_device_t::_calibrate_baseband_dc_offset() _io_iface->poke8(0x016, 0x01); while (_io_iface->peek8(0x016) & 0x01) { if (count > 100) { - throw uhd::runtime_error("[ad9361_device_t] Baseband DC Offset Calibration Failure"); + throw uhd::runtime_error( + "[ad9361_device_t] Baseband DC Offset Calibration Failure"); break; } count++; @@ -763,7 +798,8 @@ void ad9361_device_t::_calibrate_rf_dc_offset() _io_iface->poke8(0x016, 0x02); while (_io_iface->peek8(0x016) & 0x02) { if (count > 200) { - throw uhd::runtime_error("[ad9361_device_t] RF DC Offset Calibration Failure"); + throw uhd::runtime_error( + "[ad9361_device_t] RF DC Offset Calibration Failure"); break; } count++; @@ -814,7 +850,8 @@ void ad9361_device_t::_calibrate_rx_quadrature() _io_iface->poke8(0x016, 0x20); while (_io_iface->peek8(0x016) & 0x20) { if (count > 1000) { - throw uhd::runtime_error("[ad9361_device_t] Rx Quadrature Calibration Failure"); + throw uhd::runtime_error( + "[ad9361_device_t] Rx Quadrature Calibration Failure"); break; } count++; @@ -831,15 +868,15 @@ void ad9361_device_t::_calibrate_rx_quadrature() * The TX quadrature needs to be done twice, once for each TX chain, with * only one register change in between. Thus, this function enacts the * calibrations, and it is called from calibrate_tx_quadrature. */ -void ad9361_device_t::_tx_quadrature_cal_routine() { - +void ad9361_device_t::_tx_quadrature_cal_routine() +{ /* This is a weird process, but here is how it works: * 1) Read the calibrated NCO frequency bits out of 0A3. * 2) Write the two bits to the RX NCO freq part of 0A0. * 3) Re-read 0A3 to get bits [5:0] because maybe they changed? * 4) Update only the TX NCO freq bits in 0A3. * 5) Profit (I hope). */ - uint8_t reg0a3 = _io_iface->peek8(0x0a3); + uint8_t reg0a3 = _io_iface->peek8(0x0a3); uint8_t nco_freq = (reg0a3 & 0xC0); _io_iface->poke8(0x0a0, 0x15 | (nco_freq >> 1)); reg0a3 = _io_iface->peek8(0x0a3); @@ -849,8 +886,8 @@ void ad9361_device_t::_tx_quadrature_cal_routine() { * where the two test tones used for quadrature calibration are outside * of the RX BBF, and therefore don't make it to the ADC. We will check * for that scenario here. */ - double max_cal_freq = (((_baseband_bw * _tfir_factor) - * ((nco_freq >> 6) + 1)) / 32) * 2; + double max_cal_freq = + (((_baseband_bw * _tfir_factor) * ((nco_freq >> 6) + 1)) / 32) * 2; double bbbw = _baseband_bw / 2.0; // bbbw represents the one-sided BW if (bbbw > 28e6) { bbbw = 28e6; @@ -882,7 +919,8 @@ void ad9361_device_t::_tx_quadrature_cal_routine() { _io_iface->poke8(0x016, 0x10); while (_io_iface->peek8(0x016) & 0x10) { if (count > 100) { - throw uhd::runtime_error("[ad9361_device_t] TX Quadrature Calibration Failure"); + throw uhd::runtime_error( + "[ad9361_device_t] TX Quadrature Calibration Failure"); break; } count++; @@ -897,7 +935,8 @@ void ad9361_device_t::_calibrate_tx_quadrature() /* Make sure we are, in fact, in the ALERT state. If not, something is * terribly wrong in the driver execution flow. */ if ((_io_iface->peek8(0x017) & 0x0F) != 5) { - throw uhd::runtime_error("[ad9361_device_t] TX Quad Cal started, but not in ALERT"); + throw uhd::runtime_error( + "[ad9361_device_t] TX Quad Cal started, but not in ALERT"); } /* Turn off free-running and continuous calibrations. Note that this @@ -974,19 +1013,20 @@ void ad9361_device_t::_program_mixer_gm_subtable() /* Program the gain table. * * There are three different gain tables for different frequency ranges! */ -void ad9361_device_t::_program_gain_table() { +void ad9361_device_t::_program_gain_table() +{ /* Figure out which gain table we should be using for our current * frequency band. */ - uint8_t (*gain_table)[3] = NULL; + uint8_t(*gain_table)[3] = NULL; uint8_t new_gain_table; if (_rx_freq < 1300e6) { - gain_table = gain_table_sub_1300mhz; + gain_table = gain_table_sub_1300mhz; new_gain_table = 1; } else if (_rx_freq < 4e9) { - gain_table = gain_table_1300mhz_to_4000mhz; + gain_table = gain_table_1300mhz_to_4000mhz; new_gain_table = 2; } else if (_rx_freq <= 6e9) { - gain_table = gain_table_4000mhz_to_6000mhz; + gain_table = gain_table_4000mhz_to_6000mhz; new_gain_table = 3; } else { new_gain_table = 1; @@ -1112,17 +1152,17 @@ void ad9361_device_t::_setup_synth(direction_t direction, double vcorate) /* Parse the values out of the LUT based on our calculated index... */ uint8_t vco_output_level = synth_cal_lut[vcoindex][0]; - uint8_t vco_varactor = synth_cal_lut[vcoindex][1]; - uint8_t vco_bias_ref = synth_cal_lut[vcoindex][2]; - uint8_t vco_bias_tcf = synth_cal_lut[vcoindex][3]; - uint8_t vco_cal_offset = synth_cal_lut[vcoindex][4]; + uint8_t vco_varactor = synth_cal_lut[vcoindex][1]; + uint8_t vco_bias_ref = synth_cal_lut[vcoindex][2]; + uint8_t vco_bias_tcf = synth_cal_lut[vcoindex][3]; + uint8_t vco_cal_offset = synth_cal_lut[vcoindex][4]; uint8_t vco_varactor_ref = synth_cal_lut[vcoindex][5]; uint8_t charge_pump_curr = synth_cal_lut[vcoindex][6]; - uint8_t loop_filter_c2 = synth_cal_lut[vcoindex][7]; - uint8_t loop_filter_c1 = synth_cal_lut[vcoindex][8]; - uint8_t loop_filter_r1 = synth_cal_lut[vcoindex][9]; - uint8_t loop_filter_c3 = synth_cal_lut[vcoindex][10]; - uint8_t loop_filter_r3 = synth_cal_lut[vcoindex][11]; + uint8_t loop_filter_c2 = synth_cal_lut[vcoindex][7]; + uint8_t loop_filter_c1 = synth_cal_lut[vcoindex][8]; + uint8_t loop_filter_r1 = synth_cal_lut[vcoindex][9]; + uint8_t loop_filter_c3 = synth_cal_lut[vcoindex][10]; + uint8_t loop_filter_r3 = synth_cal_lut[vcoindex][11]; /* ... annnd program! */ if (direction == RX) { @@ -1171,8 +1211,8 @@ double ad9361_device_t::_tune_bbvco(const double rate) _req_coreclk = rate; - const double fref = 40e6; - const int modulus = 2088960; + const double fref = 40e6; + const int modulus = 2088960; const double vcomax = 1430e6; const double vcomin = 672e6; double vcorate; @@ -1181,7 +1221,7 @@ double ad9361_device_t::_tune_bbvco(const double rate) /* Iterate over VCO dividers until appropriate divider is found. */ int i = 1; for (; i <= 6; i++) { - vcodiv = 1 << i; + vcodiv = 1 << i; vcorate = rate * vcodiv; if (vcorate >= vcomin && vcorate <= vcomax) @@ -1196,40 +1236,40 @@ double ad9361_device_t::_tune_bbvco(const double rate) /* Fo = Fref * (Nint + Nfrac / mod) */ int nint = static_cast<int>(vcorate / fref); UHD_LOG_TRACE("AD936X", "[ad9361_device_t::_tune_bbvco] (nint)=" << (vcorate / fref)); - int nfrac = static_cast<int>(boost::math::round(((vcorate / fref) - (double) nint) * (double) modulus)); + int nfrac = static_cast<int>( + boost::math::round(((vcorate / fref) - (double)nint) * (double)modulus)); UHD_LOG_TRACE("AD936X", "[ad9361_device_t::_tune_bbvco] (nfrac)=" << ((vcorate / fref) - (double)nint) * (double)modulus); UHD_LOG_TRACE("AD936X", boost::format("[ad9361_device_t::_tune_bbvco] nint=%d nfrac=%d") % nint % nfrac); - double actual_vcorate = fref - * ((double) nint + ((double) nfrac / (double) modulus)); + double actual_vcorate = fref * ((double)nint + ((double)nfrac / (double)modulus)); /* Scale CP current according to VCO rate */ - const double icp_baseline = 150e-6; + const double icp_baseline = 150e-6; const double freq_baseline = 1280e6; - double icp = icp_baseline * (actual_vcorate / freq_baseline); - int icp_reg = static_cast<int>(icp / 25e-6) - 1; + double icp = icp_baseline * (actual_vcorate / freq_baseline); + int icp_reg = static_cast<int>(icp / 25e-6) - 1; - _io_iface->poke8(0x045, 0x00); // REFCLK / 1 to BBPLL - _io_iface->poke8(0x046, icp_reg & 0x3F); // CP current - _io_iface->poke8(0x048, 0xe8); // BBPLL loop filters - _io_iface->poke8(0x049, 0x5b); // BBPLL loop filters - _io_iface->poke8(0x04a, 0x35); // BBPLL loop filters + _io_iface->poke8(0x045, 0x00); // REFCLK / 1 to BBPLL + _io_iface->poke8(0x046, icp_reg & 0x3F); // CP current + _io_iface->poke8(0x048, 0xe8); // BBPLL loop filters + _io_iface->poke8(0x049, 0x5b); // BBPLL loop filters + _io_iface->poke8(0x04a, 0x35); // BBPLL loop filters _io_iface->poke8(0x04b, 0xe0); - _io_iface->poke8(0x04e, 0x10); // Max accuracy + _io_iface->poke8(0x04e, 0x10); // Max accuracy - _io_iface->poke8(0x043, nfrac & 0xFF); // Nfrac[7:0] - _io_iface->poke8(0x042, (nfrac >> 8) & 0xFF); // Nfrac[15:8] + _io_iface->poke8(0x043, nfrac & 0xFF); // Nfrac[7:0] + _io_iface->poke8(0x042, (nfrac >> 8) & 0xFF); // Nfrac[15:8] _io_iface->poke8(0x041, (nfrac >> 16) & 0xFF); // Nfrac[23:16] - _io_iface->poke8(0x044, nint); // Nint + _io_iface->poke8(0x044, nint); // Nint _calibrate_lock_bbpll(); _regs.bbpll = (_regs.bbpll & 0xF8) | i; - _bbpll_freq = actual_vcorate; + _bbpll_freq = actual_vcorate; _adcclock_freq = (actual_vcorate / vcodiv); return _adcclock_freq; @@ -1242,10 +1282,10 @@ double ad9361_device_t::_tune_bbvco(const double rate) * settings to the appropriate index after a re-tune. */ void ad9361_device_t::_reprogram_gains() { - set_gain(RX, CHAIN_1,_rx1_gain); - set_gain(RX, CHAIN_2,_rx2_gain); - set_gain(TX, CHAIN_1,_tx1_gain); - set_gain(TX, CHAIN_2,_tx2_gain); + set_gain(RX, CHAIN_1, _rx1_gain); + set_gain(RX, CHAIN_2, _rx2_gain); + set_gain(TX, CHAIN_1, _tx1_gain); + set_gain(TX, CHAIN_2, _tx2_gain); } /* This is the internal tune function, not available for a host call. @@ -1255,8 +1295,8 @@ void ad9361_device_t::_reprogram_gains() double ad9361_device_t::_tune_helper(direction_t direction, const double value) { /* The RFPLL runs from 6 GHz - 12 GHz */ - const double fref = 80e6; - const int modulus = 8388593; + const double fref = 80e6; + const int modulus = 8388593; const double vcomax = 12e9; const double vcomin = 6e9; double vcorate; @@ -1265,7 +1305,7 @@ double ad9361_device_t::_tune_helper(direction_t direction, const double value) /* Iterate over VCO dividers until appropriate divider is found. */ int i; for (i = 0; i <= 6; i++) { - vcodiv = 2 << i; + vcodiv = 2 << i; vcorate = value * vcodiv; if (vcorate >= vcomin && vcorate <= vcomax) break; @@ -1273,30 +1313,27 @@ double ad9361_device_t::_tune_helper(direction_t direction, const double value) if (i == 7) throw uhd::runtime_error("[ad9361_device_t] RFVCO can't find valid VCO rate!"); - int nint = static_cast<int>(vcorate / fref); + int nint = static_cast<int>(vcorate / fref); int nfrac = static_cast<int>(((vcorate / fref) - nint) * modulus); - double actual_vcorate = fref * (nint + (double) (nfrac) / modulus); - double actual_lo = actual_vcorate / vcodiv; + double actual_vcorate = fref * (nint + (double)(nfrac) / modulus); + double actual_lo = actual_vcorate / vcodiv; if (direction == RX) { - _req_rx_freq = value; /* Set band-specific settings. */ if (value < _client_params->get_band_edge(AD9361_RX_BAND0)) { _regs.inputsel = (_regs.inputsel & 0xC0) | 0x30; // Port C, balanced - } else if ((value - >= _client_params->get_band_edge(AD9361_RX_BAND0)) - && (value - < _client_params->get_band_edge(AD9361_RX_BAND1))) { + } else if ((value >= _client_params->get_band_edge(AD9361_RX_BAND0)) + && (value < _client_params->get_band_edge(AD9361_RX_BAND1))) { _regs.inputsel = (_regs.inputsel & 0xC0) | 0x0C; // Port B, balanced - } else if ((value - >= _client_params->get_band_edge(AD9361_RX_BAND1)) - && (value <= 6e9)) { + } else if ((value >= _client_params->get_band_edge(AD9361_RX_BAND1)) + && (value <= 6e9)) { _regs.inputsel = (_regs.inputsel & 0xC0) | 0x03; // Port A, balanced } else { - throw uhd::runtime_error("[ad9361_device_t] [_tune_helper] INVALID_CODE_PATH"); + throw uhd::runtime_error( + "[ad9361_device_t] [_tune_helper] INVALID_CODE_PATH"); } _io_iface->poke8(0x004, _regs.inputsel); @@ -1326,18 +1363,17 @@ double ad9361_device_t::_tune_helper(direction_t direction, const double value) return actual_lo; } else { - _req_tx_freq = value; /* Set band-specific settings. */ if (value < _client_params->get_band_edge(AD9361_TX_BAND0)) { _regs.inputsel = _regs.inputsel | 0x40; - } else if ((value - >= _client_params->get_band_edge(AD9361_TX_BAND0)) - && (value <= 6e9)) { + } else if ((value >= _client_params->get_band_edge(AD9361_TX_BAND0)) + && (value <= 6e9)) { _regs.inputsel = _regs.inputsel & 0xBF; } else { - throw uhd::runtime_error("[ad9361_device_t] [_tune_helper] INVALID_CODE_PATH"); + throw uhd::runtime_error( + "[ad9361_device_t] [_tune_helper] INVALID_CODE_PATH"); } _io_iface->poke8(0x004, _regs.inputsel); @@ -1387,8 +1423,8 @@ double ad9361_device_t::_setup_rates(const double rate) * bring-up, and then they will be switched out to reflect the actual * user-requested antenna selections. */ int divfactor = 0; - _tfir_factor = 0; - _rfir_factor = 0; + _tfir_factor = 0; + _rfir_factor = 0; if (rate < 0.33e6) { // RX1 + RX2 enabled, 3, 2, 2, 4 @@ -1397,7 +1433,7 @@ double ad9361_device_t::_setup_rates(const double rate) // TX1 + TX2 enabled, 3, 2, 2, 4 _regs.txfilt = B8(11101111); - divfactor = 48; + divfactor = 48; _tfir_factor = 4; _rfir_factor = 4; } else if (rate < 0.66e6) { @@ -1407,7 +1443,7 @@ double ad9361_device_t::_setup_rates(const double rate) // TX1 + TX2 enabled, 2, 2, 2, 4 _regs.txfilt = B8(11011111); - divfactor = 32; + divfactor = 32; _tfir_factor = 4; _rfir_factor = 4; } else if (rate <= 20e6) { @@ -1417,7 +1453,7 @@ double ad9361_device_t::_setup_rates(const double rate) // TX1 + TX2 enabled, 2, 2, 2, 2 _regs.txfilt = B8(11011110); - divfactor = 16; + divfactor = 16; _tfir_factor = 2; _rfir_factor = 2; } else if ((rate > 20e6) && (rate < 23e6)) { @@ -1427,7 +1463,7 @@ double ad9361_device_t::_setup_rates(const double rate) // TX1 + TX2 enabled, 3, 1, 2, 2 _regs.txfilt = B8(11100110); - divfactor = 24; + divfactor = 24; _tfir_factor = 2; _rfir_factor = 2; } else if ((rate >= 23e6) && (rate < 41e6)) { @@ -1437,7 +1473,7 @@ double ad9361_device_t::_setup_rates(const double rate) // TX1 + TX2 enabled, 1, 2, 2, 2 _regs.txfilt = B8(11001110); - divfactor = 16; + divfactor = 16; _tfir_factor = 2; _rfir_factor = 2; } else if ((rate >= 41e6) && (rate <= 58e6)) { @@ -1447,7 +1483,7 @@ double ad9361_device_t::_setup_rates(const double rate) // TX1 + TX2 enabled, 3, 1, 1, 2 _regs.txfilt = B8(11100010); - divfactor = 12; + divfactor = 12; _tfir_factor = 2; _rfir_factor = 2; } else if ((rate > 58e6) && (rate <= 61.44e6)) { @@ -1458,7 +1494,7 @@ double ad9361_device_t::_setup_rates(const double rate) // TX1 + TX2 enabled, 2, 1, 1, 2 _regs.txfilt = B8(11010010); - divfactor = 8; + divfactor = 8; _tfir_factor = 2; _rfir_factor = 2; } else { @@ -1470,14 +1506,14 @@ double ad9361_device_t::_setup_rates(const double rate) /* Tune the BBPLL to get the ADC and DAC clocks. */ const double adcclk = _tune_bbvco(rate * divfactor); - double dacclk = adcclk; + double dacclk = adcclk; /* The DAC clock must be <= 336e6, and is either the ADC clock or 1/2 the * ADC clock.*/ if (adcclk > 336e6) { /* Make the DAC clock = ADC/2 */ _regs.bbpll = _regs.bbpll | 0x08; - dacclk = adcclk / 2.0; + dacclk = adcclk / 2.0; } else { _regs.bbpll = _regs.bbpll & 0xF7; } @@ -1492,24 +1528,27 @@ double ad9361_device_t::_setup_rates(const double rate) _baseband_bw = (adcclk / divfactor); /* - The Tx & Rx FIR calculate 16 taps per clock cycle. This limits the number of available taps to the ratio of DAC_CLK/ADC_CLK - to the input data rate multiplied by 16. For example, if the input data rate is 25 MHz and DAC_CLK is 100 MHz, - then the ratio of DAC_CLK to the input data rate is 100/25 or 4. In this scenario, the total number of taps available is 64. - - Also, whilst the Rx FIR filter always has memory available for 128 taps, the Tx FIR Filter can only support a maximum length of 64 taps - in 1x interpolation mode, and 128 taps in 2x & 4x modes. + The Tx & Rx FIR calculate 16 taps per clock cycle. This limits the number of + available taps to the ratio of DAC_CLK/ADC_CLK to the input data rate multiplied + by 16. For example, if the input data rate is 25 MHz and DAC_CLK is 100 MHz, then the + ratio of DAC_CLK to the input data rate is 100/25 or 4. In this scenario, the total + number of taps available is 64. + + Also, whilst the Rx FIR filter always has memory available for 128 taps, the Tx FIR + Filter can only support a maximum length of 64 taps in 1x interpolation mode, and 128 + taps in 2x & 4x modes. */ - const size_t max_tx_taps = std::min<size_t>( - std::min<size_t>((16 * (int)((dacclk / rate) + 0.5)), 128), + const size_t max_tx_taps = + std::min<size_t>(std::min<size_t>((16 * (int)((dacclk / rate) + 0.5)), 128), (_tfir_factor == 1) ? 64 : 128); - const size_t max_rx_taps = std::min<size_t>((16 * (size_t)((adcclk / rate) + 0.5)), - 128); + const size_t max_rx_taps = + std::min<size_t>((16 * (size_t)((adcclk / rate) + 0.5)), 128); const size_t num_tx_taps = get_num_taps(max_tx_taps); const size_t num_rx_taps = get_num_taps(max_rx_taps); - _setup_tx_fir(num_tx_taps,_tfir_factor); - _setup_rx_fir(num_rx_taps,_rfir_factor); + _setup_tx_fir(num_tx_taps, _tfir_factor); + _setup_rx_fir(num_rx_taps, _rfir_factor); return _baseband_bw; } @@ -1522,42 +1561,42 @@ void ad9361_device_t::initialize() std::lock_guard<std::recursive_mutex> lock(_mutex); /* Initialize shadow registers. */ - _regs.vcodivs = 0x00; - _regs.inputsel = 0x30; - _regs.rxfilt = 0x00; - _regs.txfilt = 0x00; - _regs.bbpll = 0x02; + _regs.vcodivs = 0x00; + _regs.inputsel = 0x30; + _regs.rxfilt = 0x00; + _regs.txfilt = 0x00; + _regs.bbpll = 0x02; _regs.bbftune_config = 0x1e; - _regs.bbftune_mode = 0x1e; + _regs.bbftune_mode = 0x1e; /* Initialize private VRQ fields. */ - _rx_freq = DEFAULT_RX_FREQ; - _tx_freq = DEFAULT_TX_FREQ; - _req_rx_freq = 0.0; - _req_tx_freq = 0.0; - _baseband_bw = 0.0; - _req_clock_rate = 0.0; - _req_coreclk = 0.0; - _bbpll_freq = 0.0; - _adcclock_freq = 0.0; - _rx_bbf_tunediv = 0; - _curr_gain_table = 0; - _rx1_gain = 0; - _rx2_gain = 0; - _tx1_gain = 0; - _tx2_gain = 0; - _use_dc_offset_tracking = true; + _rx_freq = DEFAULT_RX_FREQ; + _tx_freq = DEFAULT_TX_FREQ; + _req_rx_freq = 0.0; + _req_tx_freq = 0.0; + _baseband_bw = 0.0; + _req_clock_rate = 0.0; + _req_coreclk = 0.0; + _bbpll_freq = 0.0; + _adcclock_freq = 0.0; + _rx_bbf_tunediv = 0; + _curr_gain_table = 0; + _rx1_gain = 0; + _rx2_gain = 0; + _tx1_gain = 0; + _tx2_gain = 0; + _use_dc_offset_tracking = true; _use_iq_balance_tracking = true; - _rx1_agc_mode = GAIN_MODE_SLOW_AGC; - _rx2_agc_mode = GAIN_MODE_SLOW_AGC; - _rx1_agc_enable = false; - _rx2_agc_enable = false; - _rx_analog_bw = 0; - _tx_analog_bw = 0; - _rx_tia_lp_bw = 0; - _tx_sec_lp_bw = 0; - _rx_bb_lp_bw = 0; - _tx_bb_lp_bw = 0; + _rx1_agc_mode = GAIN_MODE_SLOW_AGC; + _rx2_agc_mode = GAIN_MODE_SLOW_AGC; + _rx1_agc_enable = false; + _rx2_agc_enable = false; + _rx_analog_bw = 0; + _tx_analog_bw = 0; + _rx_tia_lp_bw = 0; + _tx_sec_lp_bw = 0; + _rx_bb_lp_bw = 0; + _tx_bb_lp_bw = 0; /* Reset the device. */ _io_iface->poke8(0x000, 0x01); @@ -1567,7 +1606,10 @@ void ad9361_device_t::initialize() /* Check device ID to make sure iface works */ uint32_t device_id = (_io_iface->peek8(0x037) & 0x8); if (device_id != 0x8) { - throw uhd::runtime_error(str(boost::format("[ad9361_device_t::initialize] Device ID readback failure. Expected: 0x8, Received: 0x%x") % device_id)); + throw uhd::runtime_error( + str(boost::format("[ad9361_device_t::initialize] Device ID readback failure. " + "Expected: 0x8, Received: 0x%x") + % device_id)); } /* There is not a WAT big enough for this. */ @@ -1582,20 +1624,20 @@ void ad9361_device_t::initialize() /* Enable clocks. */ switch (_client_params->get_clocking_mode()) { - case clocking_mode_t::AD9361_XTAL_N_CLK_PATH: { - _io_iface->poke8(0x009, 0x17); - } break; - - case clocking_mode_t::AD9361_XTAL_P_CLK_PATH: { - _io_iface->poke8(0x009, 0x07); - _io_iface->poke8(0x292, 0x08); - _io_iface->poke8(0x293, 0x80); - _io_iface->poke8(0x294, 0x00); - _io_iface->poke8(0x295, 0x14); - } break; + case clocking_mode_t::AD9361_XTAL_N_CLK_PATH: { + _io_iface->poke8(0x009, 0x17); + } break; + + case clocking_mode_t::AD9361_XTAL_P_CLK_PATH: { + _io_iface->poke8(0x009, 0x07); + _io_iface->poke8(0x292, 0x08); + _io_iface->poke8(0x293, 0x80); + _io_iface->poke8(0x294, 0x00); + _io_iface->poke8(0x295, 0x14); + } break; - default: - throw uhd::runtime_error("[ad9361_device_t] NOT IMPLEMENTED"); + default: + throw uhd::runtime_error("[ad9361_device_t] NOT IMPLEMENTED"); } std::this_thread::sleep_for(std::chrono::milliseconds(20)); @@ -1606,34 +1648,33 @@ void ad9361_device_t::initialize() * FDD dual port DDR CMOS no swap. * Force TX on one port, RX on the other. */ switch (_client_params->get_digital_interface_mode()) { - case AD9361_DDR_FDD_LVCMOS: { - _io_iface->poke8(0x010, 0xc8); // Swap I&Q on Tx, Swap I&Q on Rx, Toggle frame sync mode - _io_iface->poke8(0x011, 0x00); - _io_iface->poke8(0x012, 0x02); - } break; + case AD9361_DDR_FDD_LVCMOS: { + _io_iface->poke8( + 0x010, 0xc8); // Swap I&Q on Tx, Swap I&Q on Rx, Toggle frame sync mode + _io_iface->poke8(0x011, 0x00); + _io_iface->poke8(0x012, 0x02); + } break; - case AD9361_DDR_FDD_LVDS: { - _io_iface->poke8(0x010, 0xcc); // Swap I&Q on Tx, Swap I&Q on Rx, Toggle frame sync mode, 2R2T timing. - _io_iface->poke8(0x011, 0x00); - _io_iface->poke8(0x012, 0x10); + case AD9361_DDR_FDD_LVDS: { + _io_iface->poke8(0x010, 0xcc); // Swap I&Q on Tx, Swap I&Q on Rx, Toggle frame + // sync mode, 2R2T timing. + _io_iface->poke8(0x011, 0x00); + _io_iface->poke8(0x012, 0x10); - //LVDS Specific - _io_iface->poke8(0x03C, 0x23); - _io_iface->poke8(0x03D, 0xFF); - _io_iface->poke8(0x03E, 0x0F); - } break; + // LVDS Specific + _io_iface->poke8(0x03C, 0x23); + _io_iface->poke8(0x03D, 0xFF); + _io_iface->poke8(0x03E, 0x0F); + } break; - default: - throw uhd::runtime_error("[ad9361_device_t] NOT IMPLEMENTED"); + default: + throw uhd::runtime_error("[ad9361_device_t] NOT IMPLEMENTED"); } /* Data delay for TX and RX data clocks */ - digital_interface_delays_t timing = - _client_params->get_digital_interface_timing(); - uint8_t rx_delays = ((timing.rx_clk_delay & 0xF) << 4) - | (timing.rx_data_delay & 0xF); - uint8_t tx_delays = ((timing.tx_clk_delay & 0xF) << 4) - | (timing.tx_data_delay & 0xF); + digital_interface_delays_t timing = _client_params->get_digital_interface_timing(); + uint8_t rx_delays = ((timing.rx_clk_delay & 0xF) << 4) | (timing.rx_data_delay & 0xF); + uint8_t tx_delays = ((timing.tx_clk_delay & 0xF) << 4) | (timing.tx_data_delay & 0xF); _io_iface->poke8(0x006, rx_delays); _io_iface->poke8(0x007, tx_delays); @@ -1670,7 +1711,7 @@ void ad9361_device_t::initialize() _io_iface->poke8(0x036, 0xFF); /* Setup GPO */ - _io_iface->poke8(0x03a, 0x27); //set delay register + _io_iface->poke8(0x03a, 0x27); // set delay register _io_iface->poke8(0x020, 0x00); // GPO Auto Enable Setup in RX and TX _io_iface->poke8(0x027, 0x03); // GPO Manual and GPO auto value in ALERT _io_iface->poke8(0x028, 0x00); // GPO_0 RX Delay @@ -1739,16 +1780,16 @@ void ad9361_device_t::initialize() // cals done, set PPORT config switch (_client_params->get_digital_interface_mode()) { - case AD9361_DDR_FDD_LVCMOS: { - _io_iface->poke8(0x012, 0x02); - } break; + case AD9361_DDR_FDD_LVCMOS: { + _io_iface->poke8(0x012, 0x02); + } break; - case AD9361_DDR_FDD_LVDS: { - _io_iface->poke8(0x012, 0x10); - } break; + case AD9361_DDR_FDD_LVDS: { + _io_iface->poke8(0x012, 0x10); + } break; - default: - throw uhd::runtime_error("[ad9361_device_t] NOT IMPLEMENTED"); + default: + throw uhd::runtime_error("[ad9361_device_t] NOT IMPLEMENTED"); } _io_iface->poke8(0x013, 0x01); // Set ENSM FDD bit @@ -1794,7 +1835,8 @@ double ad9361_device_t::set_clock_rate(const double req_rate) std::lock_guard<std::recursive_mutex> lock(_mutex); if (req_rate > 61.44e6) { - throw uhd::runtime_error("[ad9361_device_t] Requested master clock rate outside range"); + throw uhd::runtime_error( + "[ad9361_device_t] Requested master clock rate outside range"); } UHD_LOG_TRACE("AD936X", "[ad9361_device_t::set_clock_rate] req_rate=" << req_rate); @@ -1812,21 +1854,22 @@ double ad9361_device_t::set_clock_rate(const double req_rate) * there, transition the ENSM to State 0. */ uint8_t current_state = _io_iface->peek8(0x017) & 0x0F; switch (current_state) { - case 0x05: - /* We are in the ALERT state. */ - _io_iface->poke8(0x014, 0x21); - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - _io_iface->poke8(0x014, 0x00); - break; + case 0x05: + /* We are in the ALERT state. */ + _io_iface->poke8(0x014, 0x21); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + _io_iface->poke8(0x014, 0x00); + break; - case 0x0A: - /* We are in the FDD state. */ - _io_iface->poke8(0x014, 0x00); - break; + case 0x0A: + /* We are in the FDD state. */ + _io_iface->poke8(0x014, 0x00); + break; - default: - throw uhd::runtime_error("[ad9361_device_t] [set_clock_rate:1] AD9361 in unknown state"); - break; + default: + throw uhd::runtime_error( + "[ad9361_device_t] [set_clock_rate:1] AD9361 in unknown state"); + break; }; /* Store the current chain / antenna selections so that we can restore @@ -1842,9 +1885,9 @@ double ad9361_device_t::set_clock_rate(const double req_rate) UHD_LOG_TRACE("AD936X", "[ad9361_device_t::set_clock_rate] rate=" << rate); /* Transition to the ALERT state and calibrate everything. */ - _io_iface->poke8(0x015, 0x04); //dual synth mode, synth en ctrl en - _io_iface->poke8(0x014, 0x05); //use SPI for TXNRX ctrl, to ALERT, TX on - _io_iface->poke8(0x013, 0x01); //enable ENSM + _io_iface->poke8(0x015, 0x04); // dual synth mode, synth en ctrl en + _io_iface->poke8(0x014, 0x05); // use SPI for TXNRX ctrl, to ALERT, TX on + _io_iface->poke8(0x013, 0x01); // enable ENSM std::this_thread::sleep_for(std::chrono::milliseconds(1)); _calibrate_synth_charge_pumps(); @@ -1882,38 +1925,39 @@ double ad9361_device_t::set_clock_rate(const double req_rate) switch (_client_params->get_digital_interface_mode()) { case AD9361_DDR_FDD_LVCMOS: { _io_iface->poke8(0x012, 0x02); - }break; + } break; case AD9361_DDR_FDD_LVDS: { _io_iface->poke8(0x012, 0x10); - }break; + } break; default: - throw uhd::runtime_error("[ad9361_device_t] NOT IMPLEMENTED"); + throw uhd::runtime_error("[ad9361_device_t] NOT IMPLEMENTED"); } _io_iface->poke8(0x013, 0x01); // Set ENSM FDD bit _io_iface->poke8(0x015, 0x04); // dual synth mode, synth en ctrl en /* End the function in the same state as the entry state. */ switch (current_state) { - case 0x05: - /* We are already in ALERT. */ - break; - - case 0x0A: - /* Transition back to FDD, and restore the original antenna - * / chain selections. */ - _regs.txfilt = (_regs.txfilt & 0x3F) | orig_tx_chains; - _regs.rxfilt = (_regs.rxfilt & 0x3F) | orig_rx_chains; - - _io_iface->poke8(0x002, _regs.txfilt); - _io_iface->poke8(0x003, _regs.rxfilt); - _io_iface->poke8(0x014, 0x21); - break; + case 0x05: + /* We are already in ALERT. */ + break; - default: - throw uhd::runtime_error("[ad9361_device_t] [set_clock_rate:2] AD9361 in unknown state"); - break; + case 0x0A: + /* Transition back to FDD, and restore the original antenna + * / chain selections. */ + _regs.txfilt = (_regs.txfilt & 0x3F) | orig_tx_chains; + _regs.rxfilt = (_regs.rxfilt & 0x3F) | orig_rx_chains; + + _io_iface->poke8(0x002, _regs.txfilt); + _io_iface->poke8(0x003, _regs.rxfilt); + _io_iface->poke8(0x014, 0x21); + break; + + default: + throw uhd::runtime_error( + "[ad9361_device_t] [set_clock_rate:2] AD9361 in unknown state"); + break; }; return get_clock_rate(); @@ -1967,9 +2011,9 @@ void ad9361_device_t::set_active_chains(bool tx1, bool tx2, bool rx1, bool rx2) /* Check for FDD state */ uint8_t set_back_to_fdd = 0; - uint8_t ensm_state = _io_iface->peek8(0x017) & 0x0F; - if (ensm_state == 0xA) // FDD - { + uint8_t ensm_state = _io_iface->peek8(0x017) & 0x0F; + if (ensm_state == 0xA) // FDD + { /* Put into ALERT state (via the FDD flush state). */ _io_iface->poke8(0x014, 0x01); set_back_to_fdd = 1; @@ -2003,38 +2047,42 @@ void ad9361_device_t::set_active_chains(bool tx1, bool tx2, bool rx1, bool rx2) void ad9361_device_t::set_timing_mode(const ad9361_device_t::timing_mode_t timing_mode) { switch (_client_params->get_digital_interface_mode()) { - case AD9361_DDR_FDD_LVCMOS: { - switch(timing_mode) { - case TIMING_MODE_1R1T: { - _io_iface->poke8(0x010, 0xc8); // Swap I&Q on Tx, Swap I&Q on Rx, Toggle frame sync mode - break; - } - case TIMING_MODE_2R2T: { - throw uhd::runtime_error("[ad9361_device_t] [set_timing_mode] 2R2T timing mode not supported for CMOS"); - break; - } - default: - UHD_THROW_INVALID_CODE_PATH(); - } - break; - } - case AD9361_DDR_FDD_LVDS: { - switch(timing_mode) { - case TIMING_MODE_1R1T: { - _io_iface->poke8(0x010, 0xc8); // Swap I&Q on Tx, Swap I&Q on Rx, Toggle frame sync mode, 1R1T timing. + case AD9361_DDR_FDD_LVCMOS: { + switch (timing_mode) { + case TIMING_MODE_1R1T: { + _io_iface->poke8(0x010, + 0xc8); // Swap I&Q on Tx, Swap I&Q on Rx, Toggle frame sync mode + break; + } + case TIMING_MODE_2R2T: { + throw uhd::runtime_error("[ad9361_device_t] [set_timing_mode] 2R2T " + "timing mode not supported for CMOS"); + break; + } + default: + UHD_THROW_INVALID_CODE_PATH(); + } break; } - case TIMING_MODE_2R2T: { - _io_iface->poke8(0x010, 0xcc); // Swap I&Q on Tx, Swap I&Q on Rx, Toggle frame sync mode, 2R2T timing. + case AD9361_DDR_FDD_LVDS: { + switch (timing_mode) { + case TIMING_MODE_1R1T: { + _io_iface->poke8(0x010, 0xc8); // Swap I&Q on Tx, Swap I&Q on Rx, + // Toggle frame sync mode, 1R1T timing. + break; + } + case TIMING_MODE_2R2T: { + _io_iface->poke8(0x010, 0xcc); // Swap I&Q on Tx, Swap I&Q on Rx, + // Toggle frame sync mode, 2R2T timing. + break; + } + default: + UHD_THROW_INVALID_CODE_PATH(); + } break; } default: - UHD_THROW_INVALID_CODE_PATH(); - } - break; - } - default: - throw uhd::runtime_error("[ad9361_device_t] NOT IMPLEMENTED"); + throw uhd::runtime_error("[ad9361_device_t] NOT IMPLEMENTED"); } } @@ -2138,7 +2186,6 @@ double ad9361_device_t::set_gain(direction_t direction, chain_t chain, const dou std::lock_guard<std::recursive_mutex> lock(_mutex); if (direction == RX) { - int gain_index = static_cast<int>(value); /* Clip the gain values to the proper min/max gain values. */ @@ -2169,7 +2216,7 @@ double ad9361_device_t::set_gain(direction_t direction, chain_t chain, const dou * "value" is out of bounds, so range checking must be performed * outside this function. */ - double atten = AD9361_MAX_GAIN - value; + double atten = AD9361_MAX_GAIN - value; uint32_t attenreg = uint32_t(atten * 4); if (chain == CHAIN_1) { _tx1_gain = value; @@ -2180,11 +2227,11 @@ double ad9361_device_t::set_gain(direction_t direction, chain_t chain, const dou _io_iface->poke8(0x075, attenreg & 0xFF); _io_iface->poke8(0x076, (attenreg >> 8) & 0x01); } - return AD9361_MAX_GAIN - ((double) (attenreg) / 4); + return AD9361_MAX_GAIN - ((double)(attenreg) / 4); } } -void ad9361_device_t::output_test_tone() // On RF side! +void ad9361_device_t::output_test_tone() // On RF side! { std::lock_guard<std::recursive_mutex> lock(_mutex); /* Output a 480 kHz tone at 800 MHz */ @@ -2212,19 +2259,20 @@ void ad9361_device_t::data_port_loopback(const bool loopback_enabled) * -0.25dB / bit 9bit resolution.*/ double ad9361_device_t::get_rssi(chain_t chain) { - uint32_t reg_rssi = 0; + uint32_t reg_rssi = 0; uint8_t lsb_bit_pos = 0; if (chain == CHAIN_1) { - reg_rssi = 0x1A7; + reg_rssi = 0x1A7; lsb_bit_pos = 0; - }else { - reg_rssi = 0x1A9; + } else { + reg_rssi = 0x1A9; lsb_bit_pos = 1; } uint8_t msbs = _io_iface->peek8(reg_rssi); - uint8_t lsb = ((_io_iface->peek8(0x1AB)) >> lsb_bit_pos) & 0x01; + uint8_t lsb = ((_io_iface->peek8(0x1AB)) >> lsb_bit_pos) & 0x01; uint16_t val = ((msbs << 1) | lsb); - double rssi = (-0.25f * ((double)val)); //-0.25dB/lsb (See Gain Control Users Guide p. 25) + double rssi = + (-0.25f * ((double)val)); //-0.25dB/lsb (See Gain Control Users Guide p. 25) return rssi; } @@ -2235,39 +2283,40 @@ double ad9361_device_t::get_rssi(chain_t chain) */ double ad9361_device_t::_get_temperature(const double cal_offset, const double timeout) { - //set 0x01D[0] to 1 to disable AuxADC GPIO reading + // set 0x01D[0] to 1 to disable AuxADC GPIO reading uint8_t tmp = 0; - tmp = _io_iface->peek8(0x01D); + tmp = _io_iface->peek8(0x01D); _io_iface->poke8(0x01D, (tmp | 0x01)); - _io_iface->poke8(0x00B, 0); //set offset to 0 - - _io_iface->poke8(0x00C, 0x01); //start reading, clears bit 0x00C[1] - auto end_time = - std::chrono::steady_clock::now() - + std::chrono::milliseconds(int64_t(timeout * 1000)); - //wait for valid data (toggle of bit 1 in 0x00C) - while(((_io_iface->peek8(0x00C) >> 1) & 0x01) == 0) { + _io_iface->poke8(0x00B, 0); // set offset to 0 + + _io_iface->poke8(0x00C, 0x01); // start reading, clears bit 0x00C[1] + auto end_time = std::chrono::steady_clock::now() + + std::chrono::milliseconds(int64_t(timeout * 1000)); + // wait for valid data (toggle of bit 1 in 0x00C) + while (((_io_iface->peek8(0x00C) >> 1) & 0x01) == 0) { std::this_thread::sleep_for(std::chrono::microseconds(100)); if (std::chrono::steady_clock::now() > end_time) { throw uhd::runtime_error( "[ad9361_device_t] timeout while reading temperature"); } } - _io_iface->poke8(0x00C, 0x00); //clear read flag + _io_iface->poke8(0x00C, 0x00); // clear read flag - uint8_t temp = _io_iface->peek8(0x00E); //read temperature. - double tmp_temp = temp/1.140f; //according to ADI driver - tmp_temp = tmp_temp + cal_offset; //Constant offset acquired by one point calibration. + uint8_t temp = _io_iface->peek8(0x00E); // read temperature. + double tmp_temp = temp / 1.140f; // according to ADI driver + tmp_temp = tmp_temp + cal_offset; // Constant offset acquired by one point + // calibration. return tmp_temp; } -double ad9361_device_t::get_average_temperature(const double cal_offset, const size_t num_samples) +double ad9361_device_t::get_average_temperature( + const double cal_offset, const size_t num_samples) { double d_temp = 0; - for(size_t i = 0; i < num_samples; i++) { + for (size_t i = 0; i < num_samples; i++) { double tmp_temp = _get_temperature(cal_offset); - d_temp += (tmp_temp/num_samples); + d_temp += (tmp_temp / num_samples); } return d_temp; } @@ -2289,7 +2338,8 @@ void ad9361_device_t::set_dc_offset_auto(direction_t direction, const bool on) _use_dc_offset_tracking = on; _configure_bb_dc_tracking(); } else { - throw uhd::runtime_error("[ad9361_device_t] [set_dc_offset_auto] Tx DC tracking not supported"); + throw uhd::runtime_error( + "[ad9361_device_t] [set_dc_offset_auto] Tx DC tracking not supported"); } } @@ -2312,7 +2362,8 @@ void ad9361_device_t::set_iq_balance_auto(direction_t direction, const bool on) _io_iface->poke8(0x014, 0x21); // FDD mode } } else { - throw uhd::runtime_error("[ad9361_device_t] [set_iq_balance_auto] Tx IQ tracking not supported"); + throw uhd::runtime_error( + "[ad9361_device_t] [set_iq_balance_auto] Tx IQ tracking not supported"); } } @@ -2321,41 +2372,41 @@ void ad9361_device_t::set_iq_balance_auto(direction_t direction, const bool on) * the gain configuration will be reloaded. */ void ad9361_device_t::_setup_agc(chain_t chain, gain_mode_t gain_mode) { - uint8_t gain_mode_reg = 0; - uint8_t gain_mode_prev = 0; + uint8_t gain_mode_reg = 0; + uint8_t gain_mode_prev = 0; uint8_t gain_mode_bits_pos = 0; - gain_mode_reg = _io_iface->peek8(0x0FA); + gain_mode_reg = _io_iface->peek8(0x0FA); gain_mode_prev = (gain_mode_reg & 0x0F); if (chain == CHAIN_1) { gain_mode_bits_pos = 0; } else if (chain == CHAIN_2) { gain_mode_bits_pos = 2; - } else - { + } else { throw uhd::runtime_error("[ad9361_device_t] Wrong value for chain"); } - gain_mode_reg = (gain_mode_reg & (~(0x03<<gain_mode_bits_pos))); //clear mode bits + gain_mode_reg = (gain_mode_reg & (~(0x03 << gain_mode_bits_pos))); // clear mode bits switch (gain_mode) { case GAIN_MODE_MANUAL: - //leave bits cleared + // leave bits cleared break; case GAIN_MODE_SLOW_AGC: - gain_mode_reg = (gain_mode_reg | (0x02<<gain_mode_bits_pos)); + gain_mode_reg = (gain_mode_reg | (0x02 << gain_mode_bits_pos)); break; case GAIN_MODE_FAST_AGC: - gain_mode_reg = (gain_mode_reg | (0x01<<gain_mode_bits_pos)); + gain_mode_reg = (gain_mode_reg | (0x01 << gain_mode_bits_pos)); break; default: throw uhd::runtime_error("[ad9361_device_t] Gain mode does not exist"); } _io_iface->poke8(0x0FA, gain_mode_reg); uint8_t gain_mode_status = _io_iface->peek8(0x0FA); - gain_mode_status = (gain_mode_status & 0x0F); + gain_mode_status = (gain_mode_status & 0x0F); /*Check if gain mode configuration needs to be reprogrammed*/ - if (((gain_mode_prev == 0) && (gain_mode_status != 0)) || ((gain_mode_prev != 0) && (gain_mode_status == 0))) { + if (((gain_mode_prev == 0) && (gain_mode_status != 0)) + || ((gain_mode_prev != 0) && (gain_mode_status == 0))) { if (gain_mode_status == 0) { /*load manual mode config*/ _setup_gain_control(false); @@ -2368,50 +2419,45 @@ void ad9361_device_t::_setup_agc(chain_t chain, gain_mode_t gain_mode) void ad9361_device_t::set_agc(chain_t chain, bool enable) { - if(chain == CHAIN_1) { + if (chain == CHAIN_1) { _rx1_agc_enable = enable; - if(enable) { + if (enable) { _setup_agc(chain, _rx1_agc_mode); } else { _setup_agc(chain, GAIN_MODE_MANUAL); } - } else if (chain == CHAIN_2){ + } else if (chain == CHAIN_2) { _rx2_agc_enable = enable; - if(enable) { + if (enable) { _setup_agc(chain, _rx2_agc_mode); } else { _setup_agc(chain, GAIN_MODE_MANUAL); } - } else - { + } else { throw uhd::runtime_error("[ad9361_device_t] Wrong value for chain"); } } void ad9361_device_t::set_agc_mode(chain_t chain, gain_mode_t gain_mode) { - if(chain == CHAIN_1) { + if (chain == CHAIN_1) { _rx1_agc_mode = gain_mode; - if(_rx1_agc_enable) { + if (_rx1_agc_enable) { _setup_agc(chain, _rx1_agc_mode); } - } else if(chain == CHAIN_2){ + } else if (chain == CHAIN_2) { _rx2_agc_mode = gain_mode; - if(_rx2_agc_enable) { + if (_rx2_agc_enable) { _setup_agc(chain, _rx2_agc_mode); } - } else - { + } else { throw uhd::runtime_error("[ad9361_device_t] Wrong value for chain"); } } std::vector<std::string> ad9361_device_t::get_filter_names(direction_t direction) { - auto& filters = (direction == RX) - ? _rx_filters - : _tx_filters - ; + auto& filters = (direction == RX) ? _rx_filters : _tx_filters; std::vector<std::string> ret; ret.reserve(filters.size()); @@ -2423,68 +2469,53 @@ std::vector<std::string> ad9361_device_t::get_filter_names(direction_t direction } filter_info_base::sptr ad9361_device_t::get_filter( - direction_t direction, - chain_t chain, - const std::string &name -) { - auto& filters = (direction == RX) - ? _rx_filters - : _tx_filters - ; + direction_t direction, chain_t chain, const std::string& name) +{ + auto& filters = (direction == RX) ? _rx_filters : _tx_filters; if (!filters.count(name)) { throw uhd::runtime_error( - "ad9361_device_t::get_filter this filter does not exist: " + name - ); + "ad9361_device_t::get_filter this filter does not exist: " + name); } // Check entry 0 in the tuple (the getter) exists before calling it if (!std::get<0>(filters[name])) { throw uhd::runtime_error( - "ad9361_device_t::get_filter this filter can not be read: " + name - ); + "ad9361_device_t::get_filter this filter can not be read: " + name); } return std::get<0>(filters[name])(chain); } -void ad9361_device_t::set_filter( - direction_t direction, - chain_t chain, - const std::string &name, - filter_info_base::sptr filter -) { - auto& filters = (direction == RX) - ? _rx_filters - : _tx_filters - ; +void ad9361_device_t::set_filter(direction_t direction, + chain_t chain, + const std::string& name, + filter_info_base::sptr filter) +{ + auto& filters = (direction == RX) ? _rx_filters : _tx_filters; if (!filters.count(name)) { throw uhd::runtime_error( - "ad9361_device_t::set_filter this filter does not exist: " + name - ); + "ad9361_device_t::set_filter this filter does not exist: " + name); } // Check entry 1 in the tuple (the setter) exists before calling it if (!std::get<1>(filters[name])) { throw uhd::runtime_error( - "ad9361_device_t::set_filter this filter can not be written: " + - name - ); + "ad9361_device_t::set_filter this filter can not be written: " + name); } std::get<1>(filters[name])(chain, filter); } double ad9361_device_t::set_bw_filter(direction_t direction, const double rf_bw) { - //both low pass filters are programmed to the same bw. However, their cutoffs will differ. - //Together they should create the requested bb bw. - //Select rf_bw if it is between AD9361_MIN_BW & AD9361_MAX_BW. + // both low pass filters are programmed to the same bw. However, their cutoffs will + // differ. Together they should create the requested bb bw. Select rf_bw if it is + // between AD9361_MIN_BW & AD9361_MAX_BW. const double clipped_bw = std::min(std::max(rf_bw, AD9361_MIN_BW), AD9361_MAX_BW); - if(direction == RX) - { - _rx_bb_lp_bw = _calibrate_baseband_rx_analog_filter(clipped_bw); //returns bb bw + if (direction == RX) { + _rx_bb_lp_bw = _calibrate_baseband_rx_analog_filter(clipped_bw); // returns bb bw _rx_tia_lp_bw = _calibrate_rx_TIAs(clipped_bw); _rx_analog_bw = clipped_bw; } else { - _tx_bb_lp_bw = _calibrate_baseband_tx_analog_filter(clipped_bw); //returns bb bw + _tx_bb_lp_bw = _calibrate_baseband_tx_analog_filter(clipped_bw); // returns bb bw _tx_sec_lp_bw = _calibrate_secondary_tx_filter(clipped_bw); _tx_analog_bw = clipped_bw; } @@ -2492,20 +2523,20 @@ double ad9361_device_t::set_bw_filter(direction_t direction, const double rf_bw) return (clipped_bw); } -void ad9361_device_t::_set_fir_taps(direction_t direction, chain_t chain, const std::vector<int16_t>& taps) +void ad9361_device_t::_set_fir_taps( + direction_t direction, chain_t chain, const std::vector<int16_t>& taps) { - size_t num_taps = taps.size(); + size_t num_taps = taps.size(); size_t num_taps_avail = _get_num_fir_taps(direction); - if(num_taps == num_taps_avail) - { + if (num_taps == num_taps_avail) { boost::scoped_array<uint16_t> coeffs(new uint16_t[num_taps_avail]); - for (size_t i = 0; i < num_taps_avail; i++) - { + for (size_t i = 0; i < num_taps_avail; i++) { coeffs[i] = uint16_t(taps[i]); } _program_fir_filter(direction, chain, num_taps_avail, coeffs.get()); - } else if(num_taps < num_taps_avail){ - throw uhd::runtime_error("ad9361_device_t::_set_fir_taps not enough coefficients."); + } else if (num_taps < num_taps_avail) { + throw uhd::runtime_error( + "ad9361_device_t::_set_fir_taps not enough coefficients."); } else { throw uhd::runtime_error("ad9361_device_t::_set_fir_taps too many coefficients."); } @@ -2514,7 +2545,7 @@ void ad9361_device_t::_set_fir_taps(direction_t direction, chain_t chain, const size_t ad9361_device_t::_get_num_fir_taps(direction_t direction) { uint8_t num = 0; - if(direction == RX) + if (direction == RX) num = _io_iface->peek8(0x0F5); else num = _io_iface->peek8(0x065); @@ -2525,7 +2556,7 @@ size_t ad9361_device_t::_get_num_fir_taps(direction_t direction) size_t ad9361_device_t::_get_fir_dec_int(direction_t direction) { uint8_t dec_int = 0; - if(direction == RX) + if (direction == RX) dec_int = _io_iface->peek8(0x003); else dec_int = _io_iface->peek8(0x002); @@ -2535,8 +2566,7 @@ size_t ad9361_device_t::_get_fir_dec_int(direction_t direction) * 2 = dec/int by 2 * 3 = dec/int by 4 */ dec_int = (dec_int & 0x03); - if(dec_int == 3) - { + if (dec_int == 3) { return 4; } return dec_int; @@ -2548,41 +2578,39 @@ std::vector<int16_t> ad9361_device_t::_get_fir_taps(direction_t direction, chain size_t num_taps = _get_num_fir_taps(direction); uint8_t config; uint8_t reg_numtaps = (((num_taps / 16) - 1) & 0x07) << 5; - config = reg_numtaps | 0x02; //start the programming clock + config = reg_numtaps | 0x02; // start the programming clock - if(chain == CHAIN_1) - { + if (chain == CHAIN_1) { config = config | (1 << 3); - } else if (chain == CHAIN_2){ + } else if (chain == CHAIN_2) { config = config | (1 << 4); } else { - throw uhd::runtime_error("[ad9361_device_t] Can not read both chains synchronously"); + throw uhd::runtime_error( + "[ad9361_device_t] Can not read both chains synchronously"); } - if(direction == RX) - { + if (direction == RX) { base = 0xF0; } else { base = 0x60; } - _io_iface->poke8(base+5,config); + _io_iface->poke8(base + 5, config); std::vector<int16_t> taps; uint8_t lower_val; uint8_t higher_val; uint16_t coeff; - for(size_t i = 0;i < num_taps;i++) - { - _io_iface->poke8(base,0x00+i); - lower_val = _io_iface->peek8(base+3); - higher_val = _io_iface->peek8(base+4); - coeff = ((higher_val << 8) | lower_val); + for (size_t i = 0; i < num_taps; i++) { + _io_iface->poke8(base, 0x00 + i); + lower_val = _io_iface->peek8(base + 3); + higher_val = _io_iface->peek8(base + 4); + coeff = ((higher_val << 8) | lower_val); taps.push_back(int16_t(coeff)); } - config = (config & (~(1 << 1))); //disable filter clock - _io_iface->poke8(base+5,config); + config = (config & (~(1 << 1))); // disable filter clock + _io_iface->poke8(base + 5, config); return taps; } @@ -2594,15 +2622,15 @@ filter_info_base::sptr ad9361_device_t::_get_filter_lp_tia_sec(direction_t direc { double cutoff = 0; - if(direction == RX) - { - cutoff = 2.5 * _rx_tia_lp_bw; + if (direction == RX) { + cutoff = 2.5 * _rx_tia_lp_bw; } else { - cutoff = 5 * _tx_sec_lp_bw; + cutoff = 5 * _tx_sec_lp_bw; } - filter_info_base::sptr lp(new analog_filter_lp(filter_info_base::ANALOG_LOW_PASS, false, 0, "single-pole", cutoff, 20)); - return lp; + filter_info_base::sptr lp(new analog_filter_lp( + filter_info_base::ANALOG_LOW_PASS, false, 0, "single-pole", cutoff, 20)); + return lp; } /* @@ -2611,15 +2639,19 @@ filter_info_base::sptr ad9361_device_t::_get_filter_lp_tia_sec(direction_t direc filter_info_base::sptr ad9361_device_t::_get_filter_lp_bb(direction_t direction) { double cutoff = 0; - if(direction == RX) - { + if (direction == RX) { cutoff = 1.4 * _rx_bb_lp_bw; } else { cutoff = 1.6 * _tx_bb_lp_bw; } - filter_info_base::sptr bb_lp(new analog_filter_lp(filter_info_base::ANALOG_LOW_PASS, false, 1, "third-order Butterworth", cutoff, 60)); - return bb_lp; + filter_info_base::sptr bb_lp(new analog_filter_lp(filter_info_base::ANALOG_LOW_PASS, + false, + 1, + "third-order Butterworth", + cutoff, + 60)); + return bb_lp; } /* @@ -2642,227 +2674,272 @@ filter_info_base::sptr ad9361_device_t::_get_filter_dec_int_3(direction_t direct filter_info_base::sptr ret; - if(direction == RX) - { + if (direction == RX) { full_scale = 16384; - dec = 3; - interpol = 1; + dec = 3; + interpol = 1; enable = _io_iface->peek8(0x003); enable = ((enable >> 4) & 0x03); - taps.assign(taps_array_rx, taps_array_rx + sizeof(taps_array_rx) / sizeof(int16_t) ); + taps.assign( + taps_array_rx, taps_array_rx + sizeof(taps_array_rx) / sizeof(int16_t)); } else { full_scale = 8192; - dec = 1; - interpol = 3; + dec = 1; + interpol = 3; uint8_t use_dac_clk_div = _io_iface->peek8(0x00A); - use_dac_clk_div = ((use_dac_clk_div >> 3) & 0x01); - if(use_dac_clk_div == 1) - { + use_dac_clk_div = ((use_dac_clk_div >> 3) & 0x01); + if (use_dac_clk_div == 1) { rate = rate / 2; } enable = _io_iface->peek8(0x002); enable = ((enable >> 4) & 0x03); - if(enable == 2) //0 => int. by 1, 1 => int. by 2 (HB3), 2 => int. by 3 + if (enable == 2) // 0 => int. by 1, 1 => int. by 2 (HB3), 2 => int. by 3 { rate /= 3; } - taps.assign(taps_array_tx, taps_array_tx + sizeof(taps_array_tx) / sizeof(int16_t) ); + taps.assign( + taps_array_tx, taps_array_tx + sizeof(taps_array_tx) / sizeof(int16_t)); } - ret = filter_info_base::sptr(new digital_filter_base<int16_t>(type, (enable != 2) ? true : false, 2, rate, interpol, dec, full_scale, taps.size(), taps)); - return ret; + ret = filter_info_base::sptr(new digital_filter_base<int16_t>(type, + (enable != 2) ? true : false, + 2, + rate, + interpol, + dec, + full_scale, + taps.size(), + taps)); + return ret; } filter_info_base::sptr ad9361_device_t::_get_filter_hb_3(direction_t direction) { - uint8_t enable = 0; - double rate = _adcclock_freq; - double full_scale = 0; - size_t dec = 1; - size_t interpol = 1; + uint8_t enable = 0; + double rate = _adcclock_freq; + double full_scale = 0; + size_t dec = 1; + size_t interpol = 1; filter_info_base::filter_type type = filter_info_base::DIGITAL_I16; - int16_t taps_array_rx[] = {1, 4, 6, 4, 1}; - int16_t taps_array_tx[] = {1, 2, 1}; + int16_t taps_array_rx[] = {1, 4, 6, 4, 1}; + int16_t taps_array_tx[] = {1, 2, 1}; std::vector<int16_t> taps; - if(direction == RX) - { + if (direction == RX) { full_scale = 16; - dec = 2; + dec = 2; enable = _io_iface->peek8(0x003); enable = ((enable >> 4) & 0x03); - taps.assign(taps_array_rx, taps_array_rx + sizeof(taps_array_rx) / sizeof(int16_t) ); + taps.assign( + taps_array_rx, taps_array_rx + sizeof(taps_array_rx) / sizeof(int16_t)); } else { full_scale = 2; - interpol = 2; + interpol = 2; uint8_t use_dac_clk_div = _io_iface->peek8(0x00A); - use_dac_clk_div = ((use_dac_clk_div >> 3) & 0x01); - if(use_dac_clk_div == 1) - { + use_dac_clk_div = ((use_dac_clk_div >> 3) & 0x01); + if (use_dac_clk_div == 1) { rate = rate / 2; } enable = _io_iface->peek8(0x002); enable = ((enable >> 4) & 0x03); - if(enable == 1) - { + if (enable == 1) { rate /= 2; } - taps.assign(taps_array_tx, taps_array_tx + sizeof(taps_array_tx) / sizeof(int16_t) ); + taps.assign( + taps_array_tx, taps_array_tx + sizeof(taps_array_tx) / sizeof(int16_t)); } - filter_info_base::sptr hb = filter_info_base::sptr(new digital_filter_base<int16_t>(type, (enable != 1) ? true : false, 2, rate, interpol, dec, full_scale, taps.size(), taps)); - return hb; + filter_info_base::sptr hb = + filter_info_base::sptr(new digital_filter_base<int16_t>(type, + (enable != 1) ? true : false, + 2, + rate, + interpol, + dec, + full_scale, + taps.size(), + taps)); + return hb; } filter_info_base::sptr ad9361_device_t::_get_filter_hb_2(direction_t direction) { - uint8_t enable = 0; - double rate = _adcclock_freq; - double full_scale = 0; - size_t dec = 1; - size_t interpol = 1; + uint8_t enable = 0; + double rate = _adcclock_freq; + double full_scale = 0; + size_t dec = 1; + size_t interpol = 1; filter_info_base::filter_type type = filter_info_base::DIGITAL_I16; - int16_t taps_array[] = {-9, 0, 73, 128, 73, 0, -9}; - std::vector<int16_t> taps(taps_array, taps_array + sizeof(taps_array) / sizeof(int16_t) ); + int16_t taps_array[] = {-9, 0, 73, 128, 73, 0, -9}; + std::vector<int16_t> taps( + taps_array, taps_array + sizeof(taps_array) / sizeof(int16_t)); - digital_filter_base<int16_t>::sptr hb_3 = std::dynamic_pointer_cast<digital_filter_base<int16_t> >(_get_filter_hb_3(direction)); - digital_filter_base<int16_t>::sptr dec_int_3 = std::dynamic_pointer_cast<digital_filter_base<int16_t> >(_get_filter_dec_int_3(direction)); + digital_filter_base<int16_t>::sptr hb_3 = + std::dynamic_pointer_cast<digital_filter_base<int16_t>>( + _get_filter_hb_3(direction)); + digital_filter_base<int16_t>::sptr dec_int_3 = + std::dynamic_pointer_cast<digital_filter_base<int16_t>>( + _get_filter_dec_int_3(direction)); - if(direction == RX) - { + if (direction == RX) { full_scale = 256; - dec = 2; - enable = _io_iface->peek8(0x003); + dec = 2; + enable = _io_iface->peek8(0x003); } else { full_scale = 128; - interpol = 2; - enable = _io_iface->peek8(0x002); + interpol = 2; + enable = _io_iface->peek8(0x002); } enable = ((enable >> 3) & 0x01); - if(!(hb_3->is_bypassed())) - { - if(direction == RX) - { + if (!(hb_3->is_bypassed())) { + if (direction == RX) { rate = hb_3->get_output_rate(); - }else if (direction == TX) { + } else if (direction == TX) { rate = hb_3->get_input_rate(); - if(enable) - { + if (enable) { rate /= 2; } } - } else { //else dec3/int3 or none of them is used. - if(direction == RX) - { + } else { // else dec3/int3 or none of them is used. + if (direction == RX) { rate = dec_int_3->get_output_rate(); - }else if (direction == TX) { + } else if (direction == TX) { rate = dec_int_3->get_input_rate(); - if(enable) - { + if (enable) { rate /= 2; } } } - filter_info_base::sptr hb(new digital_filter_base<int16_t>(type, (enable == 0) ? true : false, 3, rate, interpol, dec, full_scale, taps.size(), taps)); - return hb; + filter_info_base::sptr hb(new digital_filter_base<int16_t>(type, + (enable == 0) ? true : false, + 3, + rate, + interpol, + dec, + full_scale, + taps.size(), + taps)); + return hb; } filter_info_base::sptr ad9361_device_t::_get_filter_hb_1(direction_t direction) { - uint8_t enable = 0; - double rate = 0; - double full_scale = 0; - size_t dec = 1; - size_t interpol = 1; + uint8_t enable = 0; + double rate = 0; + double full_scale = 0; + size_t dec = 1; + size_t interpol = 1; filter_info_base::filter_type type = filter_info_base::DIGITAL_I16; std::vector<int16_t> taps; - int16_t taps_rx_array[] = {-8, 0, 42, 0, -147, 0, 619, 1013, 619, 0, -147, 0, 42, 0, -8}; - int16_t taps_tx_array[] = {-53, 0, 313, 0, -1155, 0, 4989, 8192, 4989, 0, -1155, 0, 313, 0, -53}; + int16_t taps_rx_array[] = { + -8, 0, 42, 0, -147, 0, 619, 1013, 619, 0, -147, 0, 42, 0, -8}; + int16_t taps_tx_array[] = { + -53, 0, 313, 0, -1155, 0, 4989, 8192, 4989, 0, -1155, 0, 313, 0, -53}; - digital_filter_base<int16_t>::sptr hb_2 = std::dynamic_pointer_cast<digital_filter_base<int16_t> >(_get_filter_hb_2(direction)); + digital_filter_base<int16_t>::sptr hb_2 = + std::dynamic_pointer_cast<digital_filter_base<int16_t>>( + _get_filter_hb_2(direction)); - if(direction == RX) - { + if (direction == RX) { full_scale = 2048; - dec = 2; - enable = _io_iface->peek8(0x003); - enable = ((enable >> 2) & 0x01); - rate = hb_2->get_output_rate(); - taps.assign(taps_rx_array, taps_rx_array + sizeof(taps_rx_array) / sizeof(int16_t) ); + dec = 2; + enable = _io_iface->peek8(0x003); + enable = ((enable >> 2) & 0x01); + rate = hb_2->get_output_rate(); + taps.assign( + taps_rx_array, taps_rx_array + sizeof(taps_rx_array) / sizeof(int16_t)); } else if (direction == TX) { full_scale = 8192; - interpol = 2; - enable = _io_iface->peek8(0x002); - enable = ((enable >> 2) & 0x01); - rate = hb_2->get_input_rate(); - if(enable) - { + interpol = 2; + enable = _io_iface->peek8(0x002); + enable = ((enable >> 2) & 0x01); + rate = hb_2->get_input_rate(); + if (enable) { rate /= 2; } - taps.assign(taps_tx_array, taps_tx_array + sizeof(taps_tx_array) / sizeof(int16_t) ); + taps.assign( + taps_tx_array, taps_tx_array + sizeof(taps_tx_array) / sizeof(int16_t)); } - filter_info_base::sptr hb(new digital_filter_base<int16_t>(type, (enable == 0) ? true : false, 4, rate, interpol, dec, full_scale, taps.size(), taps)); - return hb; + filter_info_base::sptr hb(new digital_filter_base<int16_t>(type, + (enable == 0) ? true : false, + 4, + rate, + interpol, + dec, + full_scale, + taps.size(), + taps)); + return hb; } -filter_info_base::sptr ad9361_device_t::_get_filter_fir(direction_t direction, chain_t chain) +filter_info_base::sptr ad9361_device_t::_get_filter_fir( + direction_t direction, chain_t chain) { - double rate = 0; - size_t dec = 1; - size_t interpol = 1; + double rate = 0; + size_t dec = 1; + size_t interpol = 1; size_t max_num_taps = 128; - uint8_t enable = 1; + uint8_t enable = 1; - digital_filter_base<int16_t>::sptr hb_1 = std::dynamic_pointer_cast<digital_filter_base<int16_t> >(_get_filter_hb_1(direction)); + digital_filter_base<int16_t>::sptr hb_1 = + std::dynamic_pointer_cast<digital_filter_base<int16_t>>( + _get_filter_hb_1(direction)); - if(direction == RX) - { + if (direction == RX) { dec = _get_fir_dec_int(direction); - if(dec == 0) - { + if (dec == 0) { enable = 0; - dec = 1; + dec = 1; } interpol = 1; - rate = hb_1->get_output_rate(); - }else if (direction == TX) { + rate = hb_1->get_output_rate(); + } else if (direction == TX) { interpol = _get_fir_dec_int(direction); - if(interpol == 0) - { - enable = 0; + if (interpol == 0) { + enable = 0; interpol = 1; } - dec = 1; + dec = 1; rate = hb_1->get_input_rate(); - if(enable) - { + if (enable) { rate /= interpol; } } max_num_taps = _get_num_fir_taps(direction); - filter_info_base::sptr fir(new digital_filter_fir<int16_t>(filter_info_base::DIGITAL_FIR_I16, (enable == 0) ? true : false, 5, rate, interpol, dec, 32767, max_num_taps, _get_fir_taps(direction, chain))); + filter_info_base::sptr fir( + new digital_filter_fir<int16_t>(filter_info_base::DIGITAL_FIR_I16, + (enable == 0) ? true : false, + 5, + rate, + interpol, + dec, + 32767, + max_num_taps, + _get_fir_taps(direction, chain))); return fir; } -void ad9361_device_t::_set_filter_fir(direction_t direction, chain_t channel, filter_info_base::sptr filter) +void ad9361_device_t::_set_filter_fir( + direction_t direction, chain_t channel, filter_info_base::sptr filter) { - digital_filter_fir<int16_t>::sptr fir = std::dynamic_pointer_cast<digital_filter_fir<int16_t> >(filter); - //only write taps. Ignore everything else for now + digital_filter_fir<int16_t>::sptr fir = + std::dynamic_pointer_cast<digital_filter_fir<int16_t>>(filter); + // only write taps. Ignore everything else for now _set_fir_taps(direction, channel, fir->get_taps()); } @@ -2871,34 +2948,39 @@ void ad9361_device_t::_set_filter_fir(direction_t direction, chain_t channel, fi * _tx_analog_bw and _rx_analog_bw are not valid any more! * For useful data in those variables set_bw_filter method should be used */ -void ad9361_device_t::_set_filter_lp_bb(direction_t direction, filter_info_base::sptr filter) +void ad9361_device_t::_set_filter_lp_bb( + direction_t direction, filter_info_base::sptr filter) { analog_filter_lp::sptr lpf = std::dynamic_pointer_cast<analog_filter_lp>(filter); - double bw = lpf->get_cutoff(); - if(direction == RX) - { - //remember: this function takes rf bw as its input and calibrated to 1.4 x the given value - _rx_bb_lp_bw = _calibrate_baseband_rx_analog_filter(2 * bw / 1.4); //returns bb bw + double bw = lpf->get_cutoff(); + if (direction == RX) { + // remember: this function takes rf bw as its input and calibrated to 1.4 x the + // given value + _rx_bb_lp_bw = _calibrate_baseband_rx_analog_filter(2 * bw / 1.4); // returns bb + // bw } else { - //remember: this function takes rf bw as its input and calibrates to 1.6 x the given value + // remember: this function takes rf bw as its input and calibrates to 1.6 x the + // given value _tx_bb_lp_bw = _calibrate_baseband_tx_analog_filter(2 * bw / 1.6); } } -void ad9361_device_t::_set_filter_lp_tia_sec(direction_t direction, filter_info_base::sptr filter) +void ad9361_device_t::_set_filter_lp_tia_sec( + direction_t direction, filter_info_base::sptr filter) { analog_filter_lp::sptr lpf = std::dynamic_pointer_cast<analog_filter_lp>(filter); - double bw = lpf->get_cutoff(); - if(direction == RX) - { - //remember: this function takes rf bw as its input and calibrated to 2.5 x the given value - _rx_tia_lp_bw = _calibrate_rx_TIAs(2 * bw / 2.5); //returns bb bw + double bw = lpf->get_cutoff(); + if (direction == RX) { + // remember: this function takes rf bw as its input and calibrated to 2.5 x the + // given value + _rx_tia_lp_bw = _calibrate_rx_TIAs(2 * bw / 2.5); // returns bb bw } else { - //remember: this function takes rf bw as its input and calibrates to 5 x the given value + // remember: this function takes rf bw as its input and calibrates to 5 x the + // given value _tx_sec_lp_bw = _calibrate_secondary_tx_filter(2 * bw / 5); } } -}} +}} // namespace uhd::usrp diff --git a/host/lib/usrp/common/ad936x_manager.cpp b/host/lib/usrp/common/ad936x_manager.cpp index b57b94302..9646f0427 100644 --- a/host/lib/usrp/common/ad936x_manager.cpp +++ b/host/lib/usrp/common/ad936x_manager.cpp @@ -8,9 +8,9 @@ #include <uhd/utils/log.hpp> #include <uhdlib/usrp/common/ad936x_manager.hpp> #include <boost/functional/hash.hpp> -#include <memory> #include <chrono> #include <cmath> +#include <memory> #include <thread> using namespace uhd; diff --git a/host/lib/usrp/common/adf4001_ctrl.cpp b/host/lib/usrp/common/adf4001_ctrl.cpp index 85a13455f..a9f3c1fdb 100644 --- a/host/lib/usrp/common/adf4001_ctrl.cpp +++ b/host/lib/usrp/common/adf4001_ctrl.cpp @@ -10,71 +10,72 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhdlib/usrp/common/adf4001_ctrl.hpp> #include <uhd/utils/log.hpp> - -#include <iostream> +#include <uhdlib/usrp/common/adf4001_ctrl.hpp> #include <iomanip> +#include <iostream> using namespace uhd; using namespace uhd::usrp; -adf4001_regs_t::adf4001_regs_t(void) { - ref_counter = 0; - n = 0; - charge_pump_current_1 = 0; - charge_pump_current_2 = 0; - anti_backlash_width = ANTI_BACKLASH_WIDTH_2_9NS; - lock_detect_precision = LOCK_DETECT_PRECISION_3CYC; - charge_pump_gain = CHARGE_PUMP_GAIN_1; - counter_reset = COUNTER_RESET_NORMAL; - power_down = POWER_DOWN_NORMAL; - muxout = MUXOUT_TRISTATE_OUT; +adf4001_regs_t::adf4001_regs_t(void) +{ + ref_counter = 0; + n = 0; + charge_pump_current_1 = 0; + charge_pump_current_2 = 0; + anti_backlash_width = ANTI_BACKLASH_WIDTH_2_9NS; + lock_detect_precision = LOCK_DETECT_PRECISION_3CYC; + charge_pump_gain = CHARGE_PUMP_GAIN_1; + counter_reset = COUNTER_RESET_NORMAL; + power_down = POWER_DOWN_NORMAL; + muxout = MUXOUT_TRISTATE_OUT; phase_detector_polarity = PHASE_DETECTOR_POLARITY_NEGATIVE; - charge_pump_mode = CHARGE_PUMP_TRISTATE; - fastlock_mode = FASTLOCK_MODE_DISABLED; - timer_counter_control = TIMEOUT_3CYC; + charge_pump_mode = CHARGE_PUMP_TRISTATE; + fastlock_mode = FASTLOCK_MODE_DISABLED; + timer_counter_control = TIMEOUT_3CYC; } -uint32_t adf4001_regs_t::get_reg(uint8_t addr) { +uint32_t adf4001_regs_t::get_reg(uint8_t addr) +{ uint32_t reg = 0; switch (addr) { - case 0: - reg |= (uint32_t(ref_counter) & 0x003FFF) << 2; - reg |= (uint32_t(anti_backlash_width) & 0x000003) << 16; - reg |= (uint32_t(lock_detect_precision) & 0x000001) << 20; - break; - case 1: - reg |= (uint32_t(n) & 0x001FFF) << 8; - reg |= (uint32_t(charge_pump_gain) & 0x000001) << 21; - break; - case 2: - reg |= (uint32_t(counter_reset) & 0x000001) << 2; - reg |= (uint32_t(power_down) & 0x000001) << 3; - reg |= (uint32_t(muxout) & 0x000007) << 4; - reg |= (uint32_t(phase_detector_polarity) & 0x000001) << 7; - reg |= (uint32_t(charge_pump_mode) & 0x000001) << 8; - reg |= (uint32_t(fastlock_mode) & 0x000003) << 9; - reg |= (uint32_t(timer_counter_control) & 0x00000F) << 11; - reg |= (uint32_t(charge_pump_current_1) & 0x000007) << 15; - reg |= (uint32_t(charge_pump_current_2) & 0x000007) << 18; - reg |= (uint32_t(power_down) & 0x000002) << 20; - break; - case 3: - reg |= (uint32_t(counter_reset) & 0x000001) << 2; - reg |= (uint32_t(power_down) & 0x000001) << 3; - reg |= (uint32_t(muxout) & 0x000007) << 4; - reg |= (uint32_t(phase_detector_polarity) & 0x000001) << 7; - reg |= (uint32_t(charge_pump_mode) & 0x000001) << 8; - reg |= (uint32_t(fastlock_mode) & 0x000003) << 9; - reg |= (uint32_t(timer_counter_control) & 0x00000F) << 11; - reg |= (uint32_t(charge_pump_current_1) & 0x000007) << 15; - reg |= (uint32_t(charge_pump_current_2) & 0x000007) << 18; - reg |= (uint32_t(power_down) & 0x000002) << 20; - break; - default: - break; + case 0: + reg |= (uint32_t(ref_counter) & 0x003FFF) << 2; + reg |= (uint32_t(anti_backlash_width) & 0x000003) << 16; + reg |= (uint32_t(lock_detect_precision) & 0x000001) << 20; + break; + case 1: + reg |= (uint32_t(n) & 0x001FFF) << 8; + reg |= (uint32_t(charge_pump_gain) & 0x000001) << 21; + break; + case 2: + reg |= (uint32_t(counter_reset) & 0x000001) << 2; + reg |= (uint32_t(power_down) & 0x000001) << 3; + reg |= (uint32_t(muxout) & 0x000007) << 4; + reg |= (uint32_t(phase_detector_polarity) & 0x000001) << 7; + reg |= (uint32_t(charge_pump_mode) & 0x000001) << 8; + reg |= (uint32_t(fastlock_mode) & 0x000003) << 9; + reg |= (uint32_t(timer_counter_control) & 0x00000F) << 11; + reg |= (uint32_t(charge_pump_current_1) & 0x000007) << 15; + reg |= (uint32_t(charge_pump_current_2) & 0x000007) << 18; + reg |= (uint32_t(power_down) & 0x000002) << 20; + break; + case 3: + reg |= (uint32_t(counter_reset) & 0x000001) << 2; + reg |= (uint32_t(power_down) & 0x000001) << 3; + reg |= (uint32_t(muxout) & 0x000007) << 4; + reg |= (uint32_t(phase_detector_polarity) & 0x000001) << 7; + reg |= (uint32_t(charge_pump_mode) & 0x000001) << 8; + reg |= (uint32_t(fastlock_mode) & 0x000003) << 9; + reg |= (uint32_t(timer_counter_control) & 0x00000F) << 11; + reg |= (uint32_t(charge_pump_current_1) & 0x000007) << 15; + reg |= (uint32_t(charge_pump_current_2) & 0x000007) << 18; + reg |= (uint32_t(power_down) & 0x000002) << 20; + break; + default: + break; } reg |= (uint32_t(addr) & 0x03); @@ -83,30 +84,30 @@ uint32_t adf4001_regs_t::get_reg(uint8_t addr) { } -adf4001_ctrl::adf4001_ctrl(uhd::spi_iface::sptr _spi, int slaveno): - spi_iface(_spi), - slaveno(slaveno) - { - +adf4001_ctrl::adf4001_ctrl(uhd::spi_iface::sptr _spi, int slaveno) + : spi_iface(_spi), slaveno(slaveno) +{ spi_config.mosi_edge = spi_config_t::EDGE_RISE; - //set defaults - adf4001_regs.ref_counter = 1; - adf4001_regs.n = 4; + // set defaults + adf4001_regs.ref_counter = 1; + adf4001_regs.n = 4; adf4001_regs.charge_pump_current_1 = 7; adf4001_regs.charge_pump_current_2 = 7; - adf4001_regs.muxout = adf4001_regs_t::MUXOUT_DLD; - adf4001_regs.counter_reset = adf4001_regs_t::COUNTER_RESET_NORMAL; - adf4001_regs.phase_detector_polarity = adf4001_regs_t::PHASE_DETECTOR_POLARITY_POSITIVE; + adf4001_regs.muxout = adf4001_regs_t::MUXOUT_DLD; + adf4001_regs.counter_reset = adf4001_regs_t::COUNTER_RESET_NORMAL; + adf4001_regs.phase_detector_polarity = + adf4001_regs_t::PHASE_DETECTOR_POLARITY_POSITIVE; adf4001_regs.charge_pump_mode = adf4001_regs_t::CHARGE_PUMP_TRISTATE; - //everything else should be defaults + // everything else should be defaults program_regs(); } -void adf4001_ctrl::set_lock_to_ext_ref(bool external) { - if(external) { +void adf4001_ctrl::set_lock_to_ext_ref(bool external) +{ + if (external) { adf4001_regs.charge_pump_mode = adf4001_regs_t::CHARGE_PUMP_NORMAL; } else { adf4001_regs.charge_pump_mode = adf4001_regs_t::CHARGE_PUMP_TRISTATE; @@ -115,27 +116,25 @@ void adf4001_ctrl::set_lock_to_ext_ref(bool external) { program_regs(); } -void adf4001_ctrl::program_regs(void) { - //no control over CE, only LE, therefore we use the initialization latch method +void adf4001_ctrl::program_regs(void) +{ + // no control over CE, only LE, therefore we use the initialization latch method write_reg(3); - //conduct a function latch (2) + // conduct a function latch (2) write_reg(2); - //write R counter latch (0) + // write R counter latch (0) write_reg(0); - //write N counter latch (1) + // write N counter latch (1) write_reg(1); } -void adf4001_ctrl::write_reg(uint8_t addr) { - uint32_t reg = adf4001_regs.get_reg(addr); //load the reg data +void adf4001_ctrl::write_reg(uint8_t addr) +{ + uint32_t reg = adf4001_regs.get_reg(addr); // load the reg data - spi_iface->transact_spi(slaveno, - spi_config, - reg, - 24, - false); + spi_iface->transact_spi(slaveno, spi_config, reg, 24, false); } diff --git a/host/lib/usrp/common/adf435x.cpp b/host/lib/usrp/common/adf435x.cpp index 6d59befaa..4b5f9ac7e 100644 --- a/host/lib/usrp/common/adf435x.cpp +++ b/host/lib/usrp/common/adf435x.cpp @@ -9,9 +9,7 @@ using namespace uhd; -adf435x_iface::~adf435x_iface() -{ -} +adf435x_iface::~adf435x_iface() {} adf435x_iface::sptr adf435x_iface::make_adf4350(write_fn_t write) { diff --git a/host/lib/usrp/common/apply_corrections.cpp b/host/lib/usrp/common/apply_corrections.cpp index b57ace71b..b75ab7d95 100644 --- a/host/lib/usrp/common/apply_corrections.cpp +++ b/host/lib/usrp/common/apply_corrections.cpp @@ -5,16 +5,16 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhdlib/usrp/common/apply_corrections.hpp> +#include <uhd/types/dict.hpp> #include <uhd/usrp/dboard_eeprom.hpp> -#include <uhd/utils/paths.hpp> -#include <uhd/utils/log.hpp> #include <uhd/utils/csv.hpp> -#include <uhd/types/dict.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/paths.hpp> +#include <uhdlib/usrp/common/apply_corrections.hpp> #include <boost/filesystem.hpp> #include <boost/thread/mutex.hpp> -#include <cstdio> #include <complex> +#include <cstdio> #include <fstream> namespace fs = boost::filesystem; @@ -24,24 +24,27 @@ boost::mutex corrections_mutex; /*********************************************************************** * Helper routines **********************************************************************/ -static double linear_interp(double x, double x0, double y0, double x1, double y1){ - return y0 + (x - x0)*(y1 - y0)/(x1 - x0); +static double linear_interp(double x, double x0, double y0, double x1, double y1) +{ + return y0 + (x - x0) * (y1 - y0) / (x1 - x0); } /*********************************************************************** * FE apply corrections implementation **********************************************************************/ -struct fe_cal_t{ +struct fe_cal_t +{ double lo_freq; double iq_corr_real; double iq_corr_imag; }; -static bool fe_cal_comp(fe_cal_t a, fe_cal_t b){ +static bool fe_cal_comp(fe_cal_t a, fe_cal_t b) +{ return (a.lo_freq < b.lo_freq); } -static uhd::dict<std::string, std::vector<fe_cal_t> > fe_cal_cache; +static uhd::dict<std::string, std::vector<fe_cal_t>> fe_cal_cache; static bool is_same_freq(const double f1, const double f2) { @@ -50,36 +53,46 @@ static bool is_same_freq(const double f1, const double f2) } static std::complex<double> get_fe_correction( - const std::string &key, const double lo_freq -){ - const std::vector<fe_cal_t> &datas = fe_cal_cache[key]; - if (datas.empty()) throw uhd::runtime_error("empty calibration table " + key); + const std::string& key, const double lo_freq) +{ + const std::vector<fe_cal_t>& datas = fe_cal_cache[key]; + if (datas.empty()) + throw uhd::runtime_error("empty calibration table " + key); - //search for lo freq + // search for lo freq size_t lo_index = 0; - size_t hi_index = datas.size()-1; - for (size_t i = 0; i < datas.size(); i++){ - if (is_same_freq(datas[i].lo_freq, lo_freq)) - { + size_t hi_index = datas.size() - 1; + for (size_t i = 0; i < datas.size(); i++) { + if (is_same_freq(datas[i].lo_freq, lo_freq)) { hi_index = i; lo_index = i; break; } - if (datas[i].lo_freq > lo_freq){ + if (datas[i].lo_freq > lo_freq) { hi_index = i; break; } lo_index = i; } - if (lo_index == 0) return std::complex<double>(datas[lo_index].iq_corr_real, datas[lo_index].iq_corr_imag); - if (hi_index == lo_index) return std::complex<double>(datas[hi_index].iq_corr_real, datas[hi_index].iq_corr_imag); - - //interpolation time - return std::complex<double>( - linear_interp(lo_freq, datas[lo_index].lo_freq, datas[lo_index].iq_corr_real, datas[hi_index].lo_freq, datas[hi_index].iq_corr_real), - linear_interp(lo_freq, datas[lo_index].lo_freq, datas[lo_index].iq_corr_imag, datas[hi_index].lo_freq, datas[hi_index].iq_corr_imag) - ); + if (lo_index == 0) + return std::complex<double>( + datas[lo_index].iq_corr_real, datas[lo_index].iq_corr_imag); + if (hi_index == lo_index) + return std::complex<double>( + datas[hi_index].iq_corr_real, datas[hi_index].iq_corr_imag); + + // interpolation time + return std::complex<double>(linear_interp(lo_freq, + datas[lo_index].lo_freq, + datas[lo_index].iq_corr_real, + datas[hi_index].lo_freq, + datas[hi_index].iq_corr_real), + linear_interp(lo_freq, + datas[lo_index].lo_freq, + datas[lo_index].iq_corr_imag, + datas[hi_index].lo_freq, + datas[hi_index].iq_corr_imag)); } static void apply_fe_corrections(uhd::property_tree::sptr sub_tree, @@ -88,43 +101,45 @@ static void apply_fe_corrections(uhd::property_tree::sptr sub_tree, const std::string& file_prefix, const double lo_freq) { - //make the calibration file path + // make the calibration file path const fs::path cal_data_path = fs::path(uhd::get_app_path()) / ".uhd" / "cal" / (file_prefix + db_serial + ".csv"); - if (not fs::exists(cal_data_path)) return; + if (not fs::exists(cal_data_path)) + return; - //parse csv file or get from cache - if (not fe_cal_cache.has_key(cal_data_path.string())){ + // parse csv file or get from cache + if (not fe_cal_cache.has_key(cal_data_path.string())) { std::ifstream cal_data(cal_data_path.string().c_str()); const uhd::csv::rows_type rows = uhd::csv::to_rows(cal_data); - bool read_data = false, skip_next = false;; + bool read_data = false, skip_next = false; + ; std::vector<fe_cal_t> datas; - for(const uhd::csv::row_type &row: rows){ - if (not read_data and not row.empty() and row[0] == "DATA STARTS HERE"){ + for (const uhd::csv::row_type& row : rows) { + if (not read_data and not row.empty() and row[0] == "DATA STARTS HERE") { read_data = true; skip_next = true; continue; } - if (not read_data) continue; - if (skip_next){ + if (not read_data) + continue; + if (skip_next) { skip_next = false; continue; } fe_cal_t data; - std::sscanf(row[0].c_str(), "%lf" , &data.lo_freq); - std::sscanf(row[1].c_str(), "%lf" , &data.iq_corr_real); - std::sscanf(row[2].c_str(), "%lf" , &data.iq_corr_imag); + std::sscanf(row[0].c_str(), "%lf", &data.lo_freq); + std::sscanf(row[1].c_str(), "%lf", &data.iq_corr_real); + std::sscanf(row[2].c_str(), "%lf", &data.iq_corr_imag); datas.push_back(data); } std::sort(datas.begin(), datas.end(), fe_cal_comp); fe_cal_cache[cal_data_path.string()] = datas; UHD_LOGGER_INFO("CAL") << "Calibration data loaded: " << cal_data_path.string(); - } - sub_tree->access<std::complex<double> >(fe_path) - .set(get_fe_correction(cal_data_path.string(), lo_freq)); + sub_tree->access<std::complex<double>>(fe_path).set( + get_fe_correction(cal_data_path.string(), lo_freq)); } /*********************************************************************** @@ -139,7 +154,7 @@ void uhd::usrp::apply_tx_fe_corrections( // overloading to work according to rfn ) { boost::mutex::scoped_lock l(corrections_mutex); - try{ + try { apply_fe_corrections(sub_tree, db_serial, tx_fe_corr_path + "/iq_balance/value", @@ -150,17 +165,17 @@ void uhd::usrp::apply_tx_fe_corrections( // overloading to work according to rfn tx_fe_corr_path + "/dc_offset/value", "tx_dc_cal_v0.2_", lo_freq); - } - catch(const std::exception &e){ + } catch (const std::exception& e) { UHD_LOGGER_ERROR("CAL") << "Failure in apply_tx_fe_corrections: " << e.what(); } } void uhd::usrp::apply_tx_fe_corrections( - property_tree::sptr sub_tree, //starts at mboards/x - const std::string &slot, //name of dboard slot - const double lo_freq //actual lo freq -){ + property_tree::sptr sub_tree, // starts at mboards/x + const std::string& slot, // name of dboard slot + const double lo_freq // actual lo freq +) +{ boost::mutex::scoped_lock l(corrections_mutex); // extract eeprom serial @@ -168,7 +183,7 @@ void uhd::usrp::apply_tx_fe_corrections( const std::string db_serial = sub_tree->access<uhd::usrp::dboard_eeprom_t>(db_path).get().serial; - try{ + try { apply_fe_corrections(sub_tree, db_serial, "tx_frontends/" + slot + "/iq_balance/value", @@ -179,8 +194,7 @@ void uhd::usrp::apply_tx_fe_corrections( "tx_frontends/" + slot + "/dc_offset/value", "tx_dc_cal_v0.2_", lo_freq); - } - catch(const std::exception &e){ + } catch (const std::exception& e) { UHD_LOGGER_ERROR("CAL") << "Failure in apply_tx_fe_corrections: " << e.what(); } } @@ -194,35 +208,34 @@ void uhd::usrp::apply_rx_fe_corrections( // overloading to work according to rfn ) { boost::mutex::scoped_lock l(corrections_mutex); - try{ + try { apply_fe_corrections(sub_tree, db_serial, rx_fe_corr_path + "/iq_balance/value", "rx_iq_cal_v0.2_", lo_freq); - } - catch(const std::exception &e){ + } catch (const std::exception& e) { UHD_LOGGER_ERROR("CAL") << "Failure in apply_tx_fe_corrections: " << e.what(); } } void uhd::usrp::apply_rx_fe_corrections( - property_tree::sptr sub_tree, //starts at mboards/x - const std::string &slot, //name of dboard slot - const double lo_freq //actual lo freq -){ + property_tree::sptr sub_tree, // starts at mboards/x + const std::string& slot, // name of dboard slot + const double lo_freq // actual lo freq +) +{ boost::mutex::scoped_lock l(corrections_mutex); const uhd::fs_path db_path = "dboards/" + slot + "/rx_eeprom"; const std::string db_serial = sub_tree->access<uhd::usrp::dboard_eeprom_t>(db_path).get().serial; - try{ + try { apply_fe_corrections(sub_tree, db_serial, "rx_frontends/" + slot + "/iq_balance/value", "rx_iq_cal_v0.2_", lo_freq); - } - catch(const std::exception &e){ + } catch (const std::exception& e) { UHD_LOGGER_ERROR("CAL") << "Failure in apply_rx_fe_corrections: " << e.what(); } } diff --git a/host/lib/usrp/common/fx2_ctrl.cpp b/host/lib/usrp/common/fx2_ctrl.cpp index 77501d981..cbb108dae 100644 --- a/host/lib/usrp/common/fx2_ctrl.cpp +++ b/host/lib/usrp/common/fx2_ctrl.cpp @@ -5,19 +5,19 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhdlib/usrp/common/fx2_ctrl.hpp> -#include <uhd/utils/log.hpp> #include <uhd/exception.hpp> #include <uhd/transport/usb_control.hpp> -#include <boost/functional/hash.hpp> +#include <uhd/utils/log.hpp> +#include <uhdlib/usrp/common/fx2_ctrl.hpp> #include <stdint.h> +#include <boost/functional/hash.hpp> +#include <chrono> +#include <cstring> #include <fstream> #include <sstream> #include <string> -#include <vector> -#include <cstring> -#include <chrono> #include <thread> +#include <vector> using namespace uhd; using namespace uhd::usrp; @@ -37,10 +37,10 @@ typedef uint32_t hash_type; * \param filename file used to generate hash value * \return hash value in a size_t type */ -static hash_type generate_hash(const char *filename) +static hash_type generate_hash(const char* filename) { std::ifstream file(filename); - if (not file){ + if (not file) { throw uhd::io_error(std::string("cannot open input file ") + filename); } @@ -51,7 +51,7 @@ static hash_type generate_hash(const char *filename) boost::hash_combine(hash, ch); } - if (not file.eof()){ + if (not file.eof()) { throw uhd::io_error(std::string("file error ") + filename); } @@ -65,9 +65,8 @@ static hash_type generate_hash(const char *filename) * \param record a line from an Intel HEX file * \return true if record is valid, false otherwise */ -static bool checksum(std::string *record) +static bool checksum(std::string* record) { - size_t len = record->length(); unsigned int i; unsigned char sum = 0; @@ -79,9 +78,9 @@ static bool checksum(std::string *record) } if (sum == 0) - return true; + return true; else - return false; + return false; } @@ -95,9 +94,11 @@ static bool checksum(std::string *record) * \param data output data * \return true if record is sucessfully read, false on error */ -bool parse_record(std::string *record, unsigned int &len, - unsigned int &addr, unsigned int &type, - unsigned char* data) +bool parse_record(std::string* record, + unsigned int& len, + unsigned int& addr, + unsigned int& type, + unsigned char* data) { unsigned int i; std::string _data; @@ -110,12 +111,12 @@ bool parse_record(std::string *record, unsigned int &len, std::istringstream(record->substr(3, 4)) >> std::hex >> addr; std::istringstream(record->substr(7, 2)) >> std::hex >> type; - if (len > (2 * (record->length() - 9))) // sanity check to prevent buffer overrun + if (len > (2 * (record->length() - 9))) // sanity check to prevent buffer overrun return false; for (i = 0; i < len; i++) { std::istringstream(record->substr(9 + 2 * i, 2)) >> std::hex >> val; - data[i] = (unsigned char) val; + data[i] = (unsigned char)val; } return true; @@ -125,33 +126,37 @@ bool parse_record(std::string *record, unsigned int &len, /*! * USRP control implementation for device discovery and configuration */ -class fx2_ctrl_impl : public fx2_ctrl { +class fx2_ctrl_impl : public fx2_ctrl +{ public: fx2_ctrl_impl(uhd::transport::usb_control::sptr ctrl_transport) { _ctrl_transport = ctrl_transport; } - void usrp_fx2_reset(void){ + void usrp_fx2_reset(void) + { unsigned char reset_y = 1; unsigned char reset_n = 0; usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_y, 1); usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_n, 1); - //wait for things to settle + // wait for things to settle std::this_thread::sleep_for(std::chrono::milliseconds(2000)); } void usrp_load_firmware(std::string filestring, bool force) { - const char *filename = filestring.c_str(); + const char* filename = filestring.c_str(); hash_type hash = generate_hash(filename); - hash_type loaded_hash; usrp_get_firmware_hash(loaded_hash); + hash_type loaded_hash; + usrp_get_firmware_hash(loaded_hash); - if (not force and (hash == loaded_hash)) return; + if (not force and (hash == loaded_hash)) + return; - //FIXME: verify types + // FIXME: verify types unsigned int len; unsigned int addr; unsigned int type; @@ -167,54 +172,59 @@ public: unsigned char reset_y = 1; unsigned char reset_n = 0; - //hit the reset line - if (load_img_msg) UHD_LOGGER_INFO("FX2") << "Loading firmware image: " << filestring << "..."; + // hit the reset line + if (load_img_msg) + UHD_LOGGER_INFO("FX2") << "Loading firmware image: " << filestring << "..."; usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_y, 1); while (!file.eof()) { - std::string record; - file >> record; + std::string record; + file >> record; if (!(record.length() > 0)) continue; - //check for valid record - if (not checksum(&record) or not parse_record(&record, len, addr, type, data)) { + // check for valid record + if (not checksum(&record) + or not parse_record(&record, len, addr, type, data)) { throw uhd::io_error("usrp_load_firmware: bad record checksum"); } - //type 0x00 is data + // type 0x00 is data if (type == 0x00) { int ret = usrp_control_write(FX2_FIRMWARE_LOAD, addr, 0, data, len); - if (ret < 0) throw uhd::io_error("usrp_load_firmware: usrp_control_write failed"); + if (ret < 0) + throw uhd::io_error("usrp_load_firmware: usrp_control_write failed"); } - //type 0x01 is end + // type 0x01 is end else if (type == 0x01) { - usrp_set_firmware_hash(hash); //set hash before reset + usrp_set_firmware_hash(hash); // set hash before reset usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_n, 1); file.close(); - //wait for things to settle + // wait for things to settle std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - if (load_img_msg) UHD_LOGGER_INFO("FX2") << "Firmware loaded"; + if (load_img_msg) + UHD_LOGGER_INFO("FX2") << "Firmware loaded"; return; } - //type anything else is unhandled + // type anything else is unhandled else { throw uhd::io_error("usrp_load_firmware: unsupported record"); } } - //file did not end + // file did not end throw uhd::io_error("usrp_load_firmware: bad record"); } - void usrp_init(void){ - //disable + void usrp_init(void) + { + // disable usrp_rx_enable(false); usrp_tx_enable(false); - //toggle resets + // toggle resets usrp_rx_reset(true); usrp_tx_reset(true); usrp_rx_reset(false); @@ -223,33 +233,37 @@ public: void usrp_load_fpga(std::string filestring) { - const char *filename = filestring.c_str(); + const char* filename = filestring.c_str(); hash_type hash = generate_hash(filename); - hash_type loaded_hash; usrp_get_fpga_hash(loaded_hash); + hash_type loaded_hash; + usrp_get_fpga_hash(loaded_hash); - if (hash == loaded_hash) return; + if (hash == loaded_hash) + return; const int ep0_size = 64; unsigned char buf[ep0_size]; - if (load_img_msg) UHD_LOGGER_INFO("FX2") << "Loading FPGA image: " << filestring << "..."; + if (load_img_msg) + UHD_LOGGER_INFO("FX2") << "Loading FPGA image: " << filestring << "..."; std::ifstream file; file.open(filename, std::ios::in | std::ios::binary); if (not file.good()) { throw uhd::io_error("usrp_load_fpga: cannot open fpga input file"); } - usrp_fpga_reset(true); //holding the fpga in reset while loading + usrp_fpga_reset(true); // holding the fpga in reset while loading if (usrp_control_write_cmd(VRQ_FPGA_LOAD, 0, FL_BEGIN) < 0) { throw uhd::io_error("usrp_load_fpga: fpga load error"); } while (not file.eof()) { - file.read((char *)buf, sizeof(buf)); + file.read((char*)buf, sizeof(buf)); const std::streamsize n = file.gcount(); - if(n == 0) continue; + if (n == 0) + continue; int ret = usrp_control_write(VRQ_FPGA_LOAD, 0, FL_XFER, buf, uint16_t(n)); if (ret < 0 or std::streamsize(ret) != n) { throw uhd::io_error("usrp_load_fpga: fpga load error"); @@ -262,16 +276,18 @@ public: usrp_set_fpga_hash(hash); - usrp_fpga_reset(false); //done loading, take fpga out of reset + usrp_fpga_reset(false); // done loading, take fpga out of reset file.close(); - if (load_img_msg) UHD_LOGGER_INFO("FX2") << "FPGA image loaded"; + if (load_img_msg) + UHD_LOGGER_INFO("FX2") << "FPGA image loaded"; } void usrp_load_eeprom(std::string filestring) { - if (load_img_msg) UHD_LOGGER_INFO("FX2") << "Loading EEPROM image: " << filestring << "..."; - const char *filename = filestring.c_str(); + if (load_img_msg) + UHD_LOGGER_INFO("FX2") << "Loading EEPROM image: " << filestring << "..."; + const char* filename = filestring.c_str(); const uint16_t i2c_addr = 0x50; unsigned int addr; @@ -285,19 +301,20 @@ public: throw uhd::io_error("usrp_load_eeprom: cannot open EEPROM input file"); } - file.read((char *)data, 256); + file.read((char*)data, 256); std::streamsize len = file.gcount(); - if(len == 256) { + if (len == 256) { throw uhd::io_error("usrp_load_eeprom: image size too large"); } const int pagesize = 16; - addr = 0; - while(len > 0) { + addr = 0; + while (len > 0) { sendbuf[0] = addr; - memcpy(sendbuf+1, &data[addr], len > pagesize ? pagesize : size_t(len)); - int ret = usrp_i2c_write(i2c_addr, sendbuf, (len > pagesize ? pagesize : size_t(len))+1); + memcpy(sendbuf + 1, &data[addr], len > pagesize ? pagesize : size_t(len)); + int ret = usrp_i2c_write( + i2c_addr, sendbuf, (len > pagesize ? pagesize : size_t(len)) + 1); if (ret < 0) { throw uhd::io_error("usrp_load_eeprom: usrp_i2c_write failed"); } @@ -306,7 +323,8 @@ public: std::this_thread::sleep_for(std::chrono::milliseconds(100)); } file.close(); - if (load_img_msg) UHD_LOGGER_INFO("FX2") << "EEPROM image loaded"; + if (load_img_msg) + UHD_LOGGER_INFO("FX2") << "EEPROM image loaded"; } @@ -316,32 +334,39 @@ public: } - void usrp_get_firmware_hash(hash_type &hash) + void usrp_get_firmware_hash(hash_type& hash) { - UHD_ASSERT_THROW(usrp_control_read(0xa0, USRP_HASH_SLOT_0_ADDR, 0, - (unsigned char*) &hash, sizeof(hash)) >= 0); + UHD_ASSERT_THROW( + usrp_control_read( + 0xa0, USRP_HASH_SLOT_0_ADDR, 0, (unsigned char*)&hash, sizeof(hash)) + >= 0); } void usrp_set_firmware_hash(hash_type hash) { - UHD_ASSERT_THROW(usrp_control_write(0xa0, USRP_HASH_SLOT_0_ADDR, 0, - (unsigned char*) &hash, sizeof(hash)) >= 0); - + UHD_ASSERT_THROW( + usrp_control_write( + 0xa0, USRP_HASH_SLOT_0_ADDR, 0, (unsigned char*)&hash, sizeof(hash)) + >= 0); } - void usrp_get_fpga_hash(hash_type &hash) + void usrp_get_fpga_hash(hash_type& hash) { - UHD_ASSERT_THROW(usrp_control_read(0xa0, USRP_HASH_SLOT_1_ADDR, 0, - (unsigned char*) &hash, sizeof(hash)) >= 0); + UHD_ASSERT_THROW( + usrp_control_read( + 0xa0, USRP_HASH_SLOT_1_ADDR, 0, (unsigned char*)&hash, sizeof(hash)) + >= 0); } void usrp_set_fpga_hash(hash_type hash) { - UHD_ASSERT_THROW(usrp_control_write(0xa0, USRP_HASH_SLOT_1_ADDR, 0, - (unsigned char*) &hash, sizeof(hash)) >= 0); + UHD_ASSERT_THROW( + usrp_control_write( + 0xa0, USRP_HASH_SLOT_1_ADDR, 0, (unsigned char*)&hash, sizeof(hash)) + >= 0); } void usrp_tx_enable(bool on) @@ -373,32 +398,32 @@ public: } int usrp_control_write(uint8_t request, - uint16_t value, - uint16_t index, - unsigned char *buff, - uint16_t length) + uint16_t value, + uint16_t index, + unsigned char* buff, + uint16_t length) { - return _ctrl_transport->submit(VRT_VENDOR_OUT, // bmReqeustType - request, // bRequest - value, // wValue - index, // wIndex - buff, // data - length); // wLength + return _ctrl_transport->submit(VRT_VENDOR_OUT, // bmReqeustType + request, // bRequest + value, // wValue + index, // wIndex + buff, // data + length); // wLength } int usrp_control_read(uint8_t request, - uint16_t value, - uint16_t index, - unsigned char *buff, - uint16_t length) + uint16_t value, + uint16_t index, + unsigned char* buff, + uint16_t length) { - return _ctrl_transport->submit(VRT_VENDOR_IN, // bmReqeustType - request, // bRequest - value, // wValue - index, // wIndex - buff, // data - length); // wLength + return _ctrl_transport->submit(VRT_VENDOR_IN, // bmReqeustType + request, // bRequest + value, // wValue + index, // wIndex + buff, // data + length); // wLength } @@ -407,33 +432,31 @@ public: return usrp_control_write(request, value, index, 0, 0); } - byte_vector_t read_eeprom( - uint16_t addr, - uint16_t offset, - size_t num_bytes - ){ + byte_vector_t read_eeprom(uint16_t addr, uint16_t offset, size_t num_bytes) + { this->write_i2c(addr, byte_vector_t(1, uint8_t(offset))); return this->read_i2c(addr, num_bytes); } - int usrp_i2c_write(uint16_t i2c_addr, unsigned char *buf, uint16_t len) + int usrp_i2c_write(uint16_t i2c_addr, unsigned char* buf, uint16_t len) { return usrp_control_write(VRQ_I2C_WRITE, i2c_addr, 0, buf, len); } - int usrp_i2c_read(uint16_t i2c_addr, unsigned char *buf, uint16_t len) + int usrp_i2c_read(uint16_t i2c_addr, unsigned char* buf, uint16_t len) { return usrp_control_read(VRQ_I2C_READ, i2c_addr, 0, buf, len); } - static const bool iface_debug = false; + static const bool iface_debug = false; static const size_t max_i2c_data_bytes = 64; - void write_i2c(uint16_t addr, const byte_vector_t &bytes) + void write_i2c(uint16_t addr, const byte_vector_t& bytes) { UHD_ASSERT_THROW(bytes.size() < max_i2c_data_bytes); - int ret = this->usrp_i2c_write(addr, (unsigned char *)&bytes.front(), bytes.size()); + int ret = + this->usrp_i2c_write(addr, (unsigned char*)&bytes.front(), bytes.size()); if (iface_debug && (ret < 0)) uhd::runtime_error("USRP: failed i2c write"); @@ -441,15 +464,15 @@ public: byte_vector_t read_i2c(uint16_t addr, size_t num_bytes) { - UHD_ASSERT_THROW(num_bytes < max_i2c_data_bytes); + UHD_ASSERT_THROW(num_bytes < max_i2c_data_bytes); - byte_vector_t bytes(num_bytes); - int ret = this->usrp_i2c_read(addr, (unsigned char *)&bytes.front(), num_bytes); + byte_vector_t bytes(num_bytes); + int ret = this->usrp_i2c_read(addr, (unsigned char*)&bytes.front(), num_bytes); - if (iface_debug && ((ret < 0) || (unsigned)ret < (num_bytes))) - uhd::runtime_error("USRP: failed i2c read"); + if (iface_debug && ((ret < 0) || (unsigned)ret < (num_bytes))) + uhd::runtime_error("USRP: failed i2c read"); - return bytes; + return bytes; } @@ -460,7 +483,7 @@ private: /*********************************************************************** * Public make function for fx2_ctrl interface **********************************************************************/ -fx2_ctrl::sptr fx2_ctrl::make(uhd::transport::usb_control::sptr ctrl_transport){ +fx2_ctrl::sptr fx2_ctrl::make(uhd::transport::usb_control::sptr ctrl_transport) +{ return sptr(new fx2_ctrl_impl(ctrl_transport)); } - diff --git a/host/lib/usrp/common/io_service_args.cpp b/host/lib/usrp/common/io_service_args.cpp index 8a55b8ee0..8be1ff89b 100644 --- a/host/lib/usrp/common/io_service_args.cpp +++ b/host/lib/usrp/common/io_service_args.cpp @@ -58,16 +58,18 @@ io_service_args_t read_io_service_args( io_service_args_t io_srv_args; std::string tmp_str, default_str; - io_srv_args.recv_offload = get_bool_arg(args, recv_offload_str, defaults.recv_offload); - io_srv_args.send_offload = get_bool_arg(args, send_offload_str, defaults.send_offload); + io_srv_args.recv_offload = + get_bool_arg(args, recv_offload_str, defaults.recv_offload); + io_srv_args.send_offload = + get_bool_arg(args, send_offload_str, defaults.send_offload); io_srv_args.recv_offload_wait_mode = get_wait_mode_arg( args, recv_offload_wait_mode_str, defaults.recv_offload_wait_mode); io_srv_args.send_offload_wait_mode = get_wait_mode_arg( args, send_offload_wait_mode_str, defaults.send_offload_wait_mode); - io_srv_args.num_poll_offload_threads = - args.cast<size_t>(num_poll_offload_threads_str, defaults.num_poll_offload_threads); + io_srv_args.num_poll_offload_threads = args.cast<size_t>( + num_poll_offload_threads_str, defaults.num_poll_offload_threads); if (io_srv_args.num_poll_offload_threads == 0) { UHD_LOG_WARNING(LOG_ID, "Invalid value for num_poll_offload_threads. " @@ -75,7 +77,8 @@ io_service_args_t read_io_service_args( io_srv_args.num_poll_offload_threads = 1; } - auto read_thread_args = [&args](const std::regex& expr, std::map<size_t, size_t>& dest) { + auto read_thread_args = [&args]( + const std::regex& expr, std::map<size_t, size_t>& dest) { auto keys = args.keys(); for (const auto& key : keys) { std::smatch match; diff --git a/host/lib/usrp/common/io_service_mgr.cpp b/host/lib/usrp/common/io_service_mgr.cpp index 19c06a826..e30fa422d 100644 --- a/host/lib/usrp/common/io_service_mgr.cpp +++ b/host/lib/usrp/common/io_service_mgr.cpp @@ -40,8 +40,8 @@ namespace uhd { namespace usrp { class inline_io_service_mgr { public: - io_service::sptr connect_links(recv_link_if::sptr recv_link, - send_link_if::sptr send_link); + io_service::sptr connect_links( + recv_link_if::sptr recv_link, send_link_if::sptr send_link); void disconnect_links(recv_link_if::sptr recv_link, send_link_if::sptr send_link); @@ -56,8 +56,8 @@ private: std::map<link_pair_t, link_info_t> _link_info_map; }; -io_service::sptr inline_io_service_mgr::connect_links(recv_link_if::sptr recv_link, - send_link_if::sptr send_link) +io_service::sptr inline_io_service_mgr::connect_links( + recv_link_if::sptr recv_link, send_link_if::sptr send_link) { // Check if links are already connected const link_pair_t links{recv_link, send_link}; @@ -421,12 +421,7 @@ public: void disconnect_links(recv_link_if::sptr recv_link, send_link_if::sptr send_link); private: - enum io_service_type_t - { - INLINE_IO_SRV, - BLOCKING_IO_SRV, - POLLING_IO_SRV - }; + enum io_service_type_t { INLINE_IO_SRV, BLOCKING_IO_SRV, POLLING_IO_SRV }; struct xport_args_t { bool offload = false; @@ -463,7 +458,8 @@ io_service_mgr::sptr io_service_mgr::make(const uhd::device_addr_t& args) #ifdef HAVE_DPDK return std::make_shared<dpdk_io_service_mgr_impl>(); #else - UHD_LOG_WARNING(LOG_ID, "Cannot instantiate DPDK I/O service. Proceeding with regular I/O service."); + UHD_LOG_WARNING(LOG_ID, + "Cannot instantiate DPDK I/O service. Proceeding with regular I/O service."); #endif } return std::make_shared<io_service_mgr_impl>(args); @@ -485,8 +481,8 @@ io_service::sptr io_service_mgr_impl::connect_links(recv_link_if::sptr recv_link default_args.send_offload = false; } - const io_service_args_t args = read_io_service_args( - merge_io_service_dev_args(_args, stream_args), default_args); + const io_service_args_t args = + read_io_service_args(merge_io_service_dev_args(_args, stream_args), default_args); // Check if the links are already attached to an I/O service. If they are, // then use the same manager to connect, since links can only be connected @@ -528,7 +524,8 @@ io_service::sptr io_service_mgr_impl::connect_links(recv_link_if::sptr recv_link // the inline I/O service. Warn if a different one was requested. if (!_out_of_order_supported(recv_link, send_link)) { if (io_srv_type != INLINE_IO_SRV) { - UHD_LOG_WARNING(LOG_ID, "Link type does not support send/recv offload, ignoring"); + UHD_LOG_WARNING( + LOG_ID, "Link type does not support send/recv offload, ignoring"); } io_srv_type = INLINE_IO_SRV; } diff --git a/host/lib/usrp/common/lmx2592.cpp b/host/lib/usrp/common/lmx2592.cpp index e6ffdfbfb..e1c85c05f 100644 --- a/host/lib/usrp/common/lmx2592.cpp +++ b/host/lib/usrp/common/lmx2592.cpp @@ -80,12 +80,17 @@ enum intermediate_frequency_t { FRF_IN, }; -const char* log_intermediate_frequency(intermediate_frequency_t inter) { +const char* log_intermediate_frequency(intermediate_frequency_t inter) +{ switch (inter) { - case FRF_IN: return "FRF_IN"; - case FVCO: return "FVCO"; - case FLO: return "FLO"; - default: return "???"; + case FRF_IN: + return "FRF_IN"; + case FVCO: + return "FVCO"; + case FLO: + return "FLO"; + default: + return "???"; } } @@ -98,30 +103,30 @@ inline bool abs_less_than_compare(const double a, const double b) typedef std::pair<double, intermediate_frequency_t> offset_t; // comparator that uses absolute value on the first value of an offset_t -inline bool offset_abs_less_than_compare( - const offset_t a, - const offset_t b) +inline bool offset_abs_less_than_compare(const offset_t a, const offset_t b) { return std::abs(a.first) < std::abs(b.first); } -} +} // namespace -class lmx2592_impl : public lmx2592_iface { +class lmx2592_impl : public lmx2592_iface +{ public: explicit lmx2592_impl(write_spi_t write_fn, read_spi_t read_fn) : _write_fn([write_fn](const uint8_t addr, const uint16_t data) { - const uint32_t spi_transaction = - 0 | ((addr & SPI_ADDR_MASK) << SPI_ADDR_SHIFT) | data; - write_fn(spi_transaction); - }), - _read_fn([read_fn](const uint8_t addr) { - const uint32_t spi_transaction = - SPI_READ_FLAG | ((addr & SPI_ADDR_MASK) << SPI_ADDR_SHIFT); - return read_fn(spi_transaction); - }), - _regs(), - _rewrite_regs(true) { + const uint32_t spi_transaction = + 0 | ((addr & SPI_ADDR_MASK) << SPI_ADDR_SHIFT) | data; + write_fn(spi_transaction); + }) + , _read_fn([read_fn](const uint8_t addr) { + const uint32_t spi_transaction = SPI_READ_FLAG + | ((addr & SPI_ADDR_MASK) << SPI_ADDR_SHIFT); + return read_fn(spi_transaction); + }) + , _regs() + , _rewrite_regs(true) + { UHD_LOG_TRACE("LMX2592", "Initializing Synthesizer"); // Soft Reset @@ -133,16 +138,16 @@ public: _regs.reset = 0; // Set register values where driver defaults differ from the datasheet values - _regs.acal_enable = 0; - _regs.fcal_enable = 0; - _regs.cal_clk_div = 0; - _regs.vco_idac_ovr = 1; - _regs.cp_idn = 12; - _regs.cp_iup = 12; - _regs.vco_idac = 350; + _regs.acal_enable = 0; + _regs.fcal_enable = 0; + _regs.cal_clk_div = 0; + _regs.vco_idac_ovr = 1; + _regs.cp_idn = 12; + _regs.cp_iup = 12; + _regs.vco_idac = 350; _regs.mash_ditherer = 1; - _regs.outa_mux = lmx2592_regs_t::outa_mux_t::OUTA_MUX_VCO; - _regs.fcal_fast = 1; + _regs.outa_mux = lmx2592_regs_t::outa_mux_t::OUTA_MUX_VCO; + _regs.fcal_fast = 1; // Write default register values, ensures register copy is synchronized _rewrite_regs = true; @@ -152,13 +157,15 @@ public: commit(); } - ~lmx2592_impl() override { UHD_SAFE_CALL(_regs.powerdown = 1; commit();) } + ~lmx2592_impl() override + { + UHD_SAFE_CALL(_regs.powerdown = 1; commit();) + } - double set_frequency( - const double target_freq, + double set_frequency(const double target_freq, const bool spur_dodging = false, - const double spur_dodging_threshold = DEFAULT_LMX2592_SPUR_DODGING_THRESHOLD) - override + const double spur_dodging_threshold = + DEFAULT_LMX2592_SPUR_DODGING_THRESHOLD) override { // Enforce LMX frequency limits if (target_freq < LMX2592_MIN_OUT_FREQ or target_freq > LMX2592_MAX_OUT_FREQ) { @@ -187,7 +194,7 @@ public: const int vco_multiplier = target_freq > LMX2592_MAX_VCO_FREQ ? 2 : 1; const auto target_vco_freq = target_freq * output_divider; - const auto core_vco_freq = target_vco_freq / vco_multiplier; + const auto core_vco_freq = target_vco_freq / vco_multiplier; double input_freq = _ref_freq; @@ -205,18 +212,20 @@ public: input_freq /= _regs.pll_r_pre; // Multiplier - _regs.mult = narrow_cast<uint8_t>(std::floor(LMX2592_MAX_MULT_OUT_FREQ / input_freq)); + _regs.mult = + narrow_cast<uint8_t>(std::floor(LMX2592_MAX_MULT_OUT_FREQ / input_freq)); input_freq *= _regs.mult; // Post R divider - _regs.pll_r = narrow_cast<uint8_t>(std::ceil(input_freq / LMX2592_MAX_POSTR_DIV_OUT_FREQ)); + _regs.pll_r = + narrow_cast<uint8_t>(std::ceil(input_freq / LMX2592_MAX_POSTR_DIV_OUT_FREQ)); // Default to divide by 2, will be increased later if N exceeds its limit - int prescaler = 2; + int prescaler = 2; _regs.pll_n_pre = lmx2592_regs_t::pll_n_pre_t::PLL_N_PRE_DIVIDE_BY_2; const int min_n_divider = LMX2592_MIN_N_DIV[_regs.mash_order]; - double pfd_freq = input_freq / _regs.pll_r; + double pfd_freq = input_freq / _regs.pll_r; while (pfd_freq * (prescaler * min_n_divider) / vco_multiplier > core_vco_freq) { _regs.pll_r++; pfd_freq = input_freq / _regs.pll_r; @@ -224,7 +233,7 @@ public: // Calculate N and frac const auto N_dot_F = target_vco_freq / (pfd_freq * prescaler); - auto N = static_cast<uint16_t>(std::floor(N_dot_F)); + auto N = static_cast<uint16_t>(std::floor(N_dot_F)); if (N > MAX_N_DIVIDER) { _regs.pll_n_pre = lmx2592_regs_t::pll_n_pre_t::PLL_N_PRE_DIVIDE_BY_4; N /= 2; @@ -234,30 +243,37 @@ public: // Increase VCO step size to threshold to avoid primary fractional spurs const double min_vco_step_size = spur_dodging ? spur_dodging_threshold : 1; // Calculate Fden - const auto initial_fden = static_cast<uint32_t>(std::floor(pfd_freq * prescaler / min_vco_step_size)); + const auto initial_fden = + static_cast<uint32_t>(std::floor(pfd_freq * prescaler / min_vco_step_size)); const auto fden = (spur_dodging) ? _find_fden(initial_fden) : initial_fden; // Calculate Fnum const auto initial_fnum = static_cast<uint32_t>(std::round(frac * fden)); - const auto fnum = (spur_dodging) ? _find_fnum(N, initial_fnum, fden, prescaler, pfd_freq, output_divider, spur_dodging_threshold) : initial_fnum; + const auto fnum = (spur_dodging) ? _find_fnum(N, + initial_fnum, + fden, + prescaler, + pfd_freq, + output_divider, + spur_dodging_threshold) + : initial_fnum; // Calculate mash_seed // if spur_dodging is true, mash_seed is the first odd value less than fden // else mash_seed is int(fden / 2); - const uint32_t mash_seed = (spur_dodging) ? - _find_mash_seed(fden) : - static_cast<uint32_t>(fden / 2); + const uint32_t mash_seed = (spur_dodging) ? _find_mash_seed(fden) + : static_cast<uint32_t>(fden / 2); // Calculate actual Fcore_vco, Fvco, F_lo frequencies const auto actual_fvco = pfd_freq * prescaler * (N + double(fnum) / double(fden)); const auto actual_fcore_vco = actual_fvco / vco_multiplier; - const auto actual_f_lo = actual_fcore_vco * vco_multiplier / output_divider; + const auto actual_f_lo = actual_fcore_vco * vco_multiplier / output_divider; // Write to registers - _regs.pll_n = N; - _regs.pll_num_lsb = narrow_cast<uint16_t>(fnum); - _regs.pll_num_msb = narrow_cast<uint16_t>(fnum >> 16); - _regs.pll_den_lsb = narrow_cast<uint16_t>(fden); - _regs.pll_den_msb = narrow_cast<uint16_t>(fden >> 16); + _regs.pll_n = N; + _regs.pll_num_lsb = narrow_cast<uint16_t>(fnum); + _regs.pll_num_msb = narrow_cast<uint16_t>(fnum >> 16); + _regs.pll_den_lsb = narrow_cast<uint16_t>(fden); + _regs.pll_den_msb = narrow_cast<uint16_t>(fden >> 16); _regs.mash_seed_lsb = narrow_cast<uint16_t>(mash_seed); _regs.mash_seed_msb = narrow_cast<uint16_t>(mash_seed >> 16); @@ -276,7 +292,8 @@ public: return actual_f_lo; } - void set_mash_order(const mash_order_t mash_order) override { + void set_mash_order(const mash_order_t mash_order) override + { if (mash_order == mash_order_t::INT_N) { _regs.mash_order = lmx2592_regs_t::mash_order_t::MASH_ORDER_INT_MODE; @@ -294,22 +311,26 @@ public: } } - void set_reference_frequency(const double ref_freq) override { + void set_reference_frequency(const double ref_freq) override + { if (ref_freq < LMX2592_MIN_REF_FREQ or ref_freq > LMX2592_MAX_REF_FREQ) { - throw std::runtime_error("Reference frequency is out of bounds for the LMX2592"); + throw std::runtime_error( + "Reference frequency is out of bounds for the LMX2592"); } _ref_freq = ref_freq; } - void set_output_power(const output_t output, const unsigned int power) override { + void set_output_power(const output_t output, const unsigned int power) override + { UHD_LOGGER_TRACE("LMX2592") - << "Set output: " << (output == RF_OUTPUT_A ? "A" : "B") << " to power " << power; + << "Set output: " << (output == RF_OUTPUT_A ? "A" : "B") << " to power " + << power; const auto MAX_POWER = 63; if (power > MAX_POWER) { - UHD_LOGGER_ERROR("LMX2592") - << "Requested power level of " << power << " exceeds maximum of " << MAX_POWER; + UHD_LOGGER_ERROR("LMX2592") << "Requested power level of " << power + << " exceeds maximum of " << MAX_POWER; return; } @@ -322,9 +343,11 @@ public: commit(); } - void set_output_enable(const output_t output, const bool enable) override { - UHD_LOGGER_TRACE("LMX2592") << "Set output " << (output == RF_OUTPUT_A ? "A" : "B") - << " to " << (enable ? "On" : "Off"); + void set_output_enable(const output_t output, const bool enable) override + { + UHD_LOGGER_TRACE("LMX2592") + << "Set output " << (output == RF_OUTPUT_A ? "A" : "B") << " to " + << (enable ? "On" : "Off"); if (enable) { _regs.chdiv_dist_pd = 0; @@ -338,13 +361,13 @@ public: } else { if (output == RF_OUTPUT_A) { - _regs.outa_pd = 1; - _regs.vco_dista_pd = 1; + _regs.outa_pd = 1; + _regs.vco_dista_pd = 1; _regs.chdiv_dista_en = 0; } else { - _regs.outb_pd = 1; - _regs.vco_distb_pd = 1; + _regs.outb_pd = 1; + _regs.vco_distb_pd = 1; _regs.chdiv_distb_en = 0; } } @@ -357,40 +380,41 @@ public: commit(); } - bool get_lock_status() override { + bool get_lock_status() override + { // SPI MISO is being driven by lock detect // If the PLL is locked we expect to read 0xFFFF from any read, else 0x0000 - const auto value_read = _read_fn(_regs.ADDR_R0); + const auto value_read = _read_fn(_regs.ADDR_R0); const auto lock_status = (value_read == 0xFFFF); - UHD_LOG_TRACE( - "LMX2592", - str(boost::format("Read Lock status: 0x%04X") % static_cast<unsigned int>(value_read))); + UHD_LOG_TRACE("LMX2592", + str(boost::format("Read Lock status: 0x%04X") + % static_cast<unsigned int>(value_read))); return lock_status; } - void commit() override { + void commit() override + { UHD_LOGGER_DEBUG("LMX2592") << "Storing register cache " << (_rewrite_regs ? "completely" : "selectively") << " to LMX via SPI..."; - const auto changed_addrs = - _rewrite_regs ? _regs.get_all_addrs() : _regs.get_changed_addrs<size_t>(); + const auto changed_addrs = _rewrite_regs ? _regs.get_all_addrs() + : _regs.get_changed_addrs<size_t>(); for (const auto addr : changed_addrs) { _write_fn(addr, _regs.get_reg(addr)); UHD_LOGGER_TRACE("LMX2592") - << "Register " << std::setw(2) << static_cast<unsigned int>(addr) << ": 0x" - << std::hex << std::uppercase << std::setw(4) << std::setfill('0') - << static_cast<unsigned int>(_regs.get_reg(addr)); + << "Register " << std::setw(2) << static_cast<unsigned int>(addr) + << ": 0x" << std::hex << std::uppercase << std::setw(4) + << std::setfill('0') << static_cast<unsigned int>(_regs.get_reg(addr)); } _regs.save_state(); UHD_LOG_DEBUG("LMX2592", - "Writing registers complete: " - "Updated " - << changed_addrs.size() - << " registers."); + "Writing registers complete: " + "Updated " + << changed_addrs.size() << " registers."); _rewrite_regs = false; } @@ -407,8 +431,8 @@ private: // Members bool _rewrite_regs; double _ref_freq; - void _set_chdiv_values(const int output_divider_index) { - + void _set_chdiv_values(const int output_divider_index) + { // Configure divide segments and mux const auto seg1 = LMX2592_CHDIV_SEGS[output_divider_index][0]; const auto seg2 = LMX2592_CHDIV_SEGS[output_divider_index][1]; @@ -417,12 +441,13 @@ private: // Members _regs.chdiv_seg_sel = lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_POWERDOWN; if (seg1 > 1) { - _regs.chdiv_seg_sel = lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_DIV_SEG_1; + _regs.chdiv_seg_sel = + lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_DIV_SEG_1; _regs.chdiv_seg1_en = 1; - _regs.outa_mux = lmx2592_regs_t::outa_mux_t::OUTA_MUX_DIVIDER; - _regs.outb_mux = lmx2592_regs_t::outb_mux_t::OUTB_MUX_DIVIDER; - _regs.vco_dista_pd = 1; - _regs.vco_distb_pd = 1; + _regs.outa_mux = lmx2592_regs_t::outa_mux_t::OUTA_MUX_DIVIDER; + _regs.outb_mux = lmx2592_regs_t::outb_mux_t::OUTB_MUX_DIVIDER; + _regs.vco_dista_pd = 1; + _regs.vco_distb_pd = 1; _regs.chdiv_dist_pd = 0; if (_regs.outa_pd == 0) { @@ -434,8 +459,8 @@ private: // Members } else { _regs.chdiv_seg1_en = 0; - _regs.outa_mux = lmx2592_regs_t::outa_mux_t::OUTA_MUX_VCO; - _regs.outb_mux = lmx2592_regs_t::outb_mux_t::OUTB_MUX_VCO; + _regs.outa_mux = lmx2592_regs_t::outa_mux_t::OUTA_MUX_VCO; + _regs.outb_mux = lmx2592_regs_t::outb_mux_t::OUTB_MUX_VCO; _regs.chdiv_dist_pd = 1; if (_regs.outa_pd == 0) { @@ -454,7 +479,8 @@ private: // Members if (seg2 > 1) { _regs.chdiv_seg2_en = 1; - _regs.chdiv_seg_sel = lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_DIV_SEG_1_AND_2; + _regs.chdiv_seg_sel = + lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_DIV_SEG_1_AND_2; } else { _regs.chdiv_seg2_en = 0; } @@ -473,7 +499,8 @@ private: // Members if (seg3 > 1) { _regs.chdiv_seg3_en = 1; - _regs.chdiv_seg_sel = lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_DIV_SEG_1_2_AND_3; + _regs.chdiv_seg_sel = + lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_DIV_SEG_1_2_AND_3; } else { _regs.chdiv_seg3_en = 0; } @@ -498,56 +525,33 @@ private: // Members int _get_k(const uint32_t fden) const { const auto mash = _regs.mash_order; - if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_INT_MODE or - mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_FIRST) - { + if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_INT_MODE + or mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_FIRST) { return 1; - } - else if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_SECOND) - { - if (fden % 2 != 0) - { + } else if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_SECOND) { + if (fden % 2 != 0) { return 1; - } - else { + } else { return 2; } - } - else if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_THIRD) - { - if (fden % 2 != 0 and fden % 3 != 0) - { + } else if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_THIRD) { + if (fden % 2 != 0 and fden % 3 != 0) { return 1; - } - else if (fden % 2 == 0 and fden % 3 != 0) - { + } else if (fden % 2 == 0 and fden % 3 != 0) { return 2; - } - else if (fden % 2 != 0 and fden % 3 == 0) - { + } else if (fden % 2 != 0 and fden % 3 == 0) { return 3; - } - else - { + } else { return 6; } - } - else if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_FOURTH) - { - if (fden % 2 != 0 and fden % 3 != 0) - { + } else if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_FOURTH) { + if (fden % 2 != 0 and fden % 3 != 0) { return 1; - } - else if (fden % 2 == 0 and fden % 3 != 0) - { + } else if (fden % 2 == 0 and fden % 3 != 0) { return 3; - } - else if (fden % 2 != 0 and fden % 3 == 0) - { + } else if (fden % 2 != 0 and fden % 3 == 0) { return 4; - } - else - { + } else { return 12; } } @@ -561,47 +565,38 @@ private: // Members auto fden = initial_fden; // mathematically, this loop should run a maximum of 4 times // i.e. initial_fden = 6N + 4 and mash_order is third or fourth order - for (int i = 0; i < 4; ++i) - { - if (_get_k(fden) == 1) - { - UHD_LOGGER_TRACE("LMX2592") << - "_find_fden(" << initial_fden << ") returned " << fden; + for (int i = 0; i < 4; ++i) { + if (_get_k(fden) == 1) { + UHD_LOGGER_TRACE("LMX2592") + << "_find_fden(" << initial_fden << ") returned " << fden; return fden; } // decrement rather than increment, as incrementing fden would decrease // the step size and violate any minimum step size that has been set --fden; } - UHD_LOGGER_WARNING("LMX2592") << - "Unable to find suitable fractional value denominator for spur dodging on LMX2592"; - UHD_LOGGER_ERROR("LMX2592") << - "Spur dodging failed"; + UHD_LOGGER_WARNING("LMX2592") << "Unable to find suitable fractional value " + "denominator for spur dodging on LMX2592"; + UHD_LOGGER_ERROR("LMX2592") << "Spur dodging failed"; return initial_fden; } // returns the offset of the closest multiple of // spur_frequency_base to target_frequency // A negative offset indicates the closest multiple is at a lower frequency - double _get_closest_spur_offset( - double target_frequency, - double spur_frequency_base) + double _get_closest_spur_offset(double target_frequency, double spur_frequency_base) { // find closest multiples of spur_frequency_base to target_frequency const auto first_harmonic_number = std::floor(target_frequency / spur_frequency_base); - const auto second_harmonic_number = - first_harmonic_number + 1; + const auto second_harmonic_number = first_harmonic_number + 1; // calculate offsets const auto first_spur_offset = (first_harmonic_number * spur_frequency_base) - target_frequency; const auto second_spur_offset = (second_harmonic_number * spur_frequency_base) - target_frequency; // select offset with smallest absolute value - return std::min({ - first_spur_offset, - second_spur_offset }, - abs_less_than_compare); + return std::min({first_spur_offset, second_spur_offset}, abs_less_than_compare); } // returns the closest spur offset among 4 different spurs @@ -611,8 +606,7 @@ private: // Members // 3. Reference to Fvco spur // 4. Reference to Flo spur // A negative offset indicates the closest spur is at a lower frequency - offset_t _get_min_offset_frequency( - const uint16_t N, + offset_t _get_min_offset_frequency(const uint16_t N, const uint32_t fnum, const uint32_t fden, const int prescaler, @@ -620,10 +614,10 @@ private: // Members const int output_divider) { // Calculate intermediate values - const auto fref = _ref_freq; + const auto fref = _ref_freq; const auto frf_in = pfd_freq * (N + double(fnum) / double(fden)); - const auto fvco = frf_in * prescaler; - const auto flo = fvco / output_divider; + const auto fvco = frf_in * prescaler; + const auto flo = fvco / output_divider; // the minimum offset is the smallest absolute value of these 4 values // as calculated by the _get_closest_spur_offset function @@ -631,23 +625,19 @@ private: // Members // in order to calculate the necessary frequency shift // Integer Boundary: - const offset_t ib_spur = { _get_closest_spur_offset(frf_in, pfd_freq), FRF_IN }; + const offset_t ib_spur = {_get_closest_spur_offset(frf_in, pfd_freq), FRF_IN}; // PFD Offset Spur: - const offset_t pfd_offset_spur = { _get_closest_spur_offset(fvco, pfd_freq), FVCO }; + const offset_t pfd_offset_spur = {_get_closest_spur_offset(fvco, pfd_freq), FVCO}; // Reference to Fvco Spur: - const offset_t fvco_spur = { _get_closest_spur_offset(fvco, fref), FVCO }; + const offset_t fvco_spur = {_get_closest_spur_offset(fvco, fref), FVCO}; // Reference to F_lo Spur: - const offset_t flo_spur = { _get_closest_spur_offset(flo, fref), FLO }; + const offset_t flo_spur = {_get_closest_spur_offset(flo, fref), FLO}; // use min with special comparator for minimal absolute value - return std::min({ - ib_spur, - pfd_offset_spur, - fvco_spur, - flo_spur}, + return std::min({ib_spur, pfd_offset_spur, fvco_spur, flo_spur}, offset_abs_less_than_compare); } @@ -659,8 +649,7 @@ private: // Members // PFD frequency will be at least 10x larger than the step size of // (fnum / fden). This function only considers at least 50% potential // values of fnum, and does not consider changes to N. - uint32_t _find_fnum( - const uint16_t N, + uint32_t _find_fnum(const uint16_t N, const uint32_t initial_fnum, const uint32_t fden, const int prescaler, @@ -669,40 +658,28 @@ private: // Members const double spur_dodging_threshold) { auto fnum = initial_fnum; - auto min_offset = _get_min_offset_frequency( - N, - fnum, - fden, - prescaler, - pfd_freq, - output_divider); - - UHD_LOGGER_TRACE("LMX2592") << - "closest spur is at " << min_offset.first << - " to " << log_intermediate_frequency(min_offset.second); + auto min_offset = + _get_min_offset_frequency(N, fnum, fden, prescaler, pfd_freq, output_divider); + + UHD_LOGGER_TRACE("LMX2592") << "closest spur is at " << min_offset.first << " to " + << log_intermediate_frequency(min_offset.second); // shift away from the closest integer boundary i.e. towards 0.5 const double delta_fnum_sign = ((((double)fnum) / ((double)fden)) < 0.5) ? 1 : -1; - while (std::abs(min_offset.first) < spur_dodging_threshold) - { + while (std::abs(min_offset.first) < spur_dodging_threshold) { double shift = spur_dodging_threshold; // if the spur is in the same direction as the desired shift direction... - if (std::signbit(min_offset.first) == std::signbit(delta_fnum_sign)) - { + if (std::signbit(min_offset.first) == std::signbit(delta_fnum_sign)) { shift += std::abs(min_offset.first); - } - else { + } else { shift -= std::abs(min_offset.first); } // convert shift of IF value to shift of Frf_in - if (min_offset.second == FVCO) - { + if (min_offset.second == FVCO) { shift /= prescaler; - } - else if (min_offset.second == FLO) - { + } else if (min_offset.second == FLO) { shift /= prescaler; shift *= output_divider; } @@ -710,33 +687,27 @@ private: // Members double delta_fnum_value = std::ceil((shift / pfd_freq) * fden); fnum += narrow_cast<int32_t>(delta_fnum_value * delta_fnum_sign); - UHD_LOGGER_TRACE("LMX2592") << - "adjusting fnum by " << (delta_fnum_value * delta_fnum_sign); + UHD_LOGGER_TRACE("LMX2592") + << "adjusting fnum by " << (delta_fnum_value * delta_fnum_sign); // fnum is unsigned, so this also checks for underflow - if (fnum >= fden) - { - UHD_LOGGER_WARNING("LMX2592") << - "Unable to find suitable fractional value numerator for spur dodging on LMX2592"; - UHD_LOGGER_ERROR("LMX2592") << - "Spur dodging failed"; + if (fnum >= fden) { + UHD_LOGGER_WARNING("LMX2592") + << "Unable to find suitable fractional value numerator for spur " + "dodging on LMX2592"; + UHD_LOGGER_ERROR("LMX2592") << "Spur dodging failed"; return initial_fnum; } min_offset = _get_min_offset_frequency( - N, - fnum, - fden, - prescaler, - pfd_freq, - output_divider); - - UHD_LOGGER_TRACE("LMX2592") << - "closest spur is at " << min_offset.first << - " to " << log_intermediate_frequency(min_offset.second); + N, fnum, fden, prescaler, pfd_freq, output_divider); + + UHD_LOGGER_TRACE("LMX2592") + << "closest spur is at " << min_offset.first << " to " + << log_intermediate_frequency(min_offset.second); } - UHD_LOGGER_TRACE("LMX2592") << - "_find_fnum(" << initial_fnum << ") returned " << fnum; + UHD_LOGGER_TRACE("LMX2592") + << "_find_fnum(" << initial_fnum << ") returned " << fnum; return fnum; } @@ -745,13 +716,13 @@ private: // Members { if (fden < 2) { return 1; - } - else { + } else { return (fden - 2) | 0x1; } }; }; -lmx2592_impl::sptr lmx2592_iface::make(write_spi_t write, read_spi_t read) { +lmx2592_impl::sptr lmx2592_iface::make(write_spi_t write, read_spi_t read) +{ return std::make_shared<lmx2592_impl>(write, read); } diff --git a/host/lib/usrp/common/recv_packet_demuxer.cpp b/host/lib/usrp/common/recv_packet_demuxer.cpp index 96eafa4be..c5ed1563e 100644 --- a/host/lib/usrp/common/recv_packet_demuxer.cpp +++ b/host/lib/usrp/common/recv_packet_demuxer.cpp @@ -5,15 +5,14 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhdlib/usrp/common/recv_packet_demuxer.hpp> -#include <uhd/utils/log.hpp> -#include <uhd/utils/byteswap.hpp> #include <uhd/transport/vrt_if_packet.hpp> #include <uhd/types/metadata.hpp> - +#include <uhd/utils/byteswap.hpp> +#include <uhd/utils/log.hpp> +#include <uhdlib/usrp/common/recv_packet_demuxer.hpp> #include <boost/thread/mutex.hpp> -#include <queue> #include <deque> +#include <queue> #include <vector> using namespace uhd; @@ -23,7 +22,9 @@ using namespace uhd::transport; struct recv_pkt_demux_mrb : public managed_recv_buffer { public: - recv_pkt_demux_mrb(void){/*NOP*/} + recv_pkt_demux_mrb(void) + { /*NOP*/ + } void release(void) { @@ -33,62 +34,68 @@ public: uint32_t buff[10]; }; -static UHD_INLINE uint32_t extract_sid(managed_recv_buffer::sptr &buff){ - //ASSUME that the data is in little endian format - return uhd::wtohx(buff->cast<const uint32_t *>()[1]); +static UHD_INLINE uint32_t extract_sid(managed_recv_buffer::sptr& buff) +{ + // ASSUME that the data is in little endian format + return uhd::wtohx(buff->cast<const uint32_t*>()[1]); } -recv_packet_demuxer::~recv_packet_demuxer(void){ +recv_packet_demuxer::~recv_packet_demuxer(void) +{ /* NOP */ } -class recv_packet_demuxer_impl : public uhd::usrp::recv_packet_demuxer{ +class recv_packet_demuxer_impl : public uhd::usrp::recv_packet_demuxer +{ public: - recv_packet_demuxer_impl( - transport::zero_copy_if::sptr transport, + recv_packet_demuxer_impl(transport::zero_copy_if::sptr transport, const size_t size, - const uint32_t sid_base - ): - _transport(transport), _sid_base(sid_base), _queues(size) + const uint32_t sid_base) + : _transport(transport), _sid_base(sid_base), _queues(size) { /* NOP */ } - managed_recv_buffer::sptr get_recv_buff(const size_t index, const double timeout){ + managed_recv_buffer::sptr get_recv_buff(const size_t index, const double timeout) + { boost::mutex::scoped_lock lock(_mutex); managed_recv_buffer::sptr buff; - //there is already an entry in the queue, so pop that - if (not _queues[index].wrapper.empty()){ + // there is already an entry in the queue, so pop that + if (not _queues[index].wrapper.empty()) { std::swap(buff, _queues[index].wrapper.front()); _queues[index].wrapper.pop(); return buff; } - while (true){ - //otherwise call into the transport + while (true) { + // otherwise call into the transport buff = _transport->get_recv_buff(timeout); - if (buff.get() == NULL) return buff; //timeout + if (buff.get() == NULL) + return buff; // timeout - //check the stream id to know which channel + // check the stream id to know which channel const size_t rx_index = extract_sid(buff) - _sid_base; - if (rx_index == index) return buff; //got expected message - - //otherwise queue and try again - if (rx_index < _queues.size()) _queues[rx_index].wrapper.push(buff); - else - { - UHD_LOGGER_ERROR("STREAMER") << "Got a data packet with unknown SID " << extract_sid(buff) ; - recv_pkt_demux_mrb *mrb = new recv_pkt_demux_mrb(); + if (rx_index == index) + return buff; // got expected message + + // otherwise queue and try again + if (rx_index < _queues.size()) + _queues[rx_index].wrapper.push(buff); + else { + UHD_LOGGER_ERROR("STREAMER") + << "Got a data packet with unknown SID " << extract_sid(buff); + recv_pkt_demux_mrb* mrb = new recv_pkt_demux_mrb(); vrt::if_packet_info_t info; - info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; + info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; info.num_payload_words32 = 1; - info.num_payload_bytes = info.num_payload_words32*sizeof(uint32_t); - info.has_sid = true; - info.sid = _sid_base + index; + info.num_payload_bytes = info.num_payload_words32 * sizeof(uint32_t); + info.has_sid = true; + info.sid = _sid_base + index; vrt::if_hdr_pack_le(mrb->buff, info); mrb->buff[info.num_header_words32] = rx_metadata_t::ERROR_CODE_OVERFLOW; - return mrb->make(mrb, mrb->buff, info.num_packet_words32*sizeof(uint32_t)); + return mrb->make( + mrb, mrb->buff, info.num_packet_words32 * sizeof(uint32_t)); } } } @@ -97,14 +104,17 @@ private: transport::zero_copy_if::sptr _transport; const uint32_t _sid_base; boost::mutex _mutex; - struct channel_guts_type{ - channel_guts_type(void): wrapper(container){} + struct channel_guts_type + { + channel_guts_type(void) : wrapper(container) {} std::deque<managed_recv_buffer::sptr> container; std::queue<managed_recv_buffer::sptr> wrapper; }; std::vector<channel_guts_type> _queues; }; -recv_packet_demuxer::sptr recv_packet_demuxer::make(transport::zero_copy_if::sptr transport, const size_t size, const uint32_t sid_base){ +recv_packet_demuxer::sptr recv_packet_demuxer::make( + transport::zero_copy_if::sptr transport, const size_t size, const uint32_t sid_base) +{ return sptr(new recv_packet_demuxer_impl(transport, size, sid_base)); } diff --git a/host/lib/usrp/common/validate_subdev_spec.cpp b/host/lib/usrp/common/validate_subdev_spec.cpp index 369119e4a..61895a7f8 100644 --- a/host/lib/usrp/common/validate_subdev_spec.cpp +++ b/host/lib/usrp/common/validate_subdev_spec.cpp @@ -5,58 +5,68 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhdlib/usrp/common/validate_subdev_spec.hpp> #include <uhd/exception.hpp> #include <uhd/utils/assert_has.hpp> +#include <uhdlib/usrp/common/validate_subdev_spec.hpp> #include <boost/format.hpp> using namespace uhd; using namespace uhd::usrp; -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { - static std::ostream& operator<< (std::ostream &out, const subdev_spec_pair_t &pair){ - out << pair.db_name << ":" << pair.sd_name; - return out; - } +static std::ostream& operator<<(std::ostream& out, const subdev_spec_pair_t& pair) +{ + out << pair.db_name << ":" << pair.sd_name; + return out; +} + +}} // namespace uhd::usrp + +void uhd::usrp::validate_subdev_spec(property_tree::sptr tree, + const subdev_spec_t& spec, + const std::string& type, + const std::string& mb) +{ + const size_t num_dsps = + tree->list(str(boost::format("/mboards/%s/%s_dsps") % mb % type)).size(); + + // sanity checking on the length + if (spec.size() == 0) + throw uhd::value_error( + str(boost::format("Empty %s subdevice specification is not supported.\n") + % type)); + if (spec.size() > num_dsps) + throw uhd::value_error( + str(boost::format("The subdevice specification \"%s\" is too long.\n" + "The user specified %u channels, but there are only %u %s " + "dsps on mboard %s.\n") + % spec.to_string() % spec.size() % num_dsps % type % mb)); -}} - -void uhd::usrp::validate_subdev_spec( - property_tree::sptr tree, - const subdev_spec_t &spec, - const std::string &type, - const std::string &mb -){ - const size_t num_dsps = tree->list(str(boost::format("/mboards/%s/%s_dsps") % mb % type)).size(); - - //sanity checking on the length - if (spec.size() == 0) throw uhd::value_error(str(boost::format( - "Empty %s subdevice specification is not supported.\n" - ) % type)); - if (spec.size() > num_dsps) throw uhd::value_error(str(boost::format( - "The subdevice specification \"%s\" is too long.\n" - "The user specified %u channels, but there are only %u %s dsps on mboard %s.\n" - ) % spec.to_string() % spec.size() % num_dsps % type % mb)); - - //make a list of all possible specs + // make a list of all possible specs subdev_spec_t all_specs; - for(const std::string &db: tree->list(str(boost::format("/mboards/%s/dboards") % mb))){ - for(const std::string &sd: tree->list(str(boost::format("/mboards/%s/dboards/%s/%s_frontends") % mb % db % type))){ + for (const std::string& db : + tree->list(str(boost::format("/mboards/%s/dboards") % mb))) { + for (const std::string& sd : + tree->list(str( + boost::format("/mboards/%s/dboards/%s/%s_frontends") % mb % db % type))) { all_specs.push_back(subdev_spec_pair_t(db, sd)); } } - //validate that the spec is possible - for(const subdev_spec_pair_t &pair: spec){ - uhd::assert_has(all_specs, pair, str(boost::format("%s subdevice specification on mboard %s") % type % mb)); + // validate that the spec is possible + for (const subdev_spec_pair_t& pair : spec) { + uhd::assert_has(all_specs, + pair, + str(boost::format("%s subdevice specification on mboard %s") % type % mb)); } - //enable selected frontends, disable others - for(const subdev_spec_pair_t &pair: all_specs){ + // enable selected frontends, disable others + for (const subdev_spec_pair_t& pair : all_specs) { const bool enb = uhd::has(spec, pair); - tree->access<bool>(str(boost::format( - "/mboards/%s/dboards/%s/%s_frontends/%s/enabled" - ) % mb % pair.db_name % type % pair.sd_name)).set(enb); + tree->access<bool>( + str(boost::format("/mboards/%s/dboards/%s/%s_frontends/%s/enabled") % mb + % pair.db_name % type % pair.sd_name)) + .set(enb); } } diff --git a/host/lib/usrp/cores/dsp_core_utils.cpp b/host/lib/usrp/cores/dsp_core_utils.cpp index 44885bc6f..a96028d65 100644 --- a/host/lib/usrp/cores/dsp_core_utils.cpp +++ b/host/lib/usrp/cores/dsp_core_utils.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/math.hpp> #include <uhd/exception.hpp> +#include <uhd/utils/math.hpp> #include <uhdlib/usrp/cores/dsp_core_utils.hpp> #include <boost/math/special_functions/round.hpp> #include <boost/math/special_functions/sign.hpp> @@ -14,19 +14,18 @@ static const int32_t MAX_FREQ_WORD = boost::numeric::bounds<int32_t>::highest(); static const int32_t MIN_FREQ_WORD = boost::numeric::bounds<int32_t>::lowest(); -void get_freq_and_freq_word( - const double requested_freq, - const double tick_rate, - double &actual_freq, - int32_t &freq_word -) { - //correct for outside of rate (wrap around) +void get_freq_and_freq_word(const double requested_freq, + const double tick_rate, + double& actual_freq, + int32_t& freq_word) +{ + // correct for outside of rate (wrap around) double freq = std::fmod(requested_freq, tick_rate); - if (std::abs(freq) > tick_rate/2.0) + if (std::abs(freq) > tick_rate / 2.0) freq -= boost::math::sign(freq) * tick_rate; - //confirm that the target frequency is within range of the CORDIC - UHD_ASSERT_THROW(std::abs(freq) <= tick_rate/2.0); + // confirm that the target frequency is within range of the CORDIC + UHD_ASSERT_THROW(std::abs(freq) <= tick_rate / 2.0); /* Now calculate the frequency word. It is possible for this calculation * to cause an overflow. As the requested DSP frequency approaches the @@ -54,11 +53,11 @@ void get_freq_and_freq_word( actual_freq = (double(freq_word) / scale_factor) * tick_rate; } -std::tuple<double, int> get_freq_and_freq_word(const double requested_freq, const double tick_rate) +std::tuple<double, int> get_freq_and_freq_word( + const double requested_freq, const double tick_rate) { double actual_freq; int32_t freq_word; get_freq_and_freq_word(requested_freq, tick_rate, actual_freq, freq_word); return std::make_tuple(actual_freq, freq_word); } - diff --git a/host/lib/usrp/cores/gpio_core_200.cpp b/host/lib/usrp/cores/gpio_core_200.cpp index 7df8e3c19..7ee0daf70 100644 --- a/host/lib/usrp/cores/gpio_core_200.cpp +++ b/host/lib/usrp/cores/gpio_core_200.cpp @@ -8,85 +8,108 @@ #include <uhd/types/dict.hpp> #include <uhdlib/usrp/cores/gpio_core_200.hpp> -#define REG_GPIO_IDLE _base + 0 -#define REG_GPIO_RX_ONLY _base + 4 -#define REG_GPIO_TX_ONLY _base + 8 -#define REG_GPIO_BOTH _base + 12 -#define REG_GPIO_DDR _base + 16 +#define REG_GPIO_IDLE _base + 0 +#define REG_GPIO_RX_ONLY _base + 4 +#define REG_GPIO_TX_ONLY _base + 8 +#define REG_GPIO_BOTH _base + 12 +#define REG_GPIO_DDR _base + 16 using namespace uhd; using namespace usrp; template <typename T> -static void shadow_it(T &shadow, const T &value, const T &mask){ +static void shadow_it(T& shadow, const T& value, const T& mask) +{ shadow = (shadow & ~mask) | (value & mask); } -gpio_core_200::~gpio_core_200(void){ +gpio_core_200::~gpio_core_200(void) +{ /* NOP */ } -class gpio_core_200_impl : public gpio_core_200{ +class gpio_core_200_impl : public gpio_core_200 +{ public: - gpio_core_200_impl(wb_iface::sptr iface, const size_t base, const size_t rb_addr): - _iface(iface), _base(base), _rb_addr(rb_addr), _first_atr(true) { /* NOP */ } + gpio_core_200_impl(wb_iface::sptr iface, const size_t base, const size_t rb_addr) + : _iface(iface), _base(base), _rb_addr(rb_addr), _first_atr(true) + { /* NOP */ + } - void set_pin_ctrl(const unit_t unit, const uint16_t value, const uint16_t mask){ - if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + void set_pin_ctrl(const unit_t unit, const uint16_t value, const uint16_t mask) + { + if (unit == dboard_iface::UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); shadow_it(_pin_ctrl[unit], value, mask); - update(); //full update + update(); // full update } - uint16_t get_pin_ctrl(unit_t unit){ - if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + uint16_t get_pin_ctrl(unit_t unit) + { + if (unit == dboard_iface::UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); return _pin_ctrl[unit]; } - void set_atr_reg(const unit_t unit, const atr_reg_t atr, const uint16_t value, const uint16_t mask){ - if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + void set_atr_reg( + const unit_t unit, const atr_reg_t atr, const uint16_t value, const uint16_t mask) + { + if (unit == dboard_iface::UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); shadow_it(_atr_regs[unit][atr], value, mask); - if (_first_atr) - { + if (_first_atr) { // To preserve legacy behavior, update all registers the first time update(); _first_atr = false; - } - else + } else update(atr); } - uint16_t get_atr_reg(unit_t unit, atr_reg_t reg){ - if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + uint16_t get_atr_reg(unit_t unit, atr_reg_t reg) + { + if (unit == dboard_iface::UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); return _atr_regs[unit][reg]; } - void set_gpio_ddr(const unit_t unit, const uint16_t value, const uint16_t mask){ - if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + void set_gpio_ddr(const unit_t unit, const uint16_t value, const uint16_t mask) + { + if (unit == dboard_iface::UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); shadow_it(_gpio_ddr[unit], value, mask); - _iface->poke32(REG_GPIO_DDR, //update the 32 bit register - (uint32_t(_gpio_ddr[dboard_iface::UNIT_RX]) << shift_by_unit(dboard_iface::UNIT_RX)) | - (uint32_t(_gpio_ddr[dboard_iface::UNIT_TX]) << shift_by_unit(dboard_iface::UNIT_TX)) - ); + _iface->poke32(REG_GPIO_DDR, // update the 32 bit register + (uint32_t(_gpio_ddr[dboard_iface::UNIT_RX]) + << shift_by_unit(dboard_iface::UNIT_RX)) + | (uint32_t(_gpio_ddr[dboard_iface::UNIT_TX]) + << shift_by_unit(dboard_iface::UNIT_TX))); } - uint16_t get_gpio_ddr(unit_t unit){ - if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + uint16_t get_gpio_ddr(unit_t unit) + { + if (unit == dboard_iface::UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); return _gpio_ddr[unit]; } - void set_gpio_out(const unit_t unit, const uint16_t value, const uint16_t mask){ - if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + void set_gpio_out(const unit_t unit, const uint16_t value, const uint16_t mask) + { + if (unit == dboard_iface::UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); shadow_it(_gpio_out[unit], value, mask); - this->update(); //full update + this->update(); // full update } - uint16_t get_gpio_out(unit_t unit){ - if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + uint16_t get_gpio_out(unit_t unit) + { + if (unit == dboard_iface::UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); return _gpio_out[unit]; } - uint16_t read_gpio(const unit_t unit){ - if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + uint16_t read_gpio(const unit_t unit) + { + if (unit == dboard_iface::UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); return uint16_t(_iface->peek32(_rb_addr) >> shift_by_unit(unit)); } @@ -98,81 +121,90 @@ private: uhd::dict<size_t, uint32_t> _update_cache; uhd::dict<unit_t, uint16_t> _pin_ctrl, _gpio_out, _gpio_ddr; - uhd::dict<unit_t, uhd::dict<atr_reg_t, uint16_t> > _atr_regs; + uhd::dict<unit_t, uhd::dict<atr_reg_t, uint16_t>> _atr_regs; - unsigned shift_by_unit(const unit_t unit){ - return (unit == dboard_iface::UNIT_RX)? 0 : 16; + unsigned shift_by_unit(const unit_t unit) + { + return (unit == dboard_iface::UNIT_RX) ? 0 : 16; } - void update(void){ + void update(void) + { update(gpio_atr::ATR_REG_IDLE); update(gpio_atr::ATR_REG_TX_ONLY); update(gpio_atr::ATR_REG_RX_ONLY); update(gpio_atr::ATR_REG_FULL_DUPLEX); } - void update(const atr_reg_t atr){ + void update(const atr_reg_t atr) + { size_t addr; - switch (atr) - { - case gpio_atr::ATR_REG_IDLE: - addr = REG_GPIO_IDLE; - break; - case gpio_atr::ATR_REG_TX_ONLY: - addr = REG_GPIO_TX_ONLY; - break; - case gpio_atr::ATR_REG_RX_ONLY: - addr = REG_GPIO_RX_ONLY; - break; - case gpio_atr::ATR_REG_FULL_DUPLEX: - addr = REG_GPIO_BOTH; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (atr) { + case gpio_atr::ATR_REG_IDLE: + addr = REG_GPIO_IDLE; + break; + case gpio_atr::ATR_REG_TX_ONLY: + addr = REG_GPIO_TX_ONLY; + break; + case gpio_atr::ATR_REG_RX_ONLY: + addr = REG_GPIO_RX_ONLY; + break; + case gpio_atr::ATR_REG_FULL_DUPLEX: + addr = REG_GPIO_BOTH; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } - const uint32_t atr_val = - (uint32_t(_atr_regs[dboard_iface::UNIT_RX][atr]) << shift_by_unit(dboard_iface::UNIT_RX)) | - (uint32_t(_atr_regs[dboard_iface::UNIT_TX][atr]) << shift_by_unit(dboard_iface::UNIT_TX)); - - const uint32_t gpio_val = - (uint32_t(_gpio_out[dboard_iface::UNIT_RX]) << shift_by_unit(dboard_iface::UNIT_RX)) | - (uint32_t(_gpio_out[dboard_iface::UNIT_TX]) << shift_by_unit(dboard_iface::UNIT_TX)); - - const uint32_t ctrl = - (uint32_t(_pin_ctrl[dboard_iface::UNIT_RX]) << shift_by_unit(dboard_iface::UNIT_RX)) | - (uint32_t(_pin_ctrl[dboard_iface::UNIT_TX]) << shift_by_unit(dboard_iface::UNIT_TX)); + const uint32_t atr_val = (uint32_t(_atr_regs[dboard_iface::UNIT_RX][atr]) + << shift_by_unit(dboard_iface::UNIT_RX)) + | (uint32_t(_atr_regs[dboard_iface::UNIT_TX][atr]) + << shift_by_unit(dboard_iface::UNIT_TX)); + + const uint32_t gpio_val = (uint32_t(_gpio_out[dboard_iface::UNIT_RX]) + << shift_by_unit(dboard_iface::UNIT_RX)) + | (uint32_t(_gpio_out[dboard_iface::UNIT_TX]) + << shift_by_unit(dboard_iface::UNIT_TX)); + + const uint32_t ctrl = (uint32_t(_pin_ctrl[dboard_iface::UNIT_RX]) + << shift_by_unit(dboard_iface::UNIT_RX)) + | (uint32_t(_pin_ctrl[dboard_iface::UNIT_TX]) + << shift_by_unit(dboard_iface::UNIT_TX)); const uint32_t val = (ctrl & atr_val) | ((~ctrl) & gpio_val); - if (not _update_cache.has_key(addr) or _update_cache[addr] != val) - { + if (not _update_cache.has_key(addr) or _update_cache[addr] != val) { _iface->poke32(addr, val); } _update_cache[addr] = val; } - }; -gpio_core_200::sptr gpio_core_200::make(wb_iface::sptr iface, const size_t base, const size_t rb_addr){ +gpio_core_200::sptr gpio_core_200::make( + wb_iface::sptr iface, const size_t base, const size_t rb_addr) +{ return sptr(new gpio_core_200_impl(iface, base, rb_addr)); } -gpio_core_200_32wo::~gpio_core_200_32wo(void){ +gpio_core_200_32wo::~gpio_core_200_32wo(void) +{ /* NOP */ } -class gpio_core_200_32wo_impl : public gpio_core_200_32wo{ +class gpio_core_200_32wo_impl : public gpio_core_200_32wo +{ public: - gpio_core_200_32wo_impl(wb_iface::sptr iface, const size_t base): - _iface(iface), _base(base) + gpio_core_200_32wo_impl(wb_iface::sptr iface, const size_t base) + : _iface(iface), _base(base) { set_ddr_reg(); } - void set_ddr_reg(){ + void set_ddr_reg() + { _iface->poke32(REG_GPIO_DDR, 0xffffffff); } - void set_atr_reg(const atr_reg_t atr, const uint32_t value){ + void set_atr_reg(const atr_reg_t atr, const uint32_t value) + { if (atr == gpio_atr::ATR_REG_IDLE) _iface->poke32(REG_GPIO_IDLE, value); else if (atr == gpio_atr::ATR_REG_TX_ONLY) @@ -185,19 +217,20 @@ public: UHD_THROW_INVALID_CODE_PATH(); } - void set_all_regs(const uint32_t value){ - set_atr_reg(gpio_atr::ATR_REG_IDLE, value); - set_atr_reg(gpio_atr::ATR_REG_TX_ONLY, value); - set_atr_reg(gpio_atr::ATR_REG_RX_ONLY, value); + void set_all_regs(const uint32_t value) + { + set_atr_reg(gpio_atr::ATR_REG_IDLE, value); + set_atr_reg(gpio_atr::ATR_REG_TX_ONLY, value); + set_atr_reg(gpio_atr::ATR_REG_RX_ONLY, value); set_atr_reg(gpio_atr::ATR_REG_FULL_DUPLEX, value); } private: wb_iface::sptr _iface; const size_t _base; - }; -gpio_core_200_32wo::sptr gpio_core_200_32wo::make(wb_iface::sptr iface, const size_t base){ +gpio_core_200_32wo::sptr gpio_core_200_32wo::make(wb_iface::sptr iface, const size_t base) +{ return sptr(new gpio_core_200_32wo_impl(iface, base)); } diff --git a/host/lib/usrp/cores/i2c_core_100_wb32.cpp b/host/lib/usrp/cores/i2c_core_100_wb32.cpp index ec47aa8f0..d3d0a135a 100644 --- a/host/lib/usrp/cores/i2c_core_100_wb32.cpp +++ b/host/lib/usrp/cores/i2c_core_100_wb32.cpp @@ -13,67 +13,69 @@ #define REG_I2C_PRESCALER_LO _base + 0 #define REG_I2C_PRESCALER_HI _base + 4 -#define REG_I2C_CTRL _base + 8 -#define REG_I2C_DATA _base + 12 -#define REG_I2C_CMD_STATUS _base + 16 +#define REG_I2C_CTRL _base + 8 +#define REG_I2C_DATA _base + 12 +#define REG_I2C_CMD_STATUS _base + 16 // // STA, STO, RD, WR, and IACK bits are cleared automatically // -#define I2C_CTRL_EN (1 << 7) // core enable -#define I2C_CTRL_IE (1 << 6) // interrupt enable - -#define I2C_CMD_START (1 << 7) // generate (repeated) start condition -#define I2C_CMD_STOP (1 << 6) // generate stop condition -#define I2C_CMD_RD (1 << 5) // read from slave -#define I2C_CMD_WR (1 << 4) // write to slave -#define I2C_CMD_NACK (1 << 3) // when a rcvr, send ACK (ACK=0) or NACK (ACK=1) -#define I2C_CMD_RSVD_2 (1 << 2) // reserved -#define I2C_CMD_RSVD_1 (1 << 1) // reserved -#define I2C_CMD_IACK (1 << 0) // set to clear pending interrupt - -#define I2C_ST_RXACK (1 << 7) // Received acknowledgement from slave (1 = NAK, 0 = ACK) -#define I2C_ST_BUSY (1 << 6) // 1 after START signal detected; 0 after STOP signal detected -#define I2C_ST_AL (1 << 5) // Arbitration lost. 1 when core lost arbitration -#define I2C_ST_RSVD_4 (1 << 4) // reserved -#define I2C_ST_RSVD_3 (1 << 3) // reserved -#define I2C_ST_RSVD_2 (1 << 2) // reserved -#define I2C_ST_TIP (1 << 1) // Transfer-in-progress -#define I2C_ST_IP (1 << 0) // Interrupt pending +#define I2C_CTRL_EN (1 << 7) // core enable +#define I2C_CTRL_IE (1 << 6) // interrupt enable + +#define I2C_CMD_START (1 << 7) // generate (repeated) start condition +#define I2C_CMD_STOP (1 << 6) // generate stop condition +#define I2C_CMD_RD (1 << 5) // read from slave +#define I2C_CMD_WR (1 << 4) // write to slave +#define I2C_CMD_NACK (1 << 3) // when a rcvr, send ACK (ACK=0) or NACK (ACK=1) +#define I2C_CMD_RSVD_2 (1 << 2) // reserved +#define I2C_CMD_RSVD_1 (1 << 1) // reserved +#define I2C_CMD_IACK (1 << 0) // set to clear pending interrupt + +#define I2C_ST_RXACK (1 << 7) // Received acknowledgement from slave (1 = NAK, 0 = ACK) +#define I2C_ST_BUSY \ + (1 << 6) // 1 after START signal detected; 0 after STOP signal detected +#define I2C_ST_AL (1 << 5) // Arbitration lost. 1 when core lost arbitration +#define I2C_ST_RSVD_4 (1 << 4) // reserved +#define I2C_ST_RSVD_3 (1 << 3) // reserved +#define I2C_ST_RSVD_2 (1 << 2) // reserved +#define I2C_ST_TIP (1 << 1) // Transfer-in-progress +#define I2C_ST_IP (1 << 0) // Interrupt pending using namespace uhd; -i2c_core_100_wb32::~i2c_core_100_wb32(void){ +i2c_core_100_wb32::~i2c_core_100_wb32(void) +{ /* NOP */ } -class i2c_core_100_wb32_wb32_impl : public i2c_core_100_wb32{ +class i2c_core_100_wb32_wb32_impl : public i2c_core_100_wb32 +{ public: - i2c_core_100_wb32_wb32_impl(wb_iface::sptr iface, const size_t base): - _iface(iface), _base(base) + i2c_core_100_wb32_wb32_impl(wb_iface::sptr iface, const size_t base) + : _iface(iface), _base(base) { - //init I2C FPGA interface. + // init I2C FPGA interface. _iface->poke32(REG_I2C_CTRL, 0x0000); - _iface->poke32(REG_I2C_CTRL, I2C_CTRL_EN); //enable I2C core + _iface->poke32(REG_I2C_CTRL, I2C_CTRL_EN); // enable I2C core } void set_clock_rate(const double rate) { static const uint32_t i2c_datarate = 400000; - uint16_t prescaler = uint16_t(rate / (i2c_datarate*5) - 1); + uint16_t prescaler = uint16_t(rate / (i2c_datarate * 5) - 1); _iface->poke32(REG_I2C_PRESCALER_LO, prescaler & 0xFF); _iface->poke32(REG_I2C_PRESCALER_HI, (prescaler >> 8) & 0xFF); } - void write_i2c( - uint16_t addr, - const byte_vector_t &bytes - ){ - _iface->poke32(REG_I2C_DATA, (addr << 1) | 0); //addr and read bit (0) - _iface->poke32(REG_I2C_CMD_STATUS, I2C_CMD_WR | I2C_CMD_START | (bytes.size() == 0 ? I2C_CMD_STOP : 0)); + void write_i2c(uint16_t addr, const byte_vector_t& bytes) + { + _iface->poke32(REG_I2C_DATA, (addr << 1) | 0); // addr and read bit (0) + _iface->poke32(REG_I2C_CMD_STATUS, + I2C_CMD_WR | I2C_CMD_START | (bytes.size() == 0 ? I2C_CMD_STOP : 0)); - //wait for previous transfer to complete + // wait for previous transfer to complete if (not wait_chk_ack()) { _iface->poke32(REG_I2C_CMD_STATUS, I2C_CMD_STOP); return; @@ -81,41 +83,42 @@ public: for (size_t i = 0; i < bytes.size(); i++) { _iface->poke32(REG_I2C_DATA, bytes[i]); - _iface->poke32(REG_I2C_CMD_STATUS, I2C_CMD_WR | ((i == (bytes.size() - 1)) ? I2C_CMD_STOP : 0)); - if(!wait_chk_ack()) { + _iface->poke32(REG_I2C_CMD_STATUS, + I2C_CMD_WR | ((i == (bytes.size() - 1)) ? I2C_CMD_STOP : 0)); + if (!wait_chk_ack()) { _iface->poke32(REG_I2C_CMD_STATUS, I2C_CMD_STOP); return; } } } - byte_vector_t read_i2c( - uint16_t addr, - size_t num_bytes - ){ + byte_vector_t read_i2c(uint16_t addr, size_t num_bytes) + { byte_vector_t bytes; - if (num_bytes == 0) return bytes; + if (num_bytes == 0) + return bytes; - while (_iface->peek32(REG_I2C_CMD_STATUS) & I2C_ST_BUSY){ + while (_iface->peek32(REG_I2C_CMD_STATUS) & I2C_ST_BUSY) { /* NOP */ } - _iface->poke32(REG_I2C_DATA, (addr << 1) | 1); //addr and read bit (1) + _iface->poke32(REG_I2C_DATA, (addr << 1) | 1); // addr and read bit (1) _iface->poke32(REG_I2C_CMD_STATUS, I2C_CMD_WR | I2C_CMD_START); - //wait for previous transfer to complete + // wait for previous transfer to complete if (not wait_chk_ack()) { _iface->poke32(REG_I2C_CMD_STATUS, I2C_CMD_STOP); } for (size_t i = 0; i < num_bytes; i++) { - _iface->poke32(REG_I2C_CMD_STATUS, I2C_CMD_RD | ((num_bytes == i+1) ? (I2C_CMD_STOP | I2C_CMD_NACK) : 0)); + _iface->poke32(REG_I2C_CMD_STATUS, + I2C_CMD_RD | ((num_bytes == i + 1) ? (I2C_CMD_STOP | I2C_CMD_NACK) : 0)); i2c_wait(); bytes.push_back(uint8_t(_iface->peek32(REG_I2C_DATA))); } return bytes; } - //override read_eeprom so we can write once, read all N bytes - //the default implementation calls read i2c once per byte + // override read_eeprom so we can write once, read all N bytes + // the default implementation calls read i2c once per byte byte_vector_t read_eeprom(uint16_t addr, uint16_t offset, size_t num_bytes) { this->write_i2c(addr, byte_vector_t(1, uint8_t(offset))); @@ -123,16 +126,18 @@ public: } private: - void i2c_wait(void) { - for (size_t i = 0; i < 10; i++) - { - if ((_iface->peek32(REG_I2C_CMD_STATUS) & I2C_ST_TIP) == 0) return; + void i2c_wait(void) + { + for (size_t i = 0; i < 10; i++) { + if ((_iface->peek32(REG_I2C_CMD_STATUS) & I2C_ST_TIP) == 0) + return; std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - UHD_LOGGER_ERROR("CORES") << "i2c_core_100_wb32: i2c_wait timeout" ; + UHD_LOGGER_ERROR("CORES") << "i2c_core_100_wb32: i2c_wait timeout"; } - bool wait_chk_ack(void){ + bool wait_chk_ack(void) + { i2c_wait(); return (_iface->peek32(REG_I2C_CMD_STATUS) & I2C_ST_RXACK) == 0; } diff --git a/host/lib/usrp/cores/i2c_core_200.cpp b/host/lib/usrp/cores/i2c_core_200.cpp index 4278bf611..431ba194c 100644 --- a/host/lib/usrp/cores/i2c_core_200.cpp +++ b/host/lib/usrp/cores/i2c_core_200.cpp @@ -14,67 +14,69 @@ #define REG_I2C_WR_PRESCALER_LO (1 << 3) | 0 #define REG_I2C_WR_PRESCALER_HI (1 << 3) | 1 -#define REG_I2C_WR_CTRL (1 << 3) | 2 -#define REG_I2C_WR_DATA (1 << 3) | 3 -#define REG_I2C_WR_CMD (1 << 3) | 4 -#define REG_I2C_RD_DATA (0 << 3) | 3 -#define REG_I2C_RD_ST (0 << 3) | 4 +#define REG_I2C_WR_CTRL (1 << 3) | 2 +#define REG_I2C_WR_DATA (1 << 3) | 3 +#define REG_I2C_WR_CMD (1 << 3) | 4 +#define REG_I2C_RD_DATA (0 << 3) | 3 +#define REG_I2C_RD_ST (0 << 3) | 4 // // STA, STO, RD, WR, and IACK bits are cleared automatically // -#define I2C_CTRL_EN (1 << 7) // core enable -#define I2C_CTRL_IE (1 << 6) // interrupt enable - -#define I2C_CMD_START (1 << 7) // generate (repeated) start condition -#define I2C_CMD_STOP (1 << 6) // generate stop condition -#define I2C_CMD_RD (1 << 5) // read from slave -#define I2C_CMD_WR (1 << 4) // write to slave -#define I2C_CMD_NACK (1 << 3) // when a rcvr, send ACK (ACK=0) or NACK (ACK=1) -#define I2C_CMD_RSVD_2 (1 << 2) // reserved -#define I2C_CMD_RSVD_1 (1 << 1) // reserved -#define I2C_CMD_IACK (1 << 0) // set to clear pending interrupt - -#define I2C_ST_RXACK (1 << 7) // Received acknowledgement from slave (1 = NAK, 0 = ACK) -#define I2C_ST_BUSY (1 << 6) // 1 after START signal detected; 0 after STOP signal detected -#define I2C_ST_AL (1 << 5) // Arbitration lost. 1 when core lost arbitration -#define I2C_ST_RSVD_4 (1 << 4) // reserved -#define I2C_ST_RSVD_3 (1 << 3) // reserved -#define I2C_ST_RSVD_2 (1 << 2) // reserved -#define I2C_ST_TIP (1 << 1) // Transfer-in-progress -#define I2C_ST_IP (1 << 0) // Interrupt pending +#define I2C_CTRL_EN (1 << 7) // core enable +#define I2C_CTRL_IE (1 << 6) // interrupt enable + +#define I2C_CMD_START (1 << 7) // generate (repeated) start condition +#define I2C_CMD_STOP (1 << 6) // generate stop condition +#define I2C_CMD_RD (1 << 5) // read from slave +#define I2C_CMD_WR (1 << 4) // write to slave +#define I2C_CMD_NACK (1 << 3) // when a rcvr, send ACK (ACK=0) or NACK (ACK=1) +#define I2C_CMD_RSVD_2 (1 << 2) // reserved +#define I2C_CMD_RSVD_1 (1 << 1) // reserved +#define I2C_CMD_IACK (1 << 0) // set to clear pending interrupt + +#define I2C_ST_RXACK (1 << 7) // Received acknowledgement from slave (1 = NAK, 0 = ACK) +#define I2C_ST_BUSY \ + (1 << 6) // 1 after START signal detected; 0 after STOP signal detected +#define I2C_ST_AL (1 << 5) // Arbitration lost. 1 when core lost arbitration +#define I2C_ST_RSVD_4 (1 << 4) // reserved +#define I2C_ST_RSVD_3 (1 << 3) // reserved +#define I2C_ST_RSVD_2 (1 << 2) // reserved +#define I2C_ST_TIP (1 << 1) // Transfer-in-progress +#define I2C_ST_IP (1 << 0) // Interrupt pending using namespace uhd; -i2c_core_200::~i2c_core_200(void){ +i2c_core_200::~i2c_core_200(void) +{ /* NOP */ } -class i2c_core_200_impl : public i2c_core_200{ +class i2c_core_200_impl : public i2c_core_200 +{ public: - i2c_core_200_impl(wb_iface::sptr iface, const size_t base, const size_t readback): - _iface(iface), _base(base), _readback(readback) + i2c_core_200_impl(wb_iface::sptr iface, const size_t base, const size_t readback) + : _iface(iface), _base(base), _readback(readback) { - //init I2C FPGA interface. + // init I2C FPGA interface. this->poke(REG_I2C_WR_CTRL, 0x0000); - //set prescalers to operate at 400kHz: WB_CLK is 64MHz... + // set prescalers to operate at 400kHz: WB_CLK is 64MHz... static const uint32_t i2c_datarate = 400000; - static const uint32_t wishbone_clk = 64000000; //FIXME should go somewhere else - uint16_t prescaler = wishbone_clk / (i2c_datarate*5) - 1; + static const uint32_t wishbone_clk = 64000000; // FIXME should go somewhere else + uint16_t prescaler = wishbone_clk / (i2c_datarate * 5) - 1; this->poke(REG_I2C_WR_PRESCALER_LO, prescaler & 0xFF); this->poke(REG_I2C_WR_PRESCALER_HI, (prescaler >> 8) & 0xFF); - this->poke(REG_I2C_WR_CTRL, I2C_CTRL_EN); //enable I2C core + this->poke(REG_I2C_WR_CTRL, I2C_CTRL_EN); // enable I2C core } - void write_i2c( - uint16_t addr, - const byte_vector_t &bytes - ){ - this->poke(REG_I2C_WR_DATA, (addr << 1) | 0); //addr and read bit (0) - this->poke(REG_I2C_WR_CMD, I2C_CMD_WR | I2C_CMD_START | (bytes.size() == 0 ? I2C_CMD_STOP : 0)); + void write_i2c(uint16_t addr, const byte_vector_t& bytes) + { + this->poke(REG_I2C_WR_DATA, (addr << 1) | 0); // addr and read bit (0) + this->poke(REG_I2C_WR_CMD, + I2C_CMD_WR | I2C_CMD_START | (bytes.size() == 0 ? I2C_CMD_STOP : 0)); - //wait for previous transfer to complete + // wait for previous transfer to complete if (not wait_chk_ack()) { this->poke(REG_I2C_WR_CMD, I2C_CMD_STOP); return; @@ -82,33 +84,34 @@ public: for (size_t i = 0; i < bytes.size(); i++) { this->poke(REG_I2C_WR_DATA, bytes[i]); - this->poke(REG_I2C_WR_CMD, I2C_CMD_WR | ((i == (bytes.size() - 1)) ? I2C_CMD_STOP : 0)); - if(!wait_chk_ack()) { + this->poke(REG_I2C_WR_CMD, + I2C_CMD_WR | ((i == (bytes.size() - 1)) ? I2C_CMD_STOP : 0)); + if (!wait_chk_ack()) { this->poke(REG_I2C_WR_CMD, I2C_CMD_STOP); return; } } } - byte_vector_t read_i2c( - uint16_t addr, - size_t num_bytes - ){ + byte_vector_t read_i2c(uint16_t addr, size_t num_bytes) + { byte_vector_t bytes; - if (num_bytes == 0) return bytes; + if (num_bytes == 0) + return bytes; - while (this->peek(REG_I2C_RD_ST) & I2C_ST_BUSY){ + while (this->peek(REG_I2C_RD_ST) & I2C_ST_BUSY) { /* NOP */ } - this->poke(REG_I2C_WR_DATA, (addr << 1) | 1); //addr and read bit (1) + this->poke(REG_I2C_WR_DATA, (addr << 1) | 1); // addr and read bit (1) this->poke(REG_I2C_WR_CMD, I2C_CMD_WR | I2C_CMD_START); - //wait for previous transfer to complete + // wait for previous transfer to complete if (not wait_chk_ack()) { this->poke(REG_I2C_WR_CMD, I2C_CMD_STOP); } for (size_t i = 0; i < num_bytes; i++) { - this->poke(REG_I2C_WR_CMD, I2C_CMD_RD | ((num_bytes == i+1) ? (I2C_CMD_STOP | I2C_CMD_NACK) : 0)); + this->poke(REG_I2C_WR_CMD, + I2C_CMD_RD | ((num_bytes == i + 1) ? (I2C_CMD_STOP | I2C_CMD_NACK) : 0)); i2c_wait(); bytes.push_back(this->peek(REG_I2C_RD_DATA)); } @@ -116,15 +119,18 @@ public: } private: - void i2c_wait(void) { - for (size_t i = 0; i < 100; i++){ - if ((this->peek(REG_I2C_RD_ST) & I2C_ST_TIP) == 0) return; + void i2c_wait(void) + { + for (size_t i = 0; i < 100; i++) { + if ((this->peek(REG_I2C_RD_ST) & I2C_ST_TIP) == 0) + return; std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - UHD_LOGGER_ERROR("CORES") << "i2c_core_200: i2c_wait timeout" ; + UHD_LOGGER_ERROR("CORES") << "i2c_core_200: i2c_wait timeout"; } - bool wait_chk_ack(void){ + bool wait_chk_ack(void) + { i2c_wait(); return (this->peek(REG_I2C_RD_ST) & I2C_ST_RXACK) == 0; } @@ -148,6 +154,8 @@ private: boost::mutex _mutex; }; -i2c_core_200::sptr i2c_core_200::make(wb_iface::sptr iface, const size_t base, const size_t readback){ +i2c_core_200::sptr i2c_core_200::make( + wb_iface::sptr iface, const size_t base, const size_t readback) +{ return sptr(new i2c_core_200_impl(iface, base, readback)); } diff --git a/host/lib/usrp/cores/radio_ctrl_core_3000.cpp b/host/lib/usrp/cores/radio_ctrl_core_3000.cpp index 15226e8c4..7518bfe6f 100644 --- a/host/lib/usrp/cores/radio_ctrl_core_3000.cpp +++ b/host/lib/usrp/cores/radio_ctrl_core_3000.cpp @@ -6,16 +6,16 @@ // #include <uhd/exception.hpp> -#include <uhd/utils/log.hpp> -#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 <uhd/utils/byteswap.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/safe_call.hpp> #include <uhdlib/usrp/common/async_packet_handler.hpp> #include <uhdlib/usrp/cores/radio_ctrl_core_3000.hpp> +#include <boost/format.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/thread.hpp> -#include <boost/format.hpp> #include <functional> #include <queue> @@ -23,43 +23,49 @@ using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; -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 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; -radio_ctrl_core_3000::~radio_ctrl_core_3000(void){ +radio_ctrl_core_3000::~radio_ctrl_core_3000(void) +{ /* NOP */ } -class radio_ctrl_core_3000_impl: public radio_ctrl_core_3000 +class radio_ctrl_core_3000_impl : public radio_ctrl_core_3000 { public: - radio_ctrl_core_3000_impl(const bool big_endian, - uhd::transport::zero_copy_if::sptr ctrl_xport, - uhd::transport::zero_copy_if::sptr resp_xport, - const uint32_t sid, const std::string &name) : - _link_type(vrt::if_packet_info_t::LINK_TYPE_CHDR), _packet_type( - vrt::if_packet_info_t::PACKET_TYPE_CONTEXT), _bige( - big_endian), _ctrl_xport(ctrl_xport), _resp_xport( - resp_xport), _sid(sid), _name(name), _seq_out(0), _timeout( - ACK_TIMEOUT), _resp_queue(128/*max response msgs*/), _resp_queue_size( - _resp_xport ? _resp_xport->get_num_recv_frames() : 3) + uhd::transport::zero_copy_if::sptr ctrl_xport, + uhd::transport::zero_copy_if::sptr resp_xport, + const uint32_t sid, + const std::string& name) + : _link_type(vrt::if_packet_info_t::LINK_TYPE_CHDR) + , _packet_type(vrt::if_packet_info_t::PACKET_TYPE_CONTEXT) + , _bige(big_endian) + , _ctrl_xport(ctrl_xport) + , _resp_xport(resp_xport) + , _sid(sid) + , _name(name) + , _seq_out(0) + , _timeout(ACK_TIMEOUT) + , _resp_queue(128 /*max response msgs*/) + , _resp_queue_size(_resp_xport ? _resp_xport->get_num_recv_frames() : 3) { - if (resp_xport) - { - while (resp_xport->get_recv_buff(0.0)) {} //flush + if (resp_xport) { + while (resp_xport->get_recv_buff(0.0)) { + } // flush } this->set_time(uhd::time_spec_t(0.0)); - this->set_tick_rate(1.0); //something possible but bogus + this->set_tick_rate(1.0); // something possible but bogus } ~radio_ctrl_core_3000_impl(void) { - _timeout = ACK_TIMEOUT; //reset timeout to something small + _timeout = ACK_TIMEOUT; // reset timeout to something small UHD_SAFE_CALL( - this->peek32(0);//dummy peek with the purpose of ack'ing all packets - _async_task.reset();//now its ok to release the task + this->peek32(0); // dummy peek with the purpose of ack'ing all packets + _async_task.reset(); // now its ok to release the task ) } @@ -69,36 +75,37 @@ public: void poke32(const wb_addr_type addr, const uint32_t data) { boost::mutex::scoped_lock lock(_mutex); - this->send_pkt(addr/4, data); + this->send_pkt(addr / 4, data); this->wait_for_ack(false); } uint32_t peek32(const wb_addr_type addr) { boost::mutex::scoped_lock lock(_mutex); - this->send_pkt(SR_READBACK, addr/8); + this->send_pkt(SR_READBACK, addr / 8); const uint64_t res = this->wait_for_ack(true); - const uint32_t lo = uint32_t(res & 0xffffffff); - const uint32_t hi = uint32_t(res >> 32); - return ((addr/4) & 0x1)? hi : lo; + const uint32_t lo = uint32_t(res & 0xffffffff); + const uint32_t hi = uint32_t(res >> 32); + return ((addr / 4) & 0x1) ? hi : lo; } uint64_t peek64(const wb_addr_type addr) { boost::mutex::scoped_lock lock(_mutex); - this->send_pkt(SR_READBACK, addr/8); + this->send_pkt(SR_READBACK, addr / 8); return this->wait_for_ack(true); } /******************************************************************* * Update methods for time ******************************************************************/ - void set_time(const uhd::time_spec_t &time) + void set_time(const uhd::time_spec_t& time) { boost::mutex::scoped_lock lock(_mutex); - _time = time; + _time = time; _use_time = _time != uhd::time_spec_t(0.0); - if (_use_time) _timeout = MASSIVE_TIMEOUT; //permanently sets larger timeout + if (_use_time) + _timeout = MASSIVE_TIMEOUT; // permanently sets larger timeout } uhd::time_spec_t get_time(void) @@ -129,76 +136,77 @@ private: if (not buff) { throw uhd::runtime_error("fifo ctrl timed out getting a send buffer"); } - uint32_t *pkt = buff->cast<uint32_t *>(); + uint32_t* pkt = buff->cast<uint32_t*>(); - //load packet info + // load packet info vrt::if_packet_info_t packet_info; - packet_info.link_type = _link_type; - packet_info.packet_type = _packet_type; + packet_info.link_type = _link_type; + packet_info.packet_type = _packet_type; packet_info.num_payload_words32 = 2; - packet_info.num_payload_bytes = packet_info.num_payload_words32*sizeof(uint32_t); + packet_info.num_payload_bytes = + packet_info.num_payload_words32 * sizeof(uint32_t); packet_info.packet_count = _seq_out; - packet_info.tsf = _time.to_ticks(_tick_rate); - packet_info.sob = false; - packet_info.eob = false; - packet_info.sid = _sid; - packet_info.has_sid = true; - packet_info.has_cid = false; - packet_info.has_tsi = false; - packet_info.has_tsf = _use_time; - packet_info.has_tlr = false; - - //load header - if (_bige) vrt::if_hdr_pack_be(pkt, packet_info); - else vrt::if_hdr_pack_le(pkt, packet_info); - - //load payload - pkt[packet_info.num_header_words32+0] = (_bige)? uhd::htonx(addr) : uhd::htowx(addr); - pkt[packet_info.num_header_words32+1] = (_bige)? uhd::htonx(data) : uhd::htowx(data); - //UHD_LOGGER_INFO("radio_ctrl") << boost::format("0x%08x, 0x%08x\n") % addr % data; - //send the buffer over the interface + packet_info.tsf = _time.to_ticks(_tick_rate); + packet_info.sob = false; + packet_info.eob = false; + packet_info.sid = _sid; + packet_info.has_sid = true; + packet_info.has_cid = false; + packet_info.has_tsi = false; + packet_info.has_tsf = _use_time; + packet_info.has_tlr = false; + + // load header + if (_bige) + vrt::if_hdr_pack_be(pkt, packet_info); + else + vrt::if_hdr_pack_le(pkt, packet_info); + + // load payload + pkt[packet_info.num_header_words32 + 0] = (_bige) ? uhd::htonx(addr) + : uhd::htowx(addr); + pkt[packet_info.num_header_words32 + 1] = (_bige) ? uhd::htonx(data) + : uhd::htowx(data); + // UHD_LOGGER_INFO("radio_ctrl") << boost::format("0x%08x, 0x%08x\n") % addr % + // data; send the buffer over the interface _outstanding_seqs.push(_seq_out); - buff->commit(sizeof(uint32_t)*(packet_info.num_packet_words32)); + buff->commit(sizeof(uint32_t) * (packet_info.num_packet_words32)); - _seq_out++;//inc seq for next call + _seq_out++; // inc seq for next call } UHD_INLINE uint64_t wait_for_ack(const bool readback) { - while (readback or (_outstanding_seqs.size() >= _resp_queue_size)) - { - //get seq to ack from outstanding packets list + while (readback or (_outstanding_seqs.size() >= _resp_queue_size)) { + // get seq to ack from outstanding packets list UHD_ASSERT_THROW(not _outstanding_seqs.empty()); const size_t seq_to_ack = _outstanding_seqs.front(); _outstanding_seqs.pop(); - //parse the packet + // parse the packet vrt::if_packet_info_t packet_info; resp_buff_type resp_buff; memset(&resp_buff, 0x00, sizeof(resp_buff)); - uint32_t const *pkt = NULL; + uint32_t const* pkt = NULL; managed_recv_buffer::sptr buff; - //get buffer from response endpoint - or die in timeout - if (_resp_xport) - { + // get buffer from response endpoint - or die in timeout + if (_resp_xport) { buff = _resp_xport->get_recv_buff(_timeout); - try - { + try { UHD_ASSERT_THROW(bool(buff)); UHD_ASSERT_THROW(buff->size() > 0); + } catch (const std::exception& ex) { + throw uhd::io_error( + str(boost::format("Radio ctrl (%s) no response packet - %s") + % _name % ex.what())); } - catch(const std::exception &ex) - { - throw uhd::io_error(str(boost::format("Radio ctrl (%s) no response packet - %s") % _name % ex.what())); - } - pkt = buff->cast<const uint32_t *>(); - packet_info.num_packet_words32 = buff->size()/sizeof(uint32_t); + pkt = buff->cast<const uint32_t*>(); + packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t); } - //get buffer from response endpoint - or die in timeout - else - { + // get buffer from response endpoint - or die in timeout + else { /* * Couldn't get message with haste. * Now check both possible queues for messages. @@ -206,12 +214,12 @@ private: * but could end up in dump_queue. * If we don't get a message --> Die in timeout. */ - double accum_timeout = 0.0; + double accum_timeout = 0.0; const double short_timeout = 0.005; // == 5ms - while(not ((_resp_queue.pop_with_haste(resp_buff)) + while ( + not((_resp_queue.pop_with_haste(resp_buff)) || (check_dump_queue(resp_buff)) - || (_resp_queue.pop_with_timed_wait(resp_buff, short_timeout)) - )){ + || (_resp_queue.pop_with_timed_wait(resp_buff, short_timeout)))) { /* * If a message couldn't be received within a given timeout * --> throw AssertionError! @@ -220,51 +228,53 @@ private: UHD_ASSERT_THROW(accum_timeout < _timeout); } - pkt = resp_buff.data; - packet_info.num_packet_words32 = sizeof(resp_buff)/sizeof(uint32_t); + pkt = resp_buff.data; + packet_info.num_packet_words32 = sizeof(resp_buff) / sizeof(uint32_t); } - //parse the buffer - try - { + // parse the buffer + try { packet_info.link_type = _link_type; - if (_bige) vrt::if_hdr_unpack_be(pkt, packet_info); - else vrt::if_hdr_unpack_le(pkt, packet_info); - } - catch(const std::exception &ex) - { - UHD_LOGGER_ERROR("radio_ctrl") << "Radio ctrl bad VITA packet: " << ex.what() ; - if (buff){ + if (_bige) + vrt::if_hdr_unpack_be(pkt, packet_info); + else + vrt::if_hdr_unpack_le(pkt, packet_info); + } catch (const std::exception& ex) { + UHD_LOGGER_ERROR("radio_ctrl") + << "Radio ctrl bad VITA packet: " << ex.what(); + if (buff) { UHD_VAR(buff->size()); + } else { + UHD_LOGGER_INFO("radio_ctrl") << "buff is NULL"; } - else{ - UHD_LOGGER_INFO("radio_ctrl") << "buff is NULL" ; - } - UHD_LOGGER_INFO("radio_ctrl") << std::hex << pkt[0] << std::dec ; - UHD_LOGGER_INFO("radio_ctrl") << std::hex << pkt[1] << std::dec ; - UHD_LOGGER_INFO("radio_ctrl") << std::hex << pkt[2] << std::dec ; - UHD_LOGGER_INFO("radio_ctrl") << std::hex << pkt[3] << std::dec ; + UHD_LOGGER_INFO("radio_ctrl") << std::hex << pkt[0] << std::dec; + UHD_LOGGER_INFO("radio_ctrl") << std::hex << pkt[1] << std::dec; + UHD_LOGGER_INFO("radio_ctrl") << std::hex << pkt[2] << std::dec; + UHD_LOGGER_INFO("radio_ctrl") << std::hex << pkt[3] << std::dec; } - //check the buffer - try - { + // check the buffer + try { UHD_ASSERT_THROW(packet_info.has_sid); - UHD_ASSERT_THROW(packet_info.sid == uint32_t((_sid >> 16) | (_sid << 16))); + UHD_ASSERT_THROW( + packet_info.sid == uint32_t((_sid >> 16) | (_sid << 16))); UHD_ASSERT_THROW(packet_info.packet_count == (seq_to_ack & 0xfff)); UHD_ASSERT_THROW(packet_info.num_payload_words32 == 2); UHD_ASSERT_THROW(packet_info.packet_type == _packet_type); - } - catch(const std::exception &ex) - { - throw uhd::io_error(str(boost::format("Radio ctrl (%s) packet parse error - %s") % _name % ex.what())); + } catch (const std::exception& ex) { + throw uhd::io_error( + str(boost::format("Radio ctrl (%s) packet parse error - %s") % _name + % ex.what())); } - //return the readback value - if (readback and _outstanding_seqs.empty()) - { - const uint64_t hi = (_bige)? uhd::ntohx(pkt[packet_info.num_header_words32+0]) : uhd::wtohx(pkt[packet_info.num_header_words32+0]); - const uint64_t lo = (_bige)? uhd::ntohx(pkt[packet_info.num_header_words32+1]) : uhd::wtohx(pkt[packet_info.num_header_words32+1]); + // return the readback value + if (readback and _outstanding_seqs.empty()) { + const uint64_t hi = + (_bige) ? uhd::ntohx(pkt[packet_info.num_header_words32 + 0]) + : uhd::wtohx(pkt[packet_info.num_header_words32 + 0]); + const uint64_t lo = + (_bige) ? uhd::ntohx(pkt[packet_info.num_header_words32 + 1]) + : uhd::wtohx(pkt[packet_info.num_header_words32 + 1]); return ((hi << 32) | lo); } } @@ -273,30 +283,31 @@ private: } /* - * If ctrl_core waits for a message that didn't arrive it can search for it in the dump queue. - * This actually happens during shutdown. - * handle_async_task can't access radio_ctrl_cores queue anymore thus it returns the corresponding message. - * msg_task class implements a dump_queue to store such messages. - * With check_dump_queue we can check if a message we are waiting for got stranded there. - * If a message got stuck we get it here and push it onto our own message_queue. + * If ctrl_core waits for a message that didn't arrive it can search for it in the + * dump queue. This actually happens during shutdown. handle_async_task can't access + * radio_ctrl_cores queue anymore thus it returns the corresponding message. msg_task + * class implements a dump_queue to store such messages. With check_dump_queue we can + * check if a message we are waiting for got stranded there. If a message got stuck we + * get it here and push it onto our own message_queue. */ - bool check_dump_queue(resp_buff_type& b) { - const size_t min_buff_size = 8; // Same value as in b200_io_impl->handle_async_task - uint32_t recv_sid = (((_sid)<<16)|((_sid)>>16)); + bool check_dump_queue(resp_buff_type& b) + { + const size_t min_buff_size = + 8; // Same value as in b200_io_impl->handle_async_task + uint32_t recv_sid = (((_sid) << 16) | ((_sid) >> 16)); uhd::msg_task::msg_payload_t msg; - do{ + do { msg = _async_task->get_msg_from_dump_queue(recv_sid); - } - while(msg.size() < min_buff_size && msg.size() != 0); + } while (msg.size() < min_buff_size && msg.size() != 0); - if(msg.size() >= min_buff_size) { + if (msg.size() >= min_buff_size) { memcpy(b.data, &msg.front(), std::min(msg.size(), sizeof(b.data))); return true; } return false; } - void push_response(const uint32_t *buff) + void push_response(const uint32_t* buff) { resp_buff_type resp_buff; std::memcpy(resp_buff.data, buff, sizeof(resp_buff)); @@ -328,10 +339,11 @@ private: }; radio_ctrl_core_3000::sptr radio_ctrl_core_3000::make(const bool big_endian, - zero_copy_if::sptr ctrl_xport, zero_copy_if::sptr resp_xport, - const uint32_t sid, const std::string &name) + zero_copy_if::sptr ctrl_xport, + zero_copy_if::sptr resp_xport, + const uint32_t sid, + const std::string& name) { return sptr( - new radio_ctrl_core_3000_impl(big_endian, ctrl_xport, resp_xport, - sid, name)); + new radio_ctrl_core_3000_impl(big_endian, ctrl_xport, resp_xport, sid, name)); } diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index 700a3c207..89b44290f 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -5,73 +5,78 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/types/dict.hpp> #include <uhd/exception.hpp> -#include <uhd/utils/math.hpp> +#include <uhd/types/dict.hpp> #include <uhd/utils/log.hpp> +#include <uhd/utils/math.hpp> #include <uhd/utils/safe_call.hpp> -#include <uhdlib/usrp/cores/rx_dsp_core_200.hpp> #include <uhdlib/usrp/cores/dsp_core_utils.hpp> +#include <uhdlib/usrp/cores/rx_dsp_core_200.hpp> #include <boost/assign/list_of.hpp> #include <boost/math/special_functions/round.hpp> #include <boost/numeric/conversion/bounds.hpp> #include <algorithm> -#include <cmath> #include <chrono> +#include <cmath> #include <thread> #include <tuple> -#define REG_DSP_RX_FREQ _dsp_base + 0 -#define REG_DSP_RX_SCALE_IQ _dsp_base + 4 -#define REG_DSP_RX_DECIM _dsp_base + 8 -#define REG_DSP_RX_MUX _dsp_base + 12 +#define REG_DSP_RX_FREQ _dsp_base + 0 +#define REG_DSP_RX_SCALE_IQ _dsp_base + 4 +#define REG_DSP_RX_DECIM _dsp_base + 8 +#define REG_DSP_RX_MUX _dsp_base + 12 -#define FLAG_DSP_RX_MUX_SWAP_IQ (1 << 0) +#define FLAG_DSP_RX_MUX_SWAP_IQ (1 << 0) #define FLAG_DSP_RX_MUX_REAL_MODE (1 << 1) -#define REG_RX_CTRL_STREAM_CMD _ctrl_base + 0 -#define REG_RX_CTRL_TIME_HI _ctrl_base + 4 -#define REG_RX_CTRL_TIME_LO _ctrl_base + 8 -#define REG_RX_CTRL_FORMAT _ctrl_base + 12 -#define REG_RX_CTRL_VRT_HDR _ctrl_base + 16 -#define REG_RX_CTRL_VRT_SID _ctrl_base + 20 -#define REG_RX_CTRL_VRT_TLR _ctrl_base + 24 -#define REG_RX_CTRL_NSAMPS_PP _ctrl_base + 28 -#define REG_RX_CTRL_NCHANNELS _ctrl_base + 32 - -template <class T> T ceil_log2(T num){ - return std::ceil(std::log(num)/std::log(T(2))); +#define REG_RX_CTRL_STREAM_CMD _ctrl_base + 0 +#define REG_RX_CTRL_TIME_HI _ctrl_base + 4 +#define REG_RX_CTRL_TIME_LO _ctrl_base + 8 +#define REG_RX_CTRL_FORMAT _ctrl_base + 12 +#define REG_RX_CTRL_VRT_HDR _ctrl_base + 16 +#define REG_RX_CTRL_VRT_SID _ctrl_base + 20 +#define REG_RX_CTRL_VRT_TLR _ctrl_base + 24 +#define REG_RX_CTRL_NSAMPS_PP _ctrl_base + 28 +#define REG_RX_CTRL_NCHANNELS _ctrl_base + 32 + +template <class T> +T ceil_log2(T num) +{ + return std::ceil(std::log(num) / std::log(T(2))); } using namespace uhd; -rx_dsp_core_200::~rx_dsp_core_200(void){ +rx_dsp_core_200::~rx_dsp_core_200(void) +{ /* NOP */ } -class rx_dsp_core_200_impl : public rx_dsp_core_200{ +class rx_dsp_core_200_impl : public rx_dsp_core_200 +{ public: - rx_dsp_core_200_impl( - wb_iface::sptr iface, - const size_t dsp_base, const size_t ctrl_base, - const uint32_t sid, const bool lingering_packet - ): - _iface(iface), _dsp_base(dsp_base), _ctrl_base(ctrl_base), _sid(sid) + rx_dsp_core_200_impl(wb_iface::sptr iface, + const size_t dsp_base, + const size_t ctrl_base, + const uint32_t sid, + const bool lingering_packet) + : _iface(iface), _dsp_base(dsp_base), _ctrl_base(ctrl_base), _sid(sid) { // previously uninitialized - assuming zero for all _tick_rate = _link_rate = _host_extra_scaling = _fxpt_scalar_correction = 0.0; - //init to something so update method has reasonable defaults + // init to something so update method has reasonable defaults _scaling_adjustment = 1.0; - _dsp_extra_scaling = 1.0; + _dsp_extra_scaling = 1.0; - //This is a hack/fix for the lingering packet problem. - //The caller should also flush the recv transports - if (lingering_packet){ + // This is a hack/fix for the lingering packet problem. + // The caller should also flush the recv transports + if (lingering_packet) { stream_cmd_t stream_cmd(stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); stream_cmd.num_samps = 1; issue_stream_command(stream_cmd); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); //lets lingering pkt propagate + std::this_thread::sleep_for( + std::chrono::milliseconds(10)); // lets lingering pkt propagate } this->clear(); @@ -79,143 +84,164 @@ public: ~rx_dsp_core_200_impl(void) { - UHD_SAFE_CALL - ( - //shutdown any possible streaming - this->clear(); - ) + UHD_SAFE_CALL( + // shutdown any possible streaming + this->clear();) } - void clear(void){ - _iface->poke32(REG_RX_CTRL_NCHANNELS, 0); //also reset - _iface->poke32(REG_RX_CTRL_VRT_HDR, 0 - | (0x1 << 28) //if data with stream id - | (0x1 << 26) //has trailer - | (0x1 << 20) //fractional time sample count + void clear(void) + { + _iface->poke32(REG_RX_CTRL_NCHANNELS, 0); // also reset + _iface->poke32(REG_RX_CTRL_VRT_HDR, + 0 | (0x1 << 28) // if data with stream id + | (0x1 << 26) // has trailer + | (0x1 << 20) // fractional time sample count ); _iface->poke32(REG_RX_CTRL_VRT_SID, _sid); _iface->poke32(REG_RX_CTRL_VRT_TLR, 0); } - void set_nsamps_per_packet(const size_t nsamps){ + void set_nsamps_per_packet(const size_t nsamps) + { _iface->poke32(REG_RX_CTRL_NSAMPS_PP, nsamps); } - void issue_stream_command(const stream_cmd_t &stream_cmd){ + void issue_stream_command(const stream_cmd_t& stream_cmd) + { UHD_ASSERT_THROW(stream_cmd.num_samps <= 0x0fffffff); - _continuous_streaming = stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS; + _continuous_streaming = stream_cmd.stream_mode + == stream_cmd_t::STREAM_MODE_START_CONTINUOUS; - //setup the mode to instruction flags + // setup the mode to instruction flags typedef std::tuple<bool, bool, bool, bool> inst_t; - static const uhd::dict<stream_cmd_t::stream_mode_t, inst_t> mode_to_inst = boost::assign::map_list_of - //reload, chain, samps, stop - (stream_cmd_t::STREAM_MODE_START_CONTINUOUS, inst_t(true, true, false, false)) - (stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS, inst_t(false, false, false, true)) - (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE, inst_t(false, false, true, false)) - (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE, inst_t(false, true, true, false)) - ; - - //setup the instruction flag values + static const uhd::dict<stream_cmd_t::stream_mode_t, inst_t> mode_to_inst = + boost::assign::map_list_of + // reload, chain, samps, stop + (stream_cmd_t::STREAM_MODE_START_CONTINUOUS, + inst_t(true, true, false, false))( + stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS, + inst_t(false, false, false, true))( + stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE, + inst_t(false, false, true, false))( + stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE, + inst_t(false, true, true, false)); + + // setup the instruction flag values bool inst_reload, inst_chain, inst_samps, inst_stop; - std::tie(inst_reload, inst_chain, inst_samps, inst_stop) = mode_to_inst[stream_cmd.stream_mode]; + std::tie(inst_reload, inst_chain, inst_samps, inst_stop) = + mode_to_inst[stream_cmd.stream_mode]; - //calculate the word from flags and length + // calculate the word from flags and length uint32_t cmd_word = 0; - cmd_word |= uint32_t((stream_cmd.stream_now)? 1 : 0) << 31; - cmd_word |= uint32_t((inst_chain)? 1 : 0) << 30; - cmd_word |= uint32_t((inst_reload)? 1 : 0) << 29; - cmd_word |= uint32_t((inst_stop)? 1 : 0) << 28; - cmd_word |= (inst_samps)? stream_cmd.num_samps : ((inst_stop)? 0 : 1); + cmd_word |= uint32_t((stream_cmd.stream_now) ? 1 : 0) << 31; + cmd_word |= uint32_t((inst_chain) ? 1 : 0) << 30; + cmd_word |= uint32_t((inst_reload) ? 1 : 0) << 29; + cmd_word |= uint32_t((inst_stop) ? 1 : 0) << 28; + cmd_word |= (inst_samps) ? stream_cmd.num_samps : ((inst_stop) ? 0 : 1); - //issue the stream command + // issue the stream command _iface->poke32(REG_RX_CTRL_STREAM_CMD, cmd_word); - const uint64_t ticks = (stream_cmd.stream_now)? 0 : stream_cmd.time_spec.to_ticks(_tick_rate); + const uint64_t ticks = + (stream_cmd.stream_now) ? 0 : stream_cmd.time_spec.to_ticks(_tick_rate); _iface->poke32(REG_RX_CTRL_TIME_HI, uint32_t(ticks >> 32)); - _iface->poke32(REG_RX_CTRL_TIME_LO, uint32_t(ticks >> 0)); //latches the command + _iface->poke32(REG_RX_CTRL_TIME_LO, uint32_t(ticks >> 0)); // latches the command } - void set_mux(const std::string &mode, const bool fe_swapped){ - static const uhd::dict<std::string, uint32_t> mode_to_mux = boost::assign::map_list_of - ("IQ", 0) - ("QI", FLAG_DSP_RX_MUX_SWAP_IQ) - ("I", FLAG_DSP_RX_MUX_REAL_MODE) - ("Q", FLAG_DSP_RX_MUX_SWAP_IQ | FLAG_DSP_RX_MUX_REAL_MODE) - ; - _iface->poke32(REG_DSP_RX_MUX, mode_to_mux[mode] ^ (fe_swapped? FLAG_DSP_RX_MUX_SWAP_IQ : 0)); + void set_mux(const std::string& mode, const bool fe_swapped) + { + static const uhd::dict<std::string, uint32_t> mode_to_mux = + boost::assign::map_list_of("IQ", 0)("QI", FLAG_DSP_RX_MUX_SWAP_IQ)( + "I", FLAG_DSP_RX_MUX_REAL_MODE)( + "Q", FLAG_DSP_RX_MUX_SWAP_IQ | FLAG_DSP_RX_MUX_REAL_MODE); + _iface->poke32(REG_DSP_RX_MUX, + mode_to_mux[mode] ^ (fe_swapped ? FLAG_DSP_RX_MUX_SWAP_IQ : 0)); } - void set_tick_rate(const double rate){ + void set_tick_rate(const double rate) + { _tick_rate = rate; } - void set_link_rate(const double rate){ + void set_link_rate(const double rate) + { //_link_rate = rate/sizeof(uint32_t); //in samps/s - _link_rate = rate/sizeof(uint16_t); //in samps/s (allows for 8sc) + _link_rate = rate / sizeof(uint16_t); // in samps/s (allows for 8sc) } - uhd::meta_range_t get_host_rates(void){ + uhd::meta_range_t get_host_rates(void) + { meta_range_t range; - for (int rate = 512; rate > 256; rate -= 4){ - range.push_back(range_t(_tick_rate/rate)); + for (int rate = 512; rate > 256; rate -= 4) { + range.push_back(range_t(_tick_rate / rate)); } - for (int rate = 256; rate > 128; rate -= 2){ - range.push_back(range_t(_tick_rate/rate)); + for (int rate = 256; rate > 128; rate -= 2) { + range.push_back(range_t(_tick_rate / rate)); } - for (int rate = 128; rate >= int(std::ceil(_tick_rate/_link_rate)); rate -= 1){ - range.push_back(range_t(_tick_rate/rate)); + for (int rate = 128; rate >= int(std::ceil(_tick_rate / _link_rate)); rate -= 1) { + range.push_back(range_t(_tick_rate / rate)); } return range; } - double set_host_rate(const double rate){ - const size_t decim_rate = boost::math::iround(_tick_rate/this->get_host_rates().clip(rate, true)); + double set_host_rate(const double rate) + { + const size_t decim_rate = + boost::math::iround(_tick_rate / this->get_host_rates().clip(rate, true)); size_t decim = decim_rate; - //determine which half-band filters are activated + // determine which half-band filters are activated int hb0 = 0, hb1 = 0; - // hb0 can only be enabled if the rate will be decimated by at least 2 between the CIC and hb1 - if (decim >= 4 && decim % 2 == 0){ + // hb0 can only be enabled if the rate will be decimated by at least 2 between the + // CIC and hb1 + if (decim >= 4 && decim % 2 == 0) { hb0 = 1; decim /= 2; } - if (decim % 2 == 0){ + if (decim % 2 == 0) { hb1 = 1; decim /= 2; } _iface->poke32(REG_DSP_RX_DECIM, (hb1 << 9) | (hb0 << 8) | (decim & 0xff)); - if (decim > 1 and hb0 == 0 and hb1 == 0) - { - UHD_LOGGER_WARNING("CORES") << boost::format( - "The requested decimation is odd; the user should expect CIC rolloff.\n" - "Select an even decimation to ensure that a halfband filter is enabled.\n" - "decimation = dsp_rate/samp_rate -> %d = (%f MHz)/(%f MHz)\n" - ) % decim_rate % (_tick_rate/1e6) % (rate/1e6); + if (decim > 1 and hb0 == 0 and hb1 == 0) { + UHD_LOGGER_WARNING("CORES") + << boost::format( + "The requested decimation is odd; the user should expect CIC " + "rolloff.\n" + "Select an even decimation to ensure that a halfband filter is " + "enabled.\n" + "decimation = dsp_rate/samp_rate -> %d = (%f MHz)/(%f MHz)\n") + % decim_rate % (_tick_rate / 1e6) % (rate / 1e6); } // Calculate CIC decimation (i.e., without halfband decimators) // Calculate closest multiplier constant to reverse gain absent scale multipliers const double rate_pow = std::pow(double(decim & 0xff), 4); - _scaling_adjustment = std::pow(2, ceil_log2(rate_pow))/(1.65*rate_pow); + _scaling_adjustment = std::pow(2, ceil_log2(rate_pow)) / (1.65 * rate_pow); this->update_scalar(); - return _tick_rate/decim_rate; + return _tick_rate / decim_rate; } - void update_scalar(void){ + void update_scalar(void) + { const double factor = 1.0 + std::max(ceil_log2(_scaling_adjustment), 0.0); - const double target_scalar = (1 << 17)*_scaling_adjustment/_dsp_extra_scaling/factor; + const double target_scalar = + (1 << 17) * _scaling_adjustment / _dsp_extra_scaling / factor; const int32_t actual_scalar = boost::math::iround(target_scalar); - _fxpt_scalar_correction = target_scalar/actual_scalar*factor; //should be small + _fxpt_scalar_correction = + target_scalar / actual_scalar * factor; // should be small _iface->poke32(REG_DSP_RX_SCALE_IQ, actual_scalar); } - double get_scaling_adjustment(void){ - return _fxpt_scalar_correction*_host_extra_scaling/32767.; + double get_scaling_adjustment(void) + { + return _fxpt_scalar_correction * _host_extra_scaling / 32767.; } - double set_freq(const double requested_freq){ + double set_freq(const double requested_freq) + { double actual_freq; int32_t freq_word; get_freq_and_freq_word(requested_freq, _tick_rate, actual_freq, freq_word); @@ -223,31 +249,37 @@ public: return actual_freq; } - uhd::meta_range_t get_freq_range(void){ - return uhd::meta_range_t(-_tick_rate/2, +_tick_rate/2, _tick_rate/std::pow(2.0, 32)); + uhd::meta_range_t get_freq_range(void) + { + return uhd::meta_range_t( + -_tick_rate / 2, +_tick_rate / 2, _tick_rate / std::pow(2.0, 32)); } - void handle_overflow(void){ - if (_continuous_streaming) issue_stream_command(stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + void handle_overflow(void) + { + if (_continuous_streaming) + issue_stream_command(stream_cmd_t::STREAM_MODE_START_CONTINUOUS); } - void setup(const uhd::stream_args_t &stream_args){ - if (not stream_args.args.has_key("noclear")) this->clear(); + void setup(const uhd::stream_args_t& stream_args) + { + if (not stream_args.args.has_key("noclear")) + this->clear(); unsigned format_word = 0; - if (stream_args.otw_format == "sc16"){ - format_word = 0; - _dsp_extra_scaling = 1.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; - } - else throw uhd::value_error("USRP RX cannot handle requested wire format: " + stream_args.otw_format); + } 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; + } 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); @@ -262,10 +294,17 @@ private: const size_t _dsp_base, _ctrl_base; double _tick_rate, _link_rate; bool _continuous_streaming; - double _scaling_adjustment, _dsp_extra_scaling, _host_extra_scaling, _fxpt_scalar_correction; + double _scaling_adjustment, _dsp_extra_scaling, _host_extra_scaling, + _fxpt_scalar_correction; const uint32_t _sid; }; -rx_dsp_core_200::sptr rx_dsp_core_200::make(wb_iface::sptr iface, const size_t dsp_base, const size_t ctrl_base, const uint32_t sid, const bool lingering_packet){ - return sptr(new rx_dsp_core_200_impl(iface, dsp_base, ctrl_base, sid, lingering_packet)); +rx_dsp_core_200::sptr rx_dsp_core_200::make(wb_iface::sptr iface, + const size_t dsp_base, + const size_t ctrl_base, + const uint32_t sid, + const bool lingering_packet) +{ + return sptr( + new rx_dsp_core_200_impl(iface, dsp_base, ctrl_base, sid, lingering_packet)); } diff --git a/host/lib/usrp/cores/rx_dsp_core_3000.cpp b/host/lib/usrp/cores/rx_dsp_core_3000.cpp index d9ad108aa..3724ca827 100644 --- a/host/lib/usrp/cores/rx_dsp_core_3000.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_3000.cpp @@ -300,10 +300,12 @@ public: .set_publisher(std::bind(&rx_dsp_core_3000::get_host_rates, this)); subtree->create<double>("rate/value") .set(DEFAULT_RATE) - .set_coercer(std::bind(&rx_dsp_core_3000::set_host_rate, this, std::placeholders::_1)); + .set_coercer( + std::bind(&rx_dsp_core_3000::set_host_rate, this, std::placeholders::_1)); subtree->create<double>("freq/value") .set(DEFAULT_CORDIC_FREQ) - .set_coercer(std::bind(&rx_dsp_core_3000::set_freq, this, std::placeholders::_1)) + .set_coercer( + std::bind(&rx_dsp_core_3000::set_freq, this, std::placeholders::_1)) .set_publisher([this]() { return this->get_freq(); }); subtree->create<meta_range_t>("freq/range") .set_publisher(std::bind(&rx_dsp_core_3000::get_freq_range, this)); diff --git a/host/lib/usrp/cores/rx_frontend_core_200.cpp b/host/lib/usrp/cores/rx_frontend_core_200.cpp index f30da9466..b16de0d9e 100644 --- a/host/lib/usrp/cores/rx_frontend_core_200.cpp +++ b/host/lib/usrp/cores/rx_frontend_core_200.cpp @@ -12,65 +12,75 @@ using namespace uhd; -#define REG_RX_FE_SWAP_IQ _base + 0 //lower bit -#define REG_RX_FE_MAG_CORRECTION _base + 4 //18 bits -#define REG_RX_FE_PHASE_CORRECTION _base + 8 //18 bits -#define REG_RX_FE_OFFSET_I _base + 12 //18 bits -#define REG_RX_FE_OFFSET_Q _base + 16 //18 bits +#define REG_RX_FE_SWAP_IQ _base + 0 // lower bit +#define REG_RX_FE_MAG_CORRECTION _base + 4 // 18 bits +#define REG_RX_FE_PHASE_CORRECTION _base + 8 // 18 bits +#define REG_RX_FE_OFFSET_I _base + 12 // 18 bits +#define REG_RX_FE_OFFSET_Q _base + 16 // 18 bits #define OFFSET_FIXED (1ul << 31) -#define OFFSET_SET (1ul << 30) +#define OFFSET_SET (1ul << 30) #define FLAG_MASK (OFFSET_FIXED | OFFSET_SET) namespace { - static const double DC_OFFSET_MIN = -1.0; - static const double DC_OFFSET_MAX = 1.0; -} +static const double DC_OFFSET_MIN = -1.0; +static const double DC_OFFSET_MAX = 1.0; +} // namespace -static uint32_t fs_to_bits(const double num, const size_t bits){ - return int32_t(boost::math::round(num * (1 << (bits-1)))); +static uint32_t fs_to_bits(const double num, const size_t bits) +{ + return int32_t(boost::math::round(num * (1 << (bits - 1)))); } -rx_frontend_core_200::~rx_frontend_core_200(void){ +rx_frontend_core_200::~rx_frontend_core_200(void) +{ /* NOP */ } -const std::complex<double> rx_frontend_core_200::DEFAULT_DC_OFFSET_VALUE = std::complex<double>(0.0, 0.0); +const std::complex<double> rx_frontend_core_200::DEFAULT_DC_OFFSET_VALUE = + std::complex<double>(0.0, 0.0); const bool rx_frontend_core_200::DEFAULT_DC_OFFSET_ENABLE = true; -const std::complex<double> rx_frontend_core_200::DEFAULT_IQ_BALANCE_VALUE = std::complex<double>(0.0, 0.0); +const std::complex<double> rx_frontend_core_200::DEFAULT_IQ_BALANCE_VALUE = + std::complex<double>(0.0, 0.0); -class rx_frontend_core_200_impl : public rx_frontend_core_200{ +class rx_frontend_core_200_impl : public rx_frontend_core_200 +{ public: - rx_frontend_core_200_impl(wb_iface::sptr iface, const size_t base): - _i_dc_off(0), _q_dc_off(0), _iface(iface), _base(base) + rx_frontend_core_200_impl(wb_iface::sptr iface, const size_t base) + : _i_dc_off(0), _q_dc_off(0), _iface(iface), _base(base) { - //NOP + // NOP } - void set_mux(const bool swap){ - _iface->poke32(REG_RX_FE_SWAP_IQ, swap? 1 : 0); + void set_mux(const bool swap) + { + _iface->poke32(REG_RX_FE_SWAP_IQ, swap ? 1 : 0); } - void set_dc_offset_auto(const bool enb){ - this->set_dc_offset(enb? 0 : OFFSET_FIXED); + void set_dc_offset_auto(const bool enb) + { + this->set_dc_offset(enb ? 0 : OFFSET_FIXED); } - std::complex<double> set_dc_offset(const std::complex<double> &off){ + std::complex<double> set_dc_offset(const std::complex<double>& off) + { static const double scaler = double(1ul << 29); - _i_dc_off = boost::math::iround(off.real()*scaler); - _q_dc_off = boost::math::iround(off.imag()*scaler); + _i_dc_off = boost::math::iround(off.real() * scaler); + _q_dc_off = boost::math::iround(off.imag() * scaler); this->set_dc_offset(OFFSET_SET | OFFSET_FIXED); - return std::complex<double>(_i_dc_off/scaler, _q_dc_off/scaler); + return std::complex<double>(_i_dc_off / scaler, _q_dc_off / scaler); } - void set_dc_offset(const uint32_t flags){ + void set_dc_offset(const uint32_t flags) + { _iface->poke32(REG_RX_FE_OFFSET_I, flags | (_i_dc_off & ~FLAG_MASK)); _iface->poke32(REG_RX_FE_OFFSET_Q, flags | (_q_dc_off & ~FLAG_MASK)); } - void set_iq_balance(const std::complex<double> &cor){ + void set_iq_balance(const std::complex<double>& cor) + { _iface->poke32(REG_RX_FE_MAG_CORRECTION, fs_to_bits(cor.real(), 18)); _iface->poke32(REG_RX_FE_PHASE_CORRECTION, fs_to_bits(cor.imag(), 18)); } @@ -78,20 +88,19 @@ public: void populate_subtree(uhd::property_tree::sptr subtree) { subtree->create<uhd::meta_range_t>("dc_offset/range") - .set(meta_range_t(DC_OFFSET_MIN, DC_OFFSET_MAX)) - ; - subtree->create<std::complex<double> >("dc_offset/value") + .set(meta_range_t(DC_OFFSET_MIN, DC_OFFSET_MAX)); + subtree->create<std::complex<double>>("dc_offset/value") .set(DEFAULT_DC_OFFSET_VALUE) - .set_coercer(std::bind(&rx_frontend_core_200::set_dc_offset, this, std::placeholders::_1)) - ; + .set_coercer(std::bind( + &rx_frontend_core_200::set_dc_offset, this, std::placeholders::_1)); subtree->create<bool>("dc_offset/enable") .set(DEFAULT_DC_OFFSET_ENABLE) - .add_coerced_subscriber(std::bind(&rx_frontend_core_200::set_dc_offset_auto, this, std::placeholders::_1)) - ; - subtree->create<std::complex<double> >("iq_balance/value") + .add_coerced_subscriber(std::bind( + &rx_frontend_core_200::set_dc_offset_auto, this, std::placeholders::_1)); + subtree->create<std::complex<double>>("iq_balance/value") .set(DEFAULT_IQ_BALANCE_VALUE) - .add_coerced_subscriber(std::bind(&rx_frontend_core_200::set_iq_balance, this, std::placeholders::_1)) - ; + .add_coerced_subscriber(std::bind( + &rx_frontend_core_200::set_iq_balance, this, std::placeholders::_1)); } private: @@ -100,6 +109,8 @@ private: const size_t _base; }; -rx_frontend_core_200::sptr rx_frontend_core_200::make(wb_iface::sptr iface, const size_t base){ +rx_frontend_core_200::sptr rx_frontend_core_200::make( + wb_iface::sptr iface, const size_t base) +{ return sptr(new rx_frontend_core_200_impl(iface, base)); } diff --git a/host/lib/usrp/cores/rx_frontend_core_3000.cpp b/host/lib/usrp/cores/rx_frontend_core_3000.cpp index aa83b83c8..788e222ed 100644 --- a/host/lib/usrp/cores/rx_frontend_core_3000.cpp +++ b/host/lib/usrp/cores/rx_frontend_core_3000.cpp @@ -177,15 +177,16 @@ public: .set(meta_range_t(DC_OFFSET_MIN, DC_OFFSET_MAX)); subtree->create<std::complex<double>>("dc_offset/value") .set(DEFAULT_DC_OFFSET_VALUE) - .set_coercer(std::bind(&rx_frontend_core_3000::set_dc_offset, this, std::placeholders::_1)); + .set_coercer(std::bind( + &rx_frontend_core_3000::set_dc_offset, this, std::placeholders::_1)); subtree->create<bool>("dc_offset/enable") .set(DEFAULT_DC_OFFSET_ENABLE) - .add_coerced_subscriber( - std::bind(&rx_frontend_core_3000::set_dc_offset_auto, this, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &rx_frontend_core_3000::set_dc_offset_auto, this, std::placeholders::_1)); subtree->create<std::complex<double>>("iq_balance/value") .set(DEFAULT_IQ_BALANCE_VALUE) - .add_coerced_subscriber( - std::bind(&rx_frontend_core_3000::set_iq_balance, this, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &rx_frontend_core_3000::set_iq_balance, this, std::placeholders::_1)); } double get_output_rate() diff --git a/host/lib/usrp/cores/rx_vita_core_3000.cpp b/host/lib/usrp/cores/rx_vita_core_3000.cpp index 166e0d83f..8a20e637b 100644 --- a/host/lib/usrp/cores/rx_vita_core_3000.cpp +++ b/host/lib/usrp/cores/rx_vita_core_3000.cpp @@ -10,48 +10,40 @@ #include <uhdlib/usrp/cores/rx_vita_core_3000.hpp> #include <boost/assign/list_of.hpp> #include <boost/date_time.hpp> -#include <thread> #include <chrono> +#include <thread> #include <tuple> -#define REG_FRAMER_MAXLEN _base + 4*4 + 0 -#define REG_FRAMER_SID _base + 4*4 + 4 +#define REG_FRAMER_MAXLEN _base + 4 * 4 + 0 +#define REG_FRAMER_SID _base + 4 * 4 + 4 -#define REG_CTRL_CMD _base + 0 -#define REG_CTRL_TIME_HI _base + 4 -#define REG_CTRL_TIME_LO _base + 8 +#define REG_CTRL_CMD _base + 0 +#define REG_CTRL_TIME_HI _base + 4 +#define REG_CTRL_TIME_LO _base + 8 -#define REG_FC_WINDOW _base + 6*4 + 0 -#define REG_FC_ENABLE _base + 6*4 + 4 +#define REG_FC_WINDOW _base + 6 * 4 + 0 +#define REG_FC_ENABLE _base + 6 * 4 + 4 using namespace uhd; -rx_vita_core_3000::~rx_vita_core_3000(void){ +rx_vita_core_3000::~rx_vita_core_3000(void) +{ /* NOP */ } struct rx_vita_core_3000_impl : rx_vita_core_3000 { - rx_vita_core_3000_impl( - wb_iface::sptr iface, - const size_t base - ): - _iface(iface), - _base(base), - _continuous_streaming(false), - _is_setup(false) + rx_vita_core_3000_impl(wb_iface::sptr iface, const size_t base) + : _iface(iface), _base(base), _continuous_streaming(false), _is_setup(false) { - this->set_tick_rate(1); //init to non zero - this->set_nsamps_per_packet(100); //init to non zero + this->set_tick_rate(1); // init to non zero + this->set_nsamps_per_packet(100); // init to non zero this->clear(); } ~rx_vita_core_3000_impl(void) { - UHD_SAFE_CALL - ( - this->clear(); - ) + UHD_SAFE_CALL(this->clear();) } void configure_flow_control(const size_t window_size) @@ -67,15 +59,15 @@ struct rx_vita_core_3000_impl : rx_vita_core_3000 // is on the order of kilobytes std::this_thread::sleep_for(std::chrono::milliseconds(1)); - _iface->poke32(REG_FC_WINDOW, window_size-1); - _iface->poke32(REG_FC_ENABLE, window_size?1:0); + _iface->poke32(REG_FC_WINDOW, window_size - 1); + _iface->poke32(REG_FC_ENABLE, window_size ? 1 : 0); } void clear(void) { // FC should never be disabled, this will actually become // impossible in the future - //this->configure_flow_control(0); //disable fc + // this->configure_flow_control(0); //disable fc } void set_nsamps_per_packet(const size_t nsamps) @@ -83,43 +75,50 @@ struct rx_vita_core_3000_impl : rx_vita_core_3000 _iface->poke32(REG_FRAMER_MAXLEN, nsamps); } - void issue_stream_command(const uhd::stream_cmd_t &stream_cmd) + void issue_stream_command(const uhd::stream_cmd_t& stream_cmd) { - if (not _is_setup) - { - //UHD_LOGGER_WARNING("CORES") << "rx vita core 3000 issue stream command - not setup yet!"; + if (not _is_setup) { + // UHD_LOGGER_WARNING("CORES") << "rx vita core 3000 issue stream command - + // not setup yet!"; return; } UHD_ASSERT_THROW(stream_cmd.num_samps <= 0x0fffffff); - _continuous_streaming = stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS; + _continuous_streaming = stream_cmd.stream_mode + == stream_cmd_t::STREAM_MODE_START_CONTINUOUS; - //setup the mode to instruction flags + // setup the mode to instruction flags typedef std::tuple<bool, bool, bool, bool> inst_t; - static const uhd::dict<stream_cmd_t::stream_mode_t, inst_t> mode_to_inst = boost::assign::map_list_of - //reload, chain, samps, stop - (stream_cmd_t::STREAM_MODE_START_CONTINUOUS, inst_t(true, true, false, false)) - (stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS, inst_t(false, false, false, true)) - (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE, inst_t(false, false, true, false)) - (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE, inst_t(false, true, true, false)) - ; - - //setup the instruction flag values + static const uhd::dict<stream_cmd_t::stream_mode_t, inst_t> mode_to_inst = + boost::assign::map_list_of + // reload, chain, samps, stop + (stream_cmd_t::STREAM_MODE_START_CONTINUOUS, + inst_t(true, true, false, false))( + stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS, + inst_t(false, false, false, true))( + stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE, + inst_t(false, false, true, false))( + stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE, + inst_t(false, true, true, false)); + + // setup the instruction flag values bool inst_reload, inst_chain, inst_samps, inst_stop; - std::tie(inst_reload, inst_chain, inst_samps, inst_stop) = mode_to_inst[stream_cmd.stream_mode]; + std::tie(inst_reload, inst_chain, inst_samps, inst_stop) = + mode_to_inst[stream_cmd.stream_mode]; - //calculate the word from flags and length + // calculate the word from flags and length uint32_t cmd_word = 0; - cmd_word |= uint32_t((stream_cmd.stream_now)? 1 : 0) << 31; - cmd_word |= uint32_t((inst_chain)? 1 : 0) << 30; - cmd_word |= uint32_t((inst_reload)? 1 : 0) << 29; - cmd_word |= uint32_t((inst_stop)? 1 : 0) << 28; - cmd_word |= (inst_samps)? stream_cmd.num_samps : ((inst_stop)? 0 : 1); + cmd_word |= uint32_t((stream_cmd.stream_now) ? 1 : 0) << 31; + cmd_word |= uint32_t((inst_chain) ? 1 : 0) << 30; + cmd_word |= uint32_t((inst_reload) ? 1 : 0) << 29; + cmd_word |= uint32_t((inst_stop) ? 1 : 0) << 28; + cmd_word |= (inst_samps) ? stream_cmd.num_samps : ((inst_stop) ? 0 : 1); - //issue the stream command + // issue the stream command _iface->poke32(REG_CTRL_CMD, cmd_word); - const uint64_t ticks = (stream_cmd.stream_now)? 0 : stream_cmd.time_spec.to_ticks(_tick_rate); + const uint64_t ticks = + (stream_cmd.stream_now) ? 0 : stream_cmd.time_spec.to_ticks(_tick_rate); _iface->poke32(REG_CTRL_TIME_HI, uint32_t(ticks >> 32)); - _iface->poke32(REG_CTRL_TIME_LO, uint32_t(ticks >> 0)); //latches the command + _iface->poke32(REG_CTRL_TIME_LO, uint32_t(ticks >> 0)); // latches the command } void set_tick_rate(const double rate) @@ -134,10 +133,11 @@ struct rx_vita_core_3000_impl : rx_vita_core_3000 void handle_overflow(void) { - if (_continuous_streaming) this->issue_stream_command(stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + if (_continuous_streaming) + this->issue_stream_command(stream_cmd_t::STREAM_MODE_START_CONTINUOUS); } - void setup(const uhd::stream_args_t &) + void setup(const uhd::stream_args_t&) { _is_setup = true; } @@ -154,10 +154,7 @@ struct rx_vita_core_3000_impl : rx_vita_core_3000 bool _is_setup; }; -rx_vita_core_3000::sptr rx_vita_core_3000::make( - wb_iface::sptr iface, - const size_t base -) +rx_vita_core_3000::sptr rx_vita_core_3000::make(wb_iface::sptr iface, const size_t base) { return rx_vita_core_3000::sptr(new rx_vita_core_3000_impl(iface, base)); } diff --git a/host/lib/usrp/cores/spi_core_3000.cpp b/host/lib/usrp/cores/spi_core_3000.cpp index fb9d9d549..ad9df68dd 100644 --- a/host/lib/usrp/cores/spi_core_3000.cpp +++ b/host/lib/usrp/cores/spi_core_3000.cpp @@ -8,8 +8,8 @@ #include <uhd/exception.hpp> #include <uhdlib/usrp/cores/spi_core_3000.hpp> -#include <memory> #include <chrono> +#include <memory> #include <mutex> #include <thread> diff --git a/host/lib/usrp/cores/time64_core_200.cpp b/host/lib/usrp/cores/time64_core_200.cpp index 09fa92dcd..a7d5427c1 100644 --- a/host/lib/usrp/cores/time64_core_200.cpp +++ b/host/lib/usrp/cores/time64_core_200.cpp @@ -10,17 +10,17 @@ #include <uhdlib/usrp/cores/time64_core_200.hpp> #include <boost/math/special_functions/round.hpp> -#define REG_TIME64_TICKS_HI _base + 0 -#define REG_TIME64_TICKS_LO _base + 4 -#define REG_TIME64_FLAGS _base + 8 -#define REG_TIME64_IMM _base + 12 -#define REG_TIME64_MIMO_SYNC _base + 20 //lower byte is delay cycles +#define REG_TIME64_TICKS_HI _base + 0 +#define REG_TIME64_TICKS_LO _base + 4 +#define REG_TIME64_FLAGS _base + 8 +#define REG_TIME64_IMM _base + 12 +#define REG_TIME64_MIMO_SYNC _base + 20 // lower byte is delay cycles -//pps flags (see above) +// pps flags (see above) #define FLAG_TIME64_PPS_NEGEDGE (0 << 0) #define FLAG_TIME64_PPS_POSEDGE (1 << 0) -#define FLAG_TIME64_PPS_SMA (0 << 1) -#define FLAG_TIME64_PPS_MIMO (1 << 1) //apparently not used +#define FLAG_TIME64_PPS_SMA (0 << 1) +#define FLAG_TIME64_PPS_MIMO (1 << 1) // apparently not used #define FLAG_TIME64_LATCH_NOW 1 #define FLAG_TIME64_LATCH_NEXT_PPS 0 @@ -29,93 +29,109 @@ using namespace uhd; -time64_core_200::~time64_core_200(void){ +time64_core_200::~time64_core_200(void) +{ /* NOP */ } -class time64_core_200_impl : public time64_core_200{ +class time64_core_200_impl : public time64_core_200 +{ public: - time64_core_200_impl( - wb_iface::sptr iface, const size_t base, - const readback_bases_type &readback_bases, - const size_t mimo_delay_cycles - ): - _iface(iface), _base(base), - _readback_bases(readback_bases), - _tick_rate(0.0), - _mimo_delay_cycles(mimo_delay_cycles) + time64_core_200_impl(wb_iface::sptr iface, + const size_t base, + const readback_bases_type& readback_bases, + const size_t mimo_delay_cycles) + : _iface(iface) + , _base(base) + , _readback_bases(readback_bases) + , _tick_rate(0.0) + , _mimo_delay_cycles(mimo_delay_cycles) { _sources.push_back("none"); _sources.push_back("external"); _sources.push_back("_external_"); - if (_mimo_delay_cycles != 0) _sources.push_back("mimo"); + if (_mimo_delay_cycles != 0) + _sources.push_back("mimo"); } - void enable_gpsdo(void){ + void enable_gpsdo(void) + { _sources.push_back("gpsdo"); } - void set_tick_rate(const double rate){ + void set_tick_rate(const double rate) + { _tick_rate = rate; } - uhd::time_spec_t get_time_now(void){ - for (size_t i = 0; i < 3; i++){ //special algorithm because we cant read 64 bits synchronously + uhd::time_spec_t get_time_now(void) + { + for (size_t i = 0; i < 3; + i++) { // special algorithm because we cant read 64 bits synchronously const uint32_t ticks_hi = _iface->peek32(_readback_bases.rb_hi_now); const uint32_t ticks_lo = _iface->peek32(_readback_bases.rb_lo_now); - if (ticks_hi != _iface->peek32(_readback_bases.rb_hi_now)) continue; + if (ticks_hi != _iface->peek32(_readback_bases.rb_hi_now)) + continue; const uint64_t ticks = (uint64_t(ticks_hi) << 32) | ticks_lo; return time_spec_t::from_ticks(ticks, _tick_rate); } throw uhd::runtime_error("time64_core_200: get time now timeout"); } - uhd::time_spec_t get_time_last_pps(void){ - for (size_t i = 0; i < 3; i++){ //special algorithm because we cant read 64 bits synchronously + uhd::time_spec_t get_time_last_pps(void) + { + for (size_t i = 0; i < 3; + i++) { // special algorithm because we cant read 64 bits synchronously const uint32_t ticks_hi = _iface->peek32(_readback_bases.rb_hi_pps); const uint32_t ticks_lo = _iface->peek32(_readback_bases.rb_lo_pps); - if (ticks_hi != _iface->peek32(_readback_bases.rb_hi_pps)) continue; + if (ticks_hi != _iface->peek32(_readback_bases.rb_hi_pps)) + continue; const uint64_t ticks = (uint64_t(ticks_hi) << 32) | ticks_lo; return time_spec_t::from_ticks(ticks, _tick_rate); } throw uhd::runtime_error("time64_core_200: get time last pps timeout"); } - void set_time_now(const uhd::time_spec_t &time){ + void set_time_now(const uhd::time_spec_t& time) + { const uint64_t ticks = time.to_ticks(_tick_rate); _iface->poke32(REG_TIME64_TICKS_LO, uint32_t(ticks >> 0)); _iface->poke32(REG_TIME64_IMM, FLAG_TIME64_LATCH_NOW); - _iface->poke32(REG_TIME64_TICKS_HI, uint32_t(ticks >> 32)); //latches all 3 + _iface->poke32(REG_TIME64_TICKS_HI, uint32_t(ticks >> 32)); // latches all 3 } - void set_time_next_pps(const uhd::time_spec_t &time){ + void set_time_next_pps(const uhd::time_spec_t& time) + { const uint64_t ticks = time.to_ticks(_tick_rate); _iface->poke32(REG_TIME64_TICKS_LO, uint32_t(ticks >> 0)); _iface->poke32(REG_TIME64_IMM, FLAG_TIME64_LATCH_NEXT_PPS); - _iface->poke32(REG_TIME64_TICKS_HI, uint32_t(ticks >> 32)); //latches all 3 + _iface->poke32(REG_TIME64_TICKS_HI, uint32_t(ticks >> 32)); // latches all 3 } - void set_time_source(const std::string &source){ + void set_time_source(const std::string& source) + { assert_has(_sources, source, "time source"); - //setup pps flags - if (source == "external" or source == "gpsdo"){ - _iface->poke32(REG_TIME64_FLAGS, FLAG_TIME64_PPS_SMA | FLAG_TIME64_PPS_POSEDGE); - } - else if (source == "_external_"){ - _iface->poke32(REG_TIME64_FLAGS, FLAG_TIME64_PPS_SMA | FLAG_TIME64_PPS_NEGEDGE); + // setup pps flags + if (source == "external" or source == "gpsdo") { + _iface->poke32( + REG_TIME64_FLAGS, FLAG_TIME64_PPS_SMA | FLAG_TIME64_PPS_POSEDGE); + } else if (source == "_external_") { + _iface->poke32( + REG_TIME64_FLAGS, FLAG_TIME64_PPS_SMA | FLAG_TIME64_PPS_NEGEDGE); } - //setup mimo flags - if (source == "mimo"){ - _iface->poke32(REG_TIME64_MIMO_SYNC, FLAG_TIME64_MIMO_SYNC | (_mimo_delay_cycles & 0xff)); - } - else{ + // setup mimo flags + if (source == "mimo") { + _iface->poke32(REG_TIME64_MIMO_SYNC, + FLAG_TIME64_MIMO_SYNC | (_mimo_delay_cycles & 0xff)); + } else { _iface->poke32(REG_TIME64_MIMO_SYNC, 0); } } - std::vector<std::string> get_time_sources(void){ + std::vector<std::string> get_time_sources(void) + { return _sources; } @@ -128,6 +144,10 @@ private: std::vector<std::string> _sources; }; -time64_core_200::sptr time64_core_200::make(wb_iface::sptr iface, const size_t base, const readback_bases_type &readback_bases, const size_t mimo_delay_cycles){ +time64_core_200::sptr time64_core_200::make(wb_iface::sptr iface, + const size_t base, + const readback_bases_type& readback_bases, + const size_t mimo_delay_cycles) +{ return sptr(new time64_core_200_impl(iface, base, readback_bases, mimo_delay_cycles)); } diff --git a/host/lib/usrp/cores/time_core_3000.cpp b/host/lib/usrp/cores/time_core_3000.cpp index 3fb6c3d57..852c3882e 100644 --- a/host/lib/usrp/cores/time_core_3000.cpp +++ b/host/lib/usrp/cores/time_core_3000.cpp @@ -5,44 +5,40 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/safe_call.hpp> #include <uhd/utils/log.hpp> +#include <uhd/utils/safe_call.hpp> #include <uhdlib/usrp/cores/time_core_3000.hpp> #include <chrono> #include <thread> -#define REG_TIME_HI _base + 0 -#define REG_TIME_LO _base + 4 -#define REG_TIME_CTRL _base + 8 +#define REG_TIME_HI _base + 0 +#define REG_TIME_LO _base + 4 +#define REG_TIME_CTRL _base + 8 -#define CTRL_LATCH_TIME_NOW (1 << 0) -#define CTRL_LATCH_TIME_PPS (1 << 1) -#define CTRL_LATCH_TIME_SYNC (1 << 2) +#define CTRL_LATCH_TIME_NOW (1 << 0) +#define CTRL_LATCH_TIME_PPS (1 << 1) +#define CTRL_LATCH_TIME_SYNC (1 << 2) using namespace uhd; -time_core_3000::~time_core_3000(void){ +time_core_3000::~time_core_3000(void) +{ /* NOP */ } struct time_core_3000_impl : time_core_3000 { - time_core_3000_impl( - wb_iface::sptr iface, const size_t base, - const readback_bases_type &readback_bases - ): - _iface(iface), - _base(base), - _readback_bases(readback_bases) + time_core_3000_impl(wb_iface::sptr iface, + const size_t base, + const readback_bases_type& readback_bases) + : _iface(iface), _base(base), _readback_bases(readback_bases) { - this->set_tick_rate(1); //init to non zero + this->set_tick_rate(1); // init to non zero } ~time_core_3000_impl(void) { - UHD_SAFE_CALL - ( - ;//NOP + UHD_SAFE_CALL(; // NOP ) } @@ -57,22 +53,22 @@ struct time_core_3000_impl : time_core_3000 UHD_LOGGER_DEBUG("CORES") << "Performing timer loopback test... "; const time_spec_t time0 = this->get_time_now(); std::this_thread::sleep_for(std::chrono::milliseconds(sleep_millis)); - const time_spec_t time1 = this->get_time_now(); + const time_spec_t time1 = this->get_time_now(); const double approx_secs = (time1 - time0).get_real_secs(); - const bool test_fail = (approx_secs > 0.15) or (approx_secs < 0.05); + const bool test_fail = (approx_secs > 0.15) or (approx_secs < 0.05); if (test_fail) { UHD_LOG_WARNING("CORES", "Timer loopback test failed!"); } else { UHD_LOG_DEBUG("CORES", "Timer loopback test passed."); } - //useful warning for debugging actual rate - const size_t ticks_elapsed = size_t(_tick_rate*approx_secs); - const size_t approx_rate = size_t(ticks_elapsed/(sleep_millis/1e3)); - if (test_fail) UHD_LOGGER_WARNING("CORES") - << "Expecting clock rate: " << (_tick_rate/1e6) << " MHz\n" - << "Approximate clock rate: " << (approx_rate/1e6) << " MHz\n" - ; + // useful warning for debugging actual rate + const size_t ticks_elapsed = size_t(_tick_rate * approx_secs); + const size_t approx_rate = size_t(ticks_elapsed / (sleep_millis / 1e3)); + if (test_fail) + UHD_LOGGER_WARNING("CORES") + << "Expecting clock rate: " << (_tick_rate / 1e6) << " MHz\n" + << "Approximate clock rate: " << (approx_rate / 1e6) << " MHz\n"; } uhd::time_spec_t get_time_now(void) @@ -87,7 +83,7 @@ struct time_core_3000_impl : time_core_3000 return time_spec_t::from_ticks(ticks, _tick_rate); } - void set_time_now(const uhd::time_spec_t &time) + void set_time_now(const uhd::time_spec_t& time) { const uint64_t ticks = time.to_ticks(_tick_rate); _iface->poke32(REG_TIME_HI, uint32_t(ticks >> 32)); @@ -95,7 +91,7 @@ struct time_core_3000_impl : time_core_3000 _iface->poke32(REG_TIME_CTRL, CTRL_LATCH_TIME_NOW); } - void set_time_sync(const uhd::time_spec_t &time) + void set_time_sync(const uhd::time_spec_t& time) { const uint64_t ticks = time.to_ticks(_tick_rate); _iface->poke32(REG_TIME_HI, uint32_t(ticks >> 32)); @@ -103,7 +99,7 @@ struct time_core_3000_impl : time_core_3000 _iface->poke32(REG_TIME_CTRL, CTRL_LATCH_TIME_SYNC); } - void set_time_next_pps(const uhd::time_spec_t &time) + void set_time_next_pps(const uhd::time_spec_t& time) { const uint64_t ticks = time.to_ticks(_tick_rate); _iface->poke32(REG_TIME_HI, uint32_t(ticks >> 32)); @@ -118,9 +114,7 @@ struct time_core_3000_impl : time_core_3000 }; time_core_3000::sptr time_core_3000::make( - wb_iface::sptr iface, const size_t base, - const readback_bases_type &readback_bases -) + wb_iface::sptr iface, const size_t base, const readback_bases_type& readback_bases) { return time_core_3000::sptr(new time_core_3000_impl(iface, base, readback_bases)); } diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp index 6418d7049..8dd48181c 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp @@ -5,156 +5,173 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhdlib/usrp/cores/tx_dsp_core_200.hpp> -#include <uhdlib/usrp/cores/dsp_core_utils.hpp> -#include <uhd/types/dict.hpp> #include <uhd/exception.hpp> -#include <uhd/utils/math.hpp> +#include <uhd/types/dict.hpp> #include <uhd/utils/log.hpp> +#include <uhd/utils/math.hpp> +#include <uhdlib/usrp/cores/dsp_core_utils.hpp> +#include <uhdlib/usrp/cores/tx_dsp_core_200.hpp> #include <boost/assign/list_of.hpp> #include <boost/math/special_functions/round.hpp> #include <algorithm> -#include <cmath> #include <chrono> +#include <cmath> #include <thread> -#define REG_DSP_TX_FREQ _dsp_base + 0 -#define REG_DSP_TX_SCALE_IQ _dsp_base + 4 -#define REG_DSP_TX_INTERP _dsp_base + 8 +#define REG_DSP_TX_FREQ _dsp_base + 0 +#define REG_DSP_TX_SCALE_IQ _dsp_base + 4 +#define REG_DSP_TX_INTERP _dsp_base + 8 -#define REG_TX_CTRL_CLEAR _ctrl_base + 0 -#define REG_TX_CTRL_FORMAT _ctrl_base + 4 -#define REG_TX_CTRL_REPORT_SID _ctrl_base + 8 -#define REG_TX_CTRL_POLICY _ctrl_base + 12 -#define REG_TX_CTRL_CYCLES_PER_UP _ctrl_base + 16 -#define REG_TX_CTRL_PACKETS_PER_UP _ctrl_base + 20 +#define REG_TX_CTRL_CLEAR _ctrl_base + 0 +#define REG_TX_CTRL_FORMAT _ctrl_base + 4 +#define REG_TX_CTRL_REPORT_SID _ctrl_base + 8 +#define REG_TX_CTRL_POLICY _ctrl_base + 12 +#define REG_TX_CTRL_CYCLES_PER_UP _ctrl_base + 16 +#define REG_TX_CTRL_PACKETS_PER_UP _ctrl_base + 20 -#define FLAG_TX_CTRL_POLICY_WAIT (0x1 << 0) -#define FLAG_TX_CTRL_POLICY_NEXT_PACKET (0x1 << 1) -#define FLAG_TX_CTRL_POLICY_NEXT_BURST (0x1 << 2) +#define FLAG_TX_CTRL_POLICY_WAIT (0x1 << 0) +#define FLAG_TX_CTRL_POLICY_NEXT_PACKET (0x1 << 1) +#define FLAG_TX_CTRL_POLICY_NEXT_BURST (0x1 << 2) -//enable flag for registers: cycles and packets per update packet -#define FLAG_TX_CTRL_UP_ENB (1ul << 31) +// enable flag for registers: cycles and packets per update packet +#define FLAG_TX_CTRL_UP_ENB (1ul << 31) -template <class T> T ceil_log2(T num){ - return std::ceil(std::log(num)/std::log(T(2))); +template <class T> +T ceil_log2(T num) +{ + return std::ceil(std::log(num) / std::log(T(2))); } using namespace uhd; -tx_dsp_core_200::~tx_dsp_core_200(void){ +tx_dsp_core_200::~tx_dsp_core_200(void) +{ /* NOP */ } -class tx_dsp_core_200_impl : public tx_dsp_core_200{ +class tx_dsp_core_200_impl : public tx_dsp_core_200 +{ public: - tx_dsp_core_200_impl( - wb_iface::sptr iface, - const size_t dsp_base, const size_t ctrl_base, - const uint32_t sid - ): - _iface(iface), _dsp_base(dsp_base), _ctrl_base(ctrl_base), _sid(sid) + tx_dsp_core_200_impl(wb_iface::sptr iface, + const size_t dsp_base, + const size_t ctrl_base, + const uint32_t sid) + : _iface(iface), _dsp_base(dsp_base), _ctrl_base(ctrl_base), _sid(sid) { // previously uninitialized - assuming zero for all _tick_rate = _link_rate = _host_extra_scaling = _fxpt_scalar_correction = 0.0; - //init to something so update method has reasonable defaults + // init to something so update method has reasonable defaults _scaling_adjustment = 1.0; - _dsp_extra_scaling = 1.0; + _dsp_extra_scaling = 1.0; - //init the tx control registers + // init the tx control registers this->clear(); this->set_underflow_policy("next_packet"); } - void clear(void){ - _iface->poke32(REG_TX_CTRL_CLEAR, 1); //reset and flush technique + void clear(void) + { + _iface->poke32(REG_TX_CTRL_CLEAR, 1); // reset and flush technique std::this_thread::sleep_for(std::chrono::milliseconds(10)); _iface->poke32(REG_TX_CTRL_CLEAR, 0); _iface->poke32(REG_TX_CTRL_REPORT_SID, _sid); } - void set_underflow_policy(const std::string &policy){ - if (policy == "next_packet"){ + void set_underflow_policy(const std::string& policy) + { + if (policy == "next_packet") { _iface->poke32(REG_TX_CTRL_POLICY, FLAG_TX_CTRL_POLICY_NEXT_PACKET); - } - else if (policy == "next_burst"){ + } else if (policy == "next_burst") { _iface->poke32(REG_TX_CTRL_POLICY, FLAG_TX_CTRL_POLICY_NEXT_BURST); - } - else throw uhd::value_error("USRP TX cannot handle requested underflow policy: " + policy); + } else + throw uhd::value_error( + "USRP TX cannot handle requested underflow policy: " + policy); } - void set_tick_rate(const double rate){ + void set_tick_rate(const double rate) + { _tick_rate = rate; } - void set_link_rate(const double rate){ + void set_link_rate(const double rate) + { //_link_rate = rate/sizeof(uint32_t); //in samps/s - _link_rate = rate/sizeof(uint16_t); //in samps/s (allows for 8sc) + _link_rate = rate / sizeof(uint16_t); // in samps/s (allows for 8sc) } - uhd::meta_range_t get_host_rates(void){ + uhd::meta_range_t get_host_rates(void) + { meta_range_t range; - for (int rate = 512; rate > 256; rate -= 4){ - range.push_back(range_t(_tick_rate/rate)); + for (int rate = 512; rate > 256; rate -= 4) { + range.push_back(range_t(_tick_rate / rate)); } - for (int rate = 256; rate > 128; rate -= 2){ - range.push_back(range_t(_tick_rate/rate)); + for (int rate = 256; rate > 128; rate -= 2) { + range.push_back(range_t(_tick_rate / rate)); } - for (int rate = 128; rate >= int(std::ceil(_tick_rate/_link_rate)); rate -= 1){ - range.push_back(range_t(_tick_rate/rate)); + for (int rate = 128; rate >= int(std::ceil(_tick_rate / _link_rate)); rate -= 1) { + range.push_back(range_t(_tick_rate / rate)); } return range; } - double set_host_rate(const double rate){ - const size_t interp_rate = boost::math::iround(_tick_rate/this->get_host_rates().clip(rate, true)); + double set_host_rate(const double rate) + { + const size_t interp_rate = + boost::math::iround(_tick_rate / this->get_host_rates().clip(rate, true)); size_t interp = interp_rate; - //determine which half-band filters are activated + // determine which half-band filters are activated int hb0 = 0, hb1 = 0; - if (interp % 2 == 0){ + if (interp % 2 == 0) { hb0 = 1; interp /= 2; } - if (interp % 2 == 0){ + if (interp % 2 == 0) { hb1 = 1; interp /= 2; } _iface->poke32(REG_DSP_TX_INTERP, (hb1 << 9) | (hb0 << 8) | (interp & 0xff)); - if (interp > 1 and hb0 == 0 and hb1 == 0) - { - UHD_LOGGER_WARNING("CORES") << boost::format( - "The requested interpolation is odd; the user should expect CIC rolloff.\n" - "Select an even interpolation to ensure that a halfband filter is enabled.\n" - "interpolation = dsp_rate/samp_rate -> %d = (%f MHz)/(%f MHz)\n" - ) % interp_rate % (_tick_rate/1e6) % (rate/1e6); + if (interp > 1 and hb0 == 0 and hb1 == 0) { + UHD_LOGGER_WARNING("CORES") + << boost::format( + "The requested interpolation is odd; the user should expect CIC " + "rolloff.\n" + "Select an even interpolation to ensure that a halfband filter is " + "enabled.\n" + "interpolation = dsp_rate/samp_rate -> %d = (%f MHz)/(%f MHz)\n") + % interp_rate % (_tick_rate / 1e6) % (rate / 1e6); } // Calculate CIC interpolation (i.e., without halfband interpolators) // Calculate closest multiplier constant to reverse gain absent scale multipliers const double rate_pow = std::pow(double(interp & 0xff), 3); - _scaling_adjustment = std::pow(2, ceil_log2(rate_pow))/(1.65*rate_pow); + _scaling_adjustment = std::pow(2, ceil_log2(rate_pow)) / (1.65 * rate_pow); this->update_scalar(); - return _tick_rate/interp_rate; + return _tick_rate / interp_rate; } - void update_scalar(void){ + void update_scalar(void) + { const double factor = 1.0 + std::max(ceil_log2(_scaling_adjustment), 0.0); - const double target_scalar = (1 << 17)*_scaling_adjustment/_dsp_extra_scaling/factor; + const double target_scalar = + (1 << 17) * _scaling_adjustment / _dsp_extra_scaling / factor; const int32_t actual_scalar = boost::math::iround(target_scalar); - _fxpt_scalar_correction = target_scalar/actual_scalar*factor; //should be small + _fxpt_scalar_correction = + target_scalar / actual_scalar * factor; // should be small _iface->poke32(REG_DSP_TX_SCALE_IQ, actual_scalar); } - double get_scaling_adjustment(void){ - return _fxpt_scalar_correction*_host_extra_scaling*32767.; + double get_scaling_adjustment(void) + { + return _fxpt_scalar_correction * _host_extra_scaling * 32767.; } - double set_freq(const double requested_freq){ + double set_freq(const double requested_freq) + { double actual_freq; int32_t freq_word; get_freq_and_freq_word(requested_freq, _tick_rate, actual_freq, freq_word); @@ -162,32 +179,39 @@ public: return actual_freq; } - uhd::meta_range_t get_freq_range(void){ - return uhd::meta_range_t(-_tick_rate/2, +_tick_rate/2, _tick_rate/std::pow(2.0, 32)); + uhd::meta_range_t get_freq_range(void) + { + return uhd::meta_range_t( + -_tick_rate / 2, +_tick_rate / 2, _tick_rate / std::pow(2.0, 32)); } - void set_updates(const size_t cycles_per_up, const size_t packets_per_up){ - _iface->poke32(REG_TX_CTRL_CYCLES_PER_UP, (cycles_per_up == 0)? 0 : (FLAG_TX_CTRL_UP_ENB | cycles_per_up)); - _iface->poke32(REG_TX_CTRL_PACKETS_PER_UP, (packets_per_up == 0)? 0 : (FLAG_TX_CTRL_UP_ENB | packets_per_up)); + void set_updates(const size_t cycles_per_up, const size_t packets_per_up) + { + _iface->poke32(REG_TX_CTRL_CYCLES_PER_UP, + (cycles_per_up == 0) ? 0 : (FLAG_TX_CTRL_UP_ENB | cycles_per_up)); + _iface->poke32(REG_TX_CTRL_PACKETS_PER_UP, + (packets_per_up == 0) ? 0 : (FLAG_TX_CTRL_UP_ENB | packets_per_up)); } - void setup(const uhd::stream_args_t &stream_args){ - if (not stream_args.args.has_key("noclear")) this->clear(); + void setup(const uhd::stream_args_t& stream_args) + { + if (not stream_args.args.has_key("noclear")) + this->clear(); unsigned format_word = 0; - if (stream_args.otw_format == "sc16"){ - format_word = 0; - _dsp_extra_scaling = 1.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 throw uhd::value_error("USRP TX cannot handle requested wire format: " + stream_args.otw_format); + } 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 + 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); @@ -195,7 +219,7 @@ public: _iface->poke32(REG_TX_CTRL_FORMAT, format_word); - if (stream_args.args.has_key("underflow_policy")){ + if (stream_args.args.has_key("underflow_policy")) { this->set_underflow_policy(stream_args.args["underflow_policy"]); } } @@ -204,10 +228,15 @@ private: wb_iface::sptr _iface; const size_t _dsp_base, _ctrl_base; double _tick_rate, _link_rate; - double _scaling_adjustment, _dsp_extra_scaling, _host_extra_scaling, _fxpt_scalar_correction; + double _scaling_adjustment, _dsp_extra_scaling, _host_extra_scaling, + _fxpt_scalar_correction; const uint32_t _sid; }; -tx_dsp_core_200::sptr tx_dsp_core_200::make(wb_iface::sptr iface, const size_t dsp_base, const size_t ctrl_base, const uint32_t sid){ +tx_dsp_core_200::sptr tx_dsp_core_200::make(wb_iface::sptr iface, + const size_t dsp_base, + const size_t ctrl_base, + const uint32_t sid) +{ return sptr(new tx_dsp_core_200_impl(iface, dsp_base, ctrl_base, sid)); } diff --git a/host/lib/usrp/cores/tx_dsp_core_3000.cpp b/host/lib/usrp/cores/tx_dsp_core_3000.cpp index c89b684fa..3b0d85c00 100644 --- a/host/lib/usrp/cores/tx_dsp_core_3000.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_3000.cpp @@ -187,10 +187,12 @@ public: .set_publisher(std::bind(&tx_dsp_core_3000::get_host_rates, this)); subtree->create<double>("rate/value") .set(DEFAULT_RATE) - .set_coercer(std::bind(&tx_dsp_core_3000::set_host_rate, this, std::placeholders::_1)); + .set_coercer( + std::bind(&tx_dsp_core_3000::set_host_rate, this, std::placeholders::_1)); subtree->create<double>("freq/value") .set(DEFAULT_CORDIC_FREQ) - .set_coercer(std::bind(&tx_dsp_core_3000::set_freq, this, std::placeholders::_1)) + .set_coercer( + std::bind(&tx_dsp_core_3000::set_freq, this, std::placeholders::_1)) .set_publisher([this]() { return this->get_freq(); }); subtree->create<meta_range_t>("freq/range") .set_publisher(std::bind(&tx_dsp_core_3000::get_freq_range, this)); diff --git a/host/lib/usrp/cores/tx_frontend_core_200.cpp b/host/lib/usrp/cores/tx_frontend_core_200.cpp index c02ce755a..46a79c497 100644 --- a/host/lib/usrp/cores/tx_frontend_core_200.cpp +++ b/host/lib/usrp/cores/tx_frontend_core_200.cpp @@ -5,68 +5,78 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhdlib/usrp/cores/tx_frontend_core_200.hpp> +#include <uhd/exception.hpp> #include <uhd/types/dict.hpp> #include <uhd/types/ranges.hpp> -#include <uhd/exception.hpp> +#include <uhdlib/usrp/cores/tx_frontend_core_200.hpp> #include <boost/assign/list_of.hpp> #include <boost/math/special_functions/round.hpp> #include <functional> using namespace uhd; -#define REG_TX_FE_DC_OFFSET_I _base + 0 * _offset //24 bits -#define REG_TX_FE_DC_OFFSET_Q _base + 1 * _offset //24 bits -#define REG_TX_FE_MAG_CORRECTION _base + 2 * _offset //18 bits -#define REG_TX_FE_PHASE_CORRECTION _base + 3 * _offset //18 bits -#define REG_TX_FE_MUX _base + 4 * _offset //8 bits (std output = 0x10, reversed = 0x01) +#define REG_TX_FE_DC_OFFSET_I _base + 0 * _offset // 24 bits +#define REG_TX_FE_DC_OFFSET_Q _base + 1 * _offset // 24 bits +#define REG_TX_FE_MAG_CORRECTION _base + 2 * _offset // 18 bits +#define REG_TX_FE_PHASE_CORRECTION _base + 3 * _offset // 18 bits +#define REG_TX_FE_MUX _base + 4 * _offset // 8 bits (std output = 0x10, reversed = 0x01) -const std::complex<double> tx_frontend_core_200::DEFAULT_DC_OFFSET_VALUE = std::complex<double>(0.0, 0.0); -const std::complex<double> tx_frontend_core_200::DEFAULT_IQ_BALANCE_VALUE = std::complex<double>(0.0, 0.0); +const std::complex<double> tx_frontend_core_200::DEFAULT_DC_OFFSET_VALUE = + std::complex<double>(0.0, 0.0); +const std::complex<double> tx_frontend_core_200::DEFAULT_IQ_BALANCE_VALUE = + std::complex<double>(0.0, 0.0); namespace { - static const double DC_OFFSET_MIN = -1.0; - static const double DC_OFFSET_MAX = 1.0; -} +static const double DC_OFFSET_MIN = -1.0; +static const double DC_OFFSET_MAX = 1.0; +} // namespace -static uint32_t fs_to_bits(const double num, const size_t bits){ - return int32_t(boost::math::round(num * (1 << (bits-1)))); +static uint32_t fs_to_bits(const double num, const size_t bits) +{ + return int32_t(boost::math::round(num * (1 << (bits - 1)))); } -tx_frontend_core_200::~tx_frontend_core_200(void){ +tx_frontend_core_200::~tx_frontend_core_200(void) +{ /* NOP */ } -class tx_frontend_core_200_impl : public tx_frontend_core_200{ +class tx_frontend_core_200_impl : public tx_frontend_core_200 +{ public: - tx_frontend_core_200_impl(wb_iface::sptr iface, const size_t base, const size_t offset): - _iface(iface), _base(base), _offset(offset) + tx_frontend_core_200_impl( + wb_iface::sptr iface, const size_t base, const size_t offset) + : _iface(iface), _base(base), _offset(offset) { - //NOP + // NOP } - void set_mux(const std::string &mode){ - static const uhd::dict<std::string, uint32_t> mode_to_mux = boost::assign::map_list_of - ("IQ", (0x1 << 4) | (0x0 << 0)) //DAC0Q=DUC0Q, DAC0I=DUC0I - ("QI", (0x0 << 4) | (0x1 << 0)) //DAC0Q=DUC0I, DAC0I=DUC0Q - ("I", (0xf << 4) | (0x0 << 0)) //DAC0Q=ZERO, DAC0I=DUC0I - ("Q", (0x0 << 4) | (0xf << 0)) //DAC0Q=DUC0I, DAC0I=ZERO - ; + void set_mux(const std::string& mode) + { + static const uhd::dict<std::string, uint32_t> mode_to_mux = + boost::assign::map_list_of( + "IQ", (0x1 << 4) | (0x0 << 0)) // DAC0Q=DUC0Q, DAC0I=DUC0I + ("QI", (0x0 << 4) | (0x1 << 0)) // DAC0Q=DUC0I, DAC0I=DUC0Q + ("I", (0xf << 4) | (0x0 << 0)) // DAC0Q=ZERO, DAC0I=DUC0I + ("Q", (0x0 << 4) | (0xf << 0)) // DAC0Q=DUC0I, DAC0I=ZERO + ; _iface->poke32(REG_TX_FE_MUX, mode_to_mux[mode]); } - std::complex<double> set_dc_offset(const std::complex<double> &off){ + std::complex<double> set_dc_offset(const std::complex<double>& off) + { static const double scaler = double(1ul << 23); - const int32_t i_dc_off = boost::math::iround(off.real()*scaler); - const int32_t q_dc_off = boost::math::iround(off.imag()*scaler); + const int32_t i_dc_off = boost::math::iround(off.real() * scaler); + const int32_t q_dc_off = boost::math::iround(off.imag() * scaler); _iface->poke32(REG_TX_FE_DC_OFFSET_I, i_dc_off); _iface->poke32(REG_TX_FE_DC_OFFSET_Q, q_dc_off); - return std::complex<double>(i_dc_off/scaler, q_dc_off/scaler); + return std::complex<double>(i_dc_off / scaler, q_dc_off / scaler); } - void set_iq_balance(const std::complex<double> &cor){ + void set_iq_balance(const std::complex<double>& cor) + { _iface->poke32(REG_TX_FE_MAG_CORRECTION, fs_to_bits(cor.real(), 18)); _iface->poke32(REG_TX_FE_PHASE_CORRECTION, fs_to_bits(cor.imag(), 18)); } @@ -74,16 +84,15 @@ public: void populate_subtree(uhd::property_tree::sptr subtree) { subtree->create<uhd::meta_range_t>("dc_offset/range") - .set(meta_range_t(DC_OFFSET_MIN, DC_OFFSET_MAX)) - ; - subtree->create< std::complex<double> >("dc_offset/value") + .set(meta_range_t(DC_OFFSET_MIN, DC_OFFSET_MAX)); + subtree->create<std::complex<double>>("dc_offset/value") .set(DEFAULT_DC_OFFSET_VALUE) - .set_coercer(std::bind(&tx_frontend_core_200::set_dc_offset, this, std::placeholders::_1)) - ; - subtree->create< std::complex<double> >("iq_balance/value") + .set_coercer(std::bind( + &tx_frontend_core_200::set_dc_offset, this, std::placeholders::_1)); + subtree->create<std::complex<double>>("iq_balance/value") .set(DEFAULT_IQ_BALANCE_VALUE) - .add_coerced_subscriber(std::bind(&tx_frontend_core_200::set_iq_balance, this, std::placeholders::_1)) - ; + .add_coerced_subscriber(std::bind( + &tx_frontend_core_200::set_iq_balance, this, std::placeholders::_1)); } private: @@ -92,6 +101,8 @@ private: const size_t _offset; }; -tx_frontend_core_200::sptr tx_frontend_core_200::make(wb_iface::sptr iface, const size_t base, const size_t offset){ +tx_frontend_core_200::sptr tx_frontend_core_200::make( + wb_iface::sptr iface, const size_t base, const size_t offset) +{ return sptr(new tx_frontend_core_200_impl(iface, base, offset)); } diff --git a/host/lib/usrp/cores/tx_vita_core_3000.cpp b/host/lib/usrp/cores/tx_vita_core_3000.cpp index 689a6cf45..c89301464 100644 --- a/host/lib/usrp/cores/tx_vita_core_3000.cpp +++ b/host/lib/usrp/cores/tx_vita_core_3000.cpp @@ -8,35 +8,35 @@ #include <uhd/utils/safe_call.hpp> #include <uhdlib/usrp/cores/tx_vita_core_3000.hpp> -#define REG_CTRL_ERROR_POLICY (_base + 0) -#define REG_FC_PRE_RADIO_RESP_BASE (_base + 2*4) -#define REG_FC_PRE_FIFO_RESP_BASE (_base + 4*4) -#define REG_CTRL_FC_CYCLE_OFFSET (0*4) -#define REG_CTRL_FC_PACKET_OFFSET (1*4) +#define REG_CTRL_ERROR_POLICY (_base + 0) +#define REG_FC_PRE_RADIO_RESP_BASE (_base + 2 * 4) +#define REG_FC_PRE_FIFO_RESP_BASE (_base + 4 * 4) +#define REG_CTRL_FC_CYCLE_OFFSET (0 * 4) +#define REG_CTRL_FC_PACKET_OFFSET (1 * 4) using namespace uhd; -tx_vita_core_3000::~tx_vita_core_3000(void){ +tx_vita_core_3000::~tx_vita_core_3000(void) +{ /* NOP */ } struct tx_vita_core_3000_impl : tx_vita_core_3000 { tx_vita_core_3000_impl( - wb_iface::sptr iface, - const size_t base, - fc_monitor_loc fc_location - ): - _iface(iface), - _base(base), - _fc_base((fc_location==FC_PRE_RADIO or fc_location==FC_DEFAULT) ? - REG_FC_PRE_RADIO_RESP_BASE : REG_FC_PRE_FIFO_RESP_BASE), - _fc_location(fc_location) + wb_iface::sptr iface, const size_t base, fc_monitor_loc fc_location) + : _iface(iface) + , _base(base) + , _fc_base((fc_location == FC_PRE_RADIO or fc_location == FC_DEFAULT) + ? REG_FC_PRE_RADIO_RESP_BASE + : REG_FC_PRE_FIFO_RESP_BASE) + , _fc_location(fc_location) { if (fc_location != FC_DEFAULT) { - //Turn off the other FC monitoring module - const size_t other_fc_base = (fc_location==FC_PRE_RADIO) ? - REG_FC_PRE_FIFO_RESP_BASE : REG_FC_PRE_RADIO_RESP_BASE; + // Turn off the other FC monitoring module + const size_t other_fc_base = (fc_location == FC_PRE_RADIO) + ? REG_FC_PRE_FIFO_RESP_BASE + : REG_FC_PRE_RADIO_RESP_BASE; _iface->poke32(other_fc_base + REG_CTRL_FC_CYCLE_OFFSET, 0); _iface->poke32(other_fc_base + REG_CTRL_FC_PACKET_OFFSET, 0); } @@ -46,75 +46,67 @@ struct tx_vita_core_3000_impl : tx_vita_core_3000 ~tx_vita_core_3000_impl(void) { - UHD_SAFE_CALL - ( - this->clear(); - ) + UHD_SAFE_CALL(this->clear();) } void clear(void) { this->configure_flow_control(0, 0); - this->set_underflow_policy(_policy); //clears the seq + this->set_underflow_policy(_policy); // clears the seq } - void set_underflow_policy(const std::string &policy) + void set_underflow_policy(const std::string& policy) { - if (policy == "next_packet") - { + if (policy == "next_packet") { _iface->poke32(REG_CTRL_ERROR_POLICY, (1 << 1)); - } - else if (policy == "next_burst") - { + } else if (policy == "next_burst") { _iface->poke32(REG_CTRL_ERROR_POLICY, (1 << 2)); - } - else if (policy == "wait") - { + } else if (policy == "wait") { _iface->poke32(REG_CTRL_ERROR_POLICY, (1 << 0)); - } - else throw uhd::value_error("USRP TX cannot handle requested underflow policy: " + policy); + } else + throw uhd::value_error( + "USRP TX cannot handle requested underflow policy: " + policy); _policy = policy; } - void setup(const uhd::stream_args_t &stream_args) + void setup(const uhd::stream_args_t& stream_args) { - if (stream_args.args.has_key("underflow_policy")) - { + if (stream_args.args.has_key("underflow_policy")) { this->set_underflow_policy(stream_args.args["underflow_policy"]); } } void configure_flow_control(const size_t cycs_per_up, const size_t pkts_per_up) { - if (cycs_per_up == 0) _iface->poke32(_fc_base + REG_CTRL_FC_CYCLE_OFFSET, 0); - else _iface->poke32(_fc_base + REG_CTRL_FC_CYCLE_OFFSET, (1 << 31) | ((cycs_per_up) & 0xffffff)); + if (cycs_per_up == 0) + _iface->poke32(_fc_base + REG_CTRL_FC_CYCLE_OFFSET, 0); + else + _iface->poke32(_fc_base + REG_CTRL_FC_CYCLE_OFFSET, + (1 << 31) | ((cycs_per_up)&0xffffff)); - if (pkts_per_up == 0) _iface->poke32(_fc_base + REG_CTRL_FC_PACKET_OFFSET, 0); - else _iface->poke32(_fc_base + REG_CTRL_FC_PACKET_OFFSET, (1 << 31) | ((pkts_per_up) & 0xffff)); + if (pkts_per_up == 0) + _iface->poke32(_fc_base + REG_CTRL_FC_PACKET_OFFSET, 0); + else + _iface->poke32( + _fc_base + REG_CTRL_FC_PACKET_OFFSET, (1 << 31) | ((pkts_per_up)&0xffff)); } - wb_iface::sptr _iface; - const size_t _base; - const size_t _fc_base; - std::string _policy; - fc_monitor_loc _fc_location; - + wb_iface::sptr _iface; + const size_t _base; + const size_t _fc_base; + std::string _policy; + fc_monitor_loc _fc_location; }; tx_vita_core_3000::sptr tx_vita_core_3000::make( - wb_iface::sptr iface, - const size_t base, - fc_monitor_loc fc_location -) + wb_iface::sptr iface, const size_t base, fc_monitor_loc fc_location) { return tx_vita_core_3000::sptr(new tx_vita_core_3000_impl(iface, base, fc_location)); } tx_vita_core_3000::sptr tx_vita_core_3000::make_no_radio_buff( - wb_iface::sptr iface, - const size_t base -) + wb_iface::sptr iface, const size_t base) { - //No internal radio buffer so only pre-radio monitoring is supported. + // No internal radio buffer so only pre-radio monitoring is supported. return tx_vita_core_3000::sptr(new tx_vita_core_3000_impl(iface, base, FC_DEFAULT)); } diff --git a/host/lib/usrp/cores/user_settings_core_200.cpp b/host/lib/usrp/cores/user_settings_core_200.cpp index 7de18d11c..c3606738a 100644 --- a/host/lib/usrp/cores/user_settings_core_200.cpp +++ b/host/lib/usrp/cores/user_settings_core_200.cpp @@ -9,22 +9,25 @@ using namespace uhd; -#define REG_USER_ADDR _base + 0 -#define REG_USER_DATA _base + 4 +#define REG_USER_ADDR _base + 0 +#define REG_USER_DATA _base + 4 -user_settings_core_200::~user_settings_core_200(void){ +user_settings_core_200::~user_settings_core_200(void) +{ /* NOP */ } -class user_settings_core_200_impl : public user_settings_core_200{ +class user_settings_core_200_impl : public user_settings_core_200 +{ public: - user_settings_core_200_impl(wb_iface::sptr iface, const size_t base): - _iface(iface), _base(base) + user_settings_core_200_impl(wb_iface::sptr iface, const size_t base) + : _iface(iface), _base(base) { - //NOP + // NOP } - void set_reg(const user_reg_t ®){ + void set_reg(const user_reg_t& reg) + { _iface->poke32(REG_USER_ADDR, reg.first); _iface->poke32(REG_USER_DATA, reg.second); } @@ -34,6 +37,8 @@ private: const size_t _base; }; -user_settings_core_200::sptr user_settings_core_200::make(wb_iface::sptr iface, const size_t base){ +user_settings_core_200::sptr user_settings_core_200::make( + wb_iface::sptr iface, const size_t base) +{ return sptr(new user_settings_core_200_impl(iface, base)); } diff --git a/host/lib/usrp/cores/user_settings_core_3000.cpp b/host/lib/usrp/cores/user_settings_core_3000.cpp index 66baed57a..7518756f7 100644 --- a/host/lib/usrp/cores/user_settings_core_3000.cpp +++ b/host/lib/usrp/cores/user_settings_core_3000.cpp @@ -5,53 +5,60 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhdlib/usrp/cores/user_settings_core_3000.hpp> #include <uhd/exception.hpp> +#include <uhdlib/usrp/cores/user_settings_core_3000.hpp> #include <boost/thread/thread.hpp> using namespace uhd; -#define REG_USER_SR_ADDR _sr_base_addr + 0 -#define REG_USER_SR_DATA _sr_base_addr + 4 -#define REG_USER_RB_ADDR _sr_base_addr + 8 +#define REG_USER_SR_ADDR _sr_base_addr + 0 +#define REG_USER_SR_DATA _sr_base_addr + 4 +#define REG_USER_RB_ADDR _sr_base_addr + 8 -class user_settings_core_3000_impl : public user_settings_core_3000 { +class user_settings_core_3000_impl : public user_settings_core_3000 +{ public: - user_settings_core_3000_impl( - wb_iface::sptr iface, - const wb_addr_type sr_base_addr, const wb_addr_type rb_reg_addr): - _iface(iface), _sr_base_addr(sr_base_addr), _rb_reg_addr(rb_reg_addr) + user_settings_core_3000_impl(wb_iface::sptr iface, + const wb_addr_type sr_base_addr, + const wb_addr_type rb_reg_addr) + : _iface(iface), _sr_base_addr(sr_base_addr), _rb_reg_addr(rb_reg_addr) { } void poke64(const wb_addr_type offset, const uint64_t value) { - if (offset % sizeof(uint64_t) != 0) throw uhd::value_error("poke64: Incorrect address alignment"); + if (offset % sizeof(uint64_t) != 0) + throw uhd::value_error("poke64: Incorrect address alignment"); poke32(offset, static_cast<uint32_t>(value)); poke32(offset + 4, static_cast<uint32_t>(value >> 32)); } uint64_t peek64(const wb_addr_type offset) { - if (offset % sizeof(uint64_t) != 0) throw uhd::value_error("peek64: Incorrect address alignment"); + if (offset % sizeof(uint64_t) != 0) + throw uhd::value_error("peek64: Incorrect address alignment"); boost::unique_lock<boost::mutex> lock(_mutex); - _iface->poke32(REG_USER_RB_ADDR, offset >> 3); //Translate byte offset to 64-bit offset + _iface->poke32( + REG_USER_RB_ADDR, offset >> 3); // Translate byte offset to 64-bit offset return _iface->peek64(_rb_reg_addr); } void poke32(const wb_addr_type offset, const uint32_t value) { - if (offset % sizeof(uint32_t) != 0) throw uhd::value_error("poke32: Incorrect address alignment"); + if (offset % sizeof(uint32_t) != 0) + throw uhd::value_error("poke32: Incorrect address alignment"); boost::unique_lock<boost::mutex> lock(_mutex); - _iface->poke32(REG_USER_SR_ADDR, offset >> 2); //Translate byte offset to 64-bit offset + _iface->poke32( + REG_USER_SR_ADDR, offset >> 2); // Translate byte offset to 64-bit offset _iface->poke32(REG_USER_SR_DATA, value); } uint32_t peek32(const wb_addr_type offset) { - if (offset % sizeof(uint32_t) != 0) throw uhd::value_error("peek32: Incorrect address alignment"); + if (offset % sizeof(uint32_t) != 0) + throw uhd::value_error("peek32: Incorrect address alignment"); uint64_t value = peek64((offset >> 3) << 3); if ((offset & 0x7) == 0) { @@ -62,14 +69,14 @@ public: } private: - wb_iface::sptr _iface; - const wb_addr_type _sr_base_addr; - const wb_addr_type _rb_reg_addr; - boost::mutex _mutex; + wb_iface::sptr _iface; + const wb_addr_type _sr_base_addr; + const wb_addr_type _rb_reg_addr; + boost::mutex _mutex; }; -wb_iface::sptr user_settings_core_3000::make(wb_iface::sptr iface, - const wb_addr_type sr_base_addr, const wb_addr_type rb_reg_addr) +wb_iface::sptr user_settings_core_3000::make( + wb_iface::sptr iface, const wb_addr_type sr_base_addr, const wb_addr_type rb_reg_addr) { return sptr(new user_settings_core_3000_impl(iface, sr_base_addr, rb_reg_addr)); } diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index 81a7aa534..5e8ac310e 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -7,11 +7,11 @@ #include <uhd/types/dict.hpp> #include <uhd/types/ranges.hpp> -#include <uhd/utils/assert_has.hpp> -#include <uhd/utils/static.hpp> -#include <uhd/utils/log.hpp> #include <uhd/usrp/dboard_base.hpp> #include <uhd/usrp/dboard_manager.hpp> +#include <uhd/utils/assert_has.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/static.hpp> #include <boost/assign/list_of.hpp> #include <boost/format.hpp> @@ -22,37 +22,29 @@ using namespace uhd::usrp; * Constants **********************************************************************/ namespace { - constexpr uint32_t BASIC_TX_PID = 0x0000; - constexpr uint32_t BASIC_RX_PID = 0x0001; - constexpr uint32_t LF_TX_PID = 0x000E; - constexpr uint32_t LF_RX_PID = 0x000F; - - constexpr double BASIC_MAX_BANDWIDTH = 250e6; // Hz - constexpr double LF_MAX_BANDWIDTH = 32e6; // Hz - - - const std::map<std::string, double> subdev_bandwidth_scalar{ - {"A", 1.0}, - {"B", 1.0}, - {"AB", 2.0}, - {"BA", 2.0} - }; - - const uhd::dict<std::string, std::string> sd_name_to_conn = - boost::assign::map_list_of - ("AB", "IQ") - ("BA", "QI") - ("A", "I") - ("B", "Q") - ; -} +constexpr uint32_t BASIC_TX_PID = 0x0000; +constexpr uint32_t BASIC_RX_PID = 0x0001; +constexpr uint32_t LF_TX_PID = 0x000E; +constexpr uint32_t LF_RX_PID = 0x000F; + +constexpr double BASIC_MAX_BANDWIDTH = 250e6; // Hz +constexpr double LF_MAX_BANDWIDTH = 32e6; // Hz + + +const std::map<std::string, double> subdev_bandwidth_scalar{ + {"A", 1.0}, {"B", 1.0}, {"AB", 2.0}, {"BA", 2.0}}; + +const uhd::dict<std::string, std::string> sd_name_to_conn = + boost::assign::map_list_of("AB", "IQ")("BA", "QI")("A", "I")("B", "Q"); +} // namespace /*********************************************************************** * The basic and lf boards: * They share a common class because only the frequency bounds differ. **********************************************************************/ -class basic_rx : public rx_dboard_base{ +class basic_rx : public rx_dboard_base +{ public: basic_rx(ctor_args_t args, double max_freq); virtual ~basic_rx(void); @@ -63,7 +55,8 @@ private: double _max_freq; }; -class basic_tx : public tx_dboard_base{ +class basic_tx : public tx_dboard_base +{ public: basic_tx(ctor_args_t args, double max_freq); virtual ~basic_tx(void); @@ -75,167 +68,171 @@ private: /*********************************************************************** * Register the basic and LF dboards **********************************************************************/ -static dboard_base::sptr make_basic_rx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_basic_rx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new basic_rx(args, BASIC_MAX_BANDWIDTH)); } -static dboard_base::sptr make_basic_tx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_basic_tx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new basic_tx(args, BASIC_MAX_BANDWIDTH)); } -static dboard_base::sptr make_lf_rx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_lf_rx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new basic_rx(args, LF_MAX_BANDWIDTH)); } -static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new basic_tx(args, LF_MAX_BANDWIDTH)); } -UHD_STATIC_BLOCK(reg_basic_and_lf_dboards){ - dboard_manager::register_dboard(BASIC_TX_PID, &make_basic_tx, "Basic TX", sd_name_to_conn.keys()); - dboard_manager::register_dboard(BASIC_RX_PID, &make_basic_rx, "Basic RX", sd_name_to_conn.keys()); - dboard_manager::register_dboard(LF_TX_PID, &make_lf_tx, "LF TX", sd_name_to_conn.keys()); - dboard_manager::register_dboard(LF_RX_PID, &make_lf_rx, "LF RX", sd_name_to_conn.keys()); +UHD_STATIC_BLOCK(reg_basic_and_lf_dboards) +{ + dboard_manager::register_dboard( + BASIC_TX_PID, &make_basic_tx, "Basic TX", sd_name_to_conn.keys()); + dboard_manager::register_dboard( + BASIC_RX_PID, &make_basic_rx, "Basic RX", sd_name_to_conn.keys()); + dboard_manager::register_dboard( + LF_TX_PID, &make_lf_tx, "LF TX", sd_name_to_conn.keys()); + dboard_manager::register_dboard( + LF_RX_PID, &make_lf_rx, "LF RX", sd_name_to_conn.keys()); } /*********************************************************************** * Basic and LF RX dboard **********************************************************************/ basic_rx::basic_rx(ctor_args_t args, double max_freq) - : rx_dboard_base(args), - _max_freq(max_freq) + : rx_dboard_base(args), _max_freq(max_freq) { const std::string fe_name(get_subdev_name()); const std::string fe_conn(sd_name_to_conn[fe_name]); - const std::string db_name(str( - boost::format("%s (%s)") - % ((get_rx_id() == BASIC_RX_PID) ? "BasicRX" : "LFRX") - % fe_name)); + const std::string db_name( + str(boost::format("%s (%s)") + % ((get_rx_id() == BASIC_RX_PID) ? "BasicRX" : "LFRX") % fe_name)); UHD_LOG_TRACE("BASICRX", - "Initializing driver for: " << db_name << - " IQ connection type: " << fe_conn); + "Initializing driver for: " << db_name << " IQ connection type: " << fe_conn); const bool has_fe_conn_settings = get_iface()->has_set_fe_connection(dboard_iface::UNIT_RX); UHD_LOG_TRACE("BASICRX", - "Access to FE connection settings: " - << (has_fe_conn_settings ? "Yes" : "No")); + "Access to FE connection settings: " << (has_fe_conn_settings ? "Yes" : "No")); - std::vector<std::string> antenna_options = has_fe_conn_settings - ? sd_name_to_conn.keys() - : std::vector<std::string>(1, ""); + std::vector<std::string> antenna_options = + has_fe_conn_settings ? sd_name_to_conn.keys() : std::vector<std::string>(1, ""); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// this->get_rx_subtree()->create<std::string>("name").set(db_name); - this->get_rx_subtree()->create<int>("gains"); //phony property so this dir exists - this->get_rx_subtree()->create<double>("freq/value") - .set_publisher([](){ return 0.0; }); - this->get_rx_subtree()->create<meta_range_t>("freq/range") + this->get_rx_subtree()->create<int>("gains"); // phony property so this dir exists + this->get_rx_subtree()->create<double>("freq/value").set_publisher([]() { + return 0.0; + }); + this->get_rx_subtree() + ->create<meta_range_t>("freq/range") .set(freq_range_t(-_max_freq, +_max_freq)); - this->get_rx_subtree()->create<std::string>("antenna/value") + this->get_rx_subtree() + ->create<std::string>("antenna/value") .set(has_fe_conn_settings ? fe_name : ""); if (has_fe_conn_settings) { - this->get_rx_subtree()->access<std::string>("antenna/value") - .add_coerced_subscriber([this](const std::string& ant){ - this->set_rx_ant(ant); - }) - ; + this->get_rx_subtree() + ->access<std::string>("antenna/value") + .add_coerced_subscriber( + [this](const std::string& ant) { this->set_rx_ant(ant); }); } - this->get_rx_subtree()->create<std::vector<std::string>>("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(antenna_options); - this->get_rx_subtree()->create<int>("sensors"); //phony property so this dir exists - this->get_rx_subtree()->create<std::string>("connection") + this->get_rx_subtree()->create<int>("sensors"); // phony property so this dir exists + this->get_rx_subtree() + ->create<std::string>("connection") .set(sd_name_to_conn[get_subdev_name()]); - this->get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_rx_subtree()->create<double>("bandwidth/value") - .set(subdev_bandwidth_scalar.at(get_subdev_name())*_max_freq); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t( - subdev_bandwidth_scalar.at(get_subdev_name())*_max_freq, - subdev_bandwidth_scalar.at(get_subdev_name())*_max_freq)); - - //disable RX dboard clock by default + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_rx_subtree() + ->create<double>("bandwidth/value") + .set(subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq); + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq, + subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq)); + + // disable RX dboard clock by default this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, false); - //set GPIOs to output 0x0000 to decrease noise pickup + // set GPIOs to output 0x0000 to decrease noise pickup this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0000); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0xFFFF); this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, 0x0000); } -basic_rx::~basic_rx(void){ +basic_rx::~basic_rx(void) +{ /* NOP */ } void basic_rx::set_rx_ant(const std::string& ant) { UHD_ASSERT_THROW(get_iface()->has_set_fe_connection(dboard_iface::UNIT_RX)); - UHD_LOG_TRACE("BASICRX", - "Setting antenna value to: " << ant); - get_iface()->set_fe_connection( - dboard_iface::UNIT_RX, + UHD_LOG_TRACE("BASICRX", "Setting antenna value to: " << ant); + get_iface()->set_fe_connection(dboard_iface::UNIT_RX, get_subdev_name(), - usrp::fe_connection_t(sd_name_to_conn[ant], 0.0 /* IF */) - ); + usrp::fe_connection_t(sd_name_to_conn[ant], 0.0 /* IF */)); } /*********************************************************************** * Basic and LF TX dboard **********************************************************************/ -basic_tx::basic_tx(ctor_args_t args, double max_freq) : tx_dboard_base(args){ +basic_tx::basic_tx(ctor_args_t args, double max_freq) : tx_dboard_base(args) +{ _max_freq = max_freq; - //this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); + // this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// if (get_tx_id() == BASIC_TX_PID) { this->get_tx_subtree()->create<std::string>("name").set( - std::string(str(boost::format("BasicTX (%s)") % get_subdev_name() - ))); - } - else { + std::string(str(boost::format("BasicTX (%s)") % get_subdev_name()))); + } else { this->get_tx_subtree()->create<std::string>("name").set( - std::string(str(boost::format("LFTX (%s)") % get_subdev_name() - ))); + std::string(str(boost::format("LFTX (%s)") % get_subdev_name()))); } - this->get_tx_subtree()->create<int>("gains"); //phony property so this dir exists - this->get_tx_subtree()->create<double>("freq/value") - .set_publisher([](){ return 0.0; }); - this->get_tx_subtree()->create<meta_range_t>("freq/range") + this->get_tx_subtree()->create<int>("gains"); // phony property so this dir exists + this->get_tx_subtree()->create<double>("freq/value").set_publisher([]() { + return 0.0; + }); + this->get_tx_subtree() + ->create<meta_range_t>("freq/range") .set(freq_range_t(-_max_freq, +_max_freq)); - this->get_tx_subtree()->create<std::string>("antenna/value") - .set(""); - this->get_tx_subtree()->create<std::vector<std::string>>("antenna/options") - .set({""}); - this->get_tx_subtree()->create<int>("sensors"); //phony property so this dir exists - this->get_tx_subtree()->create<std::string>("connection") + this->get_tx_subtree()->create<std::string>("antenna/value").set(""); + this->get_tx_subtree()->create<std::vector<std::string>>("antenna/options").set({""}); + this->get_tx_subtree()->create<int>("sensors"); // phony property so this dir exists + this->get_tx_subtree() + ->create<std::string>("connection") .set(sd_name_to_conn[get_subdev_name()]); - this->get_tx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_tx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_tx_subtree()->create<double>("bandwidth/value") - .set(subdev_bandwidth_scalar.at(get_subdev_name())*_max_freq); - this->get_tx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t( - subdev_bandwidth_scalar.at(get_subdev_name())*_max_freq, - subdev_bandwidth_scalar.at(get_subdev_name())*_max_freq)); - - //disable TX dboard clock by default + this->get_tx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_tx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_tx_subtree() + ->create<double>("bandwidth/value") + .set(subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq); + this->get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq, + subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq)); + + // disable TX dboard clock by default this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, false); - //set GPIOs to output 0x0000 to decrease noise pickup + // set GPIOs to output 0x0000 to decrease noise pickup this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, 0x0000); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, 0xFFFF); this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, 0x0000); } -basic_tx::~basic_tx(void){ +basic_tx::~basic_tx(void) +{ /* NOP */ } diff --git a/host/lib/usrp/dboard/db_cbx.cpp b/host/lib/usrp/dboard/db_cbx.cpp index c08ae11ae..40bc49861 100644 --- a/host/lib/usrp/dboard/db_cbx.cpp +++ b/host/lib/usrp/dboard/db_cbx.cpp @@ -17,22 +17,30 @@ using namespace boost::assign; /*********************************************************************** * Structors **********************************************************************/ -sbx_xcvr::cbx::cbx(sbx_xcvr *_self_sbx_xcvr) { - //register the handle to our base CBX class +sbx_xcvr::cbx::cbx(sbx_xcvr* _self_sbx_xcvr) +{ + // register the handle to our base CBX class self_base = _self_sbx_xcvr; - _txlo = max287x_iface::make<max2870>(std::bind(&sbx_xcvr::cbx::write_lo_regs, this, dboard_iface::UNIT_TX, std::placeholders::_1)); - _rxlo = max287x_iface::make<max2870>(std::bind(&sbx_xcvr::cbx::write_lo_regs, this, dboard_iface::UNIT_RX, std::placeholders::_1)); + _txlo = max287x_iface::make<max2870>(std::bind(&sbx_xcvr::cbx::write_lo_regs, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)); + _rxlo = max287x_iface::make<max2870>(std::bind(&sbx_xcvr::cbx::write_lo_regs, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)); } -sbx_xcvr::cbx::~cbx(void){ +sbx_xcvr::cbx::~cbx(void) +{ /* NOP */ } -void sbx_xcvr::cbx::write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s) +void sbx_xcvr::cbx::write_lo_regs( + dboard_iface::unit_t unit, const std::vector<uint32_t>& regs) { - for(uint32_t reg: regs) - { + for (uint32_t reg : regs) { self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, reg, 32); } } @@ -41,39 +49,40 @@ void sbx_xcvr::cbx::write_lo_regs(dboard_iface::unit_t unit, const std::vector<u /*********************************************************************** * Tuning **********************************************************************/ -double sbx_xcvr::cbx::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { - UHD_LOGGER_TRACE("CBX") << boost::format( - "CBX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; +double sbx_xcvr::cbx::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + UHD_LOGGER_TRACE("CBX") << boost::format("CBX tune: target frequency %f MHz") + % (target_freq / 1e6); - //clip the input + // clip the input target_freq = cbx_freq_range.clip(target_freq); - double ref_freq = self_base->get_iface()->get_clock_rate(unit); + double ref_freq = self_base->get_iface()->get_clock_rate(unit); double target_pfd_freq = 25e6; - double actual_freq = 0.0; + double actual_freq = 0.0; /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to * tune in Integer-N mode, which can result in better spur * performance on some mixers. The default is fractional tuning. */ - property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree() - : self_base->get_tx_subtree(); + property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) + ? self_base->get_rx_subtree() + : self_base->get_tx_subtree(); device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); + bool is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); - if (unit == dboard_iface::UNIT_RX) - { - actual_freq = _rxlo->set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); + if (unit == dboard_iface::UNIT_RX) { + actual_freq = + _rxlo->set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); _rxlo->commit(); } else { - actual_freq = _txlo->set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); + actual_freq = + _txlo->set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); _txlo->set_output_power((actual_freq == sbx_tx_lo_2dbm.clip(actual_freq)) - ? max287x_iface::OUTPUT_POWER_2DBM - : max287x_iface::OUTPUT_POWER_5DBM); + ? max287x_iface::OUTPUT_POWER_2DBM + : max287x_iface::OUTPUT_POWER_5DBM); _txlo->commit(); } return actual_freq; } - diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp index 6e4d482be..238dbd95e 100644 --- a/host/lib/usrp/dboard/db_dbsrx.cpp +++ b/host/lib/usrp/dboard/db_dbsrx.cpp @@ -37,24 +37,23 @@ using namespace boost::assign; **********************************************************************/ static const freq_range_t dbsrx_freq_range(0.8e9, 2.4e9); -//Multiplied by 2.0 for conversion to complex bandpass from lowpass -static const freq_range_t dbsrx_bandwidth_range(2.0*4.0e6, 2.0*33.0e6); +// Multiplied by 2.0 for conversion to complex bandpass from lowpass +static const freq_range_t dbsrx_bandwidth_range(2.0 * 4.0e6, 2.0 * 33.0e6); static const freq_range_t dbsrx_pfd_freq_range(0.15e6, 2.01e6); static const std::vector<std::string> dbsrx_antennas = list_of("J3"); -static const uhd::dict<std::string, gain_range_t> dbsrx_gain_ranges = map_list_of - ("GC1", gain_range_t(0, 56, 0.5)) - ("GC2", gain_range_t(0, 24, 1)) -; +static const uhd::dict<std::string, gain_range_t> dbsrx_gain_ranges = + map_list_of("GC1", gain_range_t(0, 56, 0.5))("GC2", gain_range_t(0, 24, 1)); static const double usrp1_gpio_clock_rate_limit = 4e6; /*********************************************************************** * The DBSRX dboard class **********************************************************************/ -class dbsrx : public rx_dboard_base{ +class dbsrx : public rx_dboard_base +{ public: dbsrx(ctor_args_t args); virtual ~dbsrx(void); @@ -65,65 +64,74 @@ private: uhd::dict<std::string, double> _gains; max2118_write_regs_t _max2118_write_regs; max2118_read_regs_t _max2118_read_regs; - uint8_t _max2118_addr(void){ - return (this->get_iface()->get_special_props().mangle_i2c_addrs)? 0x65 : 0x67; + uint8_t _max2118_addr(void) + { + return (this->get_iface()->get_special_props().mangle_i2c_addrs) ? 0x65 : 0x67; }; double set_lo_freq(double target_freq); - double set_gain(double gain, const std::string &name); + double set_gain(double gain, const std::string& name); double set_bandwidth(double bandwidth); - void send_reg(uint8_t start_reg, uint8_t stop_reg){ + void send_reg(uint8_t start_reg, uint8_t stop_reg) + { start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0x5)); - stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x5)); + stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x5)); - for(uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(uint32_t) - 1){ - int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) - 1 ? sizeof(uint32_t) - 1 : stop_reg - start_addr + 1; + for (uint8_t start_addr = start_reg; start_addr <= stop_reg; + start_addr += sizeof(uint32_t) - 1) { + int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) - 1 + ? sizeof(uint32_t) - 1 + : stop_reg - start_addr + 1; - //create buffer for register data (+1 for start address) + // create buffer for register data (+1 for start address) byte_vector_t regs_vector(num_bytes + 1); - //first byte is the address of first register + // first byte is the address of first register regs_vector[0] = start_addr; - //get the register data - for(int i=0; i<num_bytes; i++){ - regs_vector[1+i] = _max2118_write_regs.get_reg(start_addr+i); - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: send reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d" - ) % int(start_addr+i) % int(regs_vector[1+i]) % int(start_addr) % num_bytes ; + // get the register data + for (int i = 0; i < num_bytes; i++) { + regs_vector[1 + i] = _max2118_write_regs.get_reg(start_addr + i); + UHD_LOGGER_TRACE("DBSRX") + << boost::format("DBSRX: send reg 0x%02x, value 0x%04x, start_addr = " + "0x%04x, num_bytes %d") + % int(start_addr + i) % int(regs_vector[1 + i]) + % int(start_addr) % num_bytes; } - //send the data - this->get_iface()->write_i2c( - _max2118_addr(), regs_vector - ); + // send the data + this->get_iface()->write_i2c(_max2118_addr(), regs_vector); } } - void read_reg(uint8_t start_reg, uint8_t stop_reg){ + void read_reg(uint8_t start_reg, uint8_t stop_reg) + { static const uint8_t status_addr = 0x0; - start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0x1)); - stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x1)); + start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0x1)); + stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x1)); - for(uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(uint32_t)){ - int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) ? sizeof(uint32_t) : stop_reg - start_addr + 1; + for (uint8_t start_addr = start_reg; start_addr <= stop_reg; + start_addr += sizeof(uint32_t)) { + int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) + ? sizeof(uint32_t) + : stop_reg - start_addr + 1; - //create buffer for register data + // create buffer for register data byte_vector_t regs_vector(num_bytes); - //read from i2c - regs_vector = this->get_iface()->read_i2c( - _max2118_addr(), num_bytes - ); + // read from i2c + regs_vector = this->get_iface()->read_i2c(_max2118_addr(), num_bytes); - for(uint8_t i=0; i < num_bytes; i++){ - if (i + start_addr >= status_addr){ + for (uint8_t i = 0; i < num_bytes; i++) { + if (i + start_addr >= status_addr) { _max2118_read_regs.set_reg(i + start_addr, regs_vector[i]); } - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: read reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d" - ) % int(start_addr+i) % int(regs_vector[i]) % int(start_addr) % num_bytes ; + UHD_LOGGER_TRACE("DBSRX") + << boost::format("DBSRX: read reg 0x%02x, value 0x%04x, start_addr = " + "0x%04x, num_bytes %d") + % int(start_addr + i) % int(regs_vector[i]) % int(start_addr) + % num_bytes; } } } @@ -132,15 +140,14 @@ private: * Get the lock detect status of the LO. * \return sensor for locked */ - sensor_value_t get_locked(void){ + sensor_value_t get_locked(void) + { read_reg(0x0, 0x0); - //mask and return lock detect + // mask and return lock detect bool locked = 5 >= _max2118_read_regs.adc and _max2118_read_regs.adc >= 2; - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: locked %d" - ) % locked ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX: locked %d") % locked; return sensor_value_t("LO", locked, "locked", "unlocked"); } @@ -149,190 +156,214 @@ private: /*********************************************************************** * Register the DBSRX dboard **********************************************************************/ -static dboard_base::sptr make_dbsrx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_dbsrx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new dbsrx(args)); } -UHD_STATIC_BLOCK(reg_dbsrx_dboard){ - //register the factory function for the rx dbid (others version) +UHD_STATIC_BLOCK(reg_dbsrx_dboard) +{ + // register the factory function for the rx dbid (others version) dboard_manager::register_dboard(0x000D, &make_dbsrx, "DBSRX"); - //register the factory function for the rx dbid (USRP1 version) + // register the factory function for the rx dbid (USRP1 version) dboard_manager::register_dboard(0x0002, &make_dbsrx, "DBSRX"); } /*********************************************************************** * Structors **********************************************************************/ -dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){ - //warn user about incorrect DBID on USRP1, requires R193 populated - if (this->get_iface()->get_special_props().soft_clock_divider and this->get_rx_id() == 0x000D) - UHD_LOGGER_WARNING("DBSRX") << boost::format( - "DBSRX: incorrect dbid\n" - "Expected dbid 0x0002 and R193\n" - "found dbid == %d\n" - "Please see the daughterboard app notes" - ) % this->get_rx_id().to_pp_string(); - - //warn user about incorrect DBID on non-USRP1, requires R194 populated - if (not this->get_iface()->get_special_props().soft_clock_divider and this->get_rx_id() == 0x0002) - UHD_LOGGER_WARNING("DBSRX") << boost::format( - "DBSRX: incorrect dbid\n" - "Expected dbid 0x000D and R194\n" - "found dbid == %d\n" - "Please see the daughterboard app notes" - ) % this->get_rx_id().to_pp_string(); - - //send initial register settings +dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args) +{ + // warn user about incorrect DBID on USRP1, requires R193 populated + if (this->get_iface()->get_special_props().soft_clock_divider + and this->get_rx_id() == 0x000D) + UHD_LOGGER_WARNING("DBSRX") + << boost::format("DBSRX: incorrect dbid\n" + "Expected dbid 0x0002 and R193\n" + "found dbid == %d\n" + "Please see the daughterboard app notes") + % this->get_rx_id().to_pp_string(); + + // warn user about incorrect DBID on non-USRP1, requires R194 populated + if (not this->get_iface()->get_special_props().soft_clock_divider + and this->get_rx_id() == 0x0002) + UHD_LOGGER_WARNING("DBSRX") + << boost::format("DBSRX: incorrect dbid\n" + "Expected dbid 0x000D and R194\n" + "found dbid == %d\n" + "Please see the daughterboard app notes") + % this->get_rx_id().to_pp_string(); + + // send initial register settings this->send_reg(0x0, 0x5); - //set defaults for LO, gains, and filter bandwidth + // set defaults for LO, gains, and filter bandwidth double codec_rate = this->get_iface()->get_codec_rate(dboard_iface::UNIT_RX); - _bandwidth = 0.8*codec_rate/2.0; // default to anti-alias at different codec_rate + _bandwidth = 0.8 * codec_rate / 2.0; // default to anti-alias at different codec_rate //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - this->get_rx_subtree()->create<std::string>("name") - .set("DBSRX"); - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_rx_subtree()->create<std::string>("name").set("DBSRX"); + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&dbsrx::get_locked, this)); - for(const std::string &name: dbsrx_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") + for (const std::string& name : dbsrx_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") .set_coercer(std::bind(&dbsrx::set_gain, this, std::placeholders::_1, name)) .set(dbsrx_gain_ranges[name].start()); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(dbsrx_gain_ranges[name]); } - this->get_rx_subtree()->create<double>("freq/value") + this->get_rx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&dbsrx::set_lo_freq, this, std::placeholders::_1)); - this->get_rx_subtree()->create<meta_range_t>("freq/range") - .set(dbsrx_freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") + this->get_rx_subtree()->create<meta_range_t>("freq/range").set(dbsrx_freq_range); + this->get_rx_subtree() + ->create<std::string>("antenna/value") .set(dbsrx_antennas.at(0)); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(dbsrx_antennas); - this->get_rx_subtree()->create<std::string>("connection") - .set("IQ"); - this->get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_rx_subtree()->create<double>("bandwidth/value") + this->get_rx_subtree()->create<std::string>("connection").set("IQ"); + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_rx_subtree() + ->create<double>("bandwidth/value") .set_coercer(std::bind(&dbsrx::set_bandwidth, this, std::placeholders::_1)); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(dbsrx_bandwidth_range); - //enable only the clocks we need + // enable only the clocks we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); - //set the gpio directions and atr controls (identically) + // set the gpio directions and atr controls (identically) this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0); // All unused in atr - if (this->get_iface()->get_special_props().soft_clock_divider){ - this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x1); // GPIO0 is clock when on USRP1 - } - else{ + if (this->get_iface()->get_special_props().soft_clock_divider) { + this->get_iface()->set_gpio_ddr( + dboard_iface::UNIT_RX, 0x1); // GPIO0 is clock when on USRP1 + } else { this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x0); // All Inputs } - //now its safe to set inital freq and bw - this->get_rx_subtree()->access<double>("freq/value") - .set(dbsrx_freq_range.start()); - this->get_rx_subtree()->access<double>("bandwidth/value") - .set(2.0*_bandwidth); //_bandwidth in lowpass, convert to complex bandpass + // now its safe to set inital freq and bw + this->get_rx_subtree()->access<double>("freq/value").set(dbsrx_freq_range.start()); + this->get_rx_subtree() + ->access<double>("bandwidth/value") + .set(2.0 * _bandwidth); //_bandwidth in lowpass, convert to complex bandpass } -dbsrx::~dbsrx(void){ -} +dbsrx::~dbsrx(void) {} /*********************************************************************** * Tuning **********************************************************************/ -double dbsrx::set_lo_freq(double target_freq){ +double dbsrx::set_lo_freq(double target_freq) +{ target_freq = dbsrx_freq_range.clip(target_freq); - double actual_freq=0.0, pfd_freq=0.0, ref_clock=0.0; - int R=0, N=0, r=0, m=0; + double actual_freq = 0.0, pfd_freq = 0.0, ref_clock = 0.0; + int R = 0, N = 0, r = 0, m = 0; bool update_filter_settings = false; - //choose refclock - std::vector<double> clock_rates = this->get_iface()->get_clock_rates(dboard_iface::UNIT_RX); + // choose refclock + std::vector<double> clock_rates = + this->get_iface()->get_clock_rates(dboard_iface::UNIT_RX); const double max_clock_rate = uhd::sorted(clock_rates).back(); - for(auto ref_clock: uhd::reversed(uhd::sorted(clock_rates))){ - //USRP1 feeds the DBSRX clock from a FPGA GPIO line. - //make sure that this clock does not exceed rate limit. - if (this->get_iface()->get_special_props().soft_clock_divider){ - if (ref_clock > usrp1_gpio_clock_rate_limit) continue; + for (auto ref_clock : uhd::reversed(uhd::sorted(clock_rates))) { + // USRP1 feeds the DBSRX clock from a FPGA GPIO line. + // make sure that this clock does not exceed rate limit. + if (this->get_iface()->get_special_props().soft_clock_divider) { + if (ref_clock > usrp1_gpio_clock_rate_limit) + continue; } - if (ref_clock > 27.0e6) continue; - if (size_t(max_clock_rate/ref_clock)%2 == 1) continue; //reject asymmetric clocks (odd divisors) + if (ref_clock > 27.0e6) + continue; + if (size_t(max_clock_rate / ref_clock) % 2 == 1) + continue; // reject asymmetric clocks (odd divisors) - //choose m_divider such that filter tuning constraint is met + // choose m_divider such that filter tuning constraint is met m = 31; - while ((ref_clock/m < 1e6 or ref_clock/m > 2.5e6) and m > 0){ m--; } + while ((ref_clock / m < 1e6 or ref_clock / m > 2.5e6) and m > 0) { + m--; + } - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: trying ref_clock %f and m_divider %d" - ) % (ref_clock) % m ; + UHD_LOGGER_TRACE("DBSRX") + << boost::format("DBSRX: trying ref_clock %f and m_divider %d") % (ref_clock) + % m; - if (m >= 32) continue; + if (m >= 32) + continue; - //choose R - for(auto r = 0; r <= 6; r += 1) { - //compute divider from setting - R = 1 << (r+1); - UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX R:%d\n") % R ; + // choose R + for (auto r = 0; r <= 6; r += 1) { + // compute divider from setting + R = 1 << (r + 1); + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX R:%d\n") % R; - //compute PFD compare frequency = ref_clock/R + // compute PFD compare frequency = ref_clock/R pfd_freq = ref_clock / R; - //constrain the PFD frequency to specified range - if ((pfd_freq < dbsrx_pfd_freq_range.start()) or (pfd_freq > dbsrx_pfd_freq_range.stop())) continue; + // constrain the PFD frequency to specified range + if ((pfd_freq < dbsrx_pfd_freq_range.start()) + or (pfd_freq > dbsrx_pfd_freq_range.stop())) + continue; - //compute N - N = int(std::floor(target_freq/pfd_freq)); + // compute N + N = int(std::floor(target_freq / pfd_freq)); - //constrain N to specified range - if ((N < 256) or (N > 32768)) continue; + // constrain N to specified range + if ((N < 256) or (N > 32768)) + continue; goto done_loop; } } - done_loop: +done_loop: - //Assert because we failed to find a suitable combination of ref_clock, R and N + // Assert because we failed to find a suitable combination of ref_clock, R and N UHD_ASSERT_THROW(ref_clock <= 27.0e6 and ref_clock >= 0.0); - UHD_ASSERT_THROW(m and ref_clock/m >= 1e6 and ref_clock/m <= 2.5e6); - UHD_ASSERT_THROW((pfd_freq >= dbsrx_pfd_freq_range.start()) and (pfd_freq <= dbsrx_pfd_freq_range.stop())); + UHD_ASSERT_THROW(m and ref_clock / m >= 1e6 and ref_clock / m <= 2.5e6); + UHD_ASSERT_THROW((pfd_freq >= dbsrx_pfd_freq_range.start()) + and (pfd_freq <= dbsrx_pfd_freq_range.stop())); UHD_ASSERT_THROW((N >= 256) and (N <= 32768)); - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: choose ref_clock (current: %f, new: %f) and m_divider %d" - ) % (this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)) % ref_clock % m ; + UHD_LOGGER_TRACE("DBSRX") + << boost::format( + "DBSRX: choose ref_clock (current: %f, new: %f) and m_divider %d") + % (this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)) % ref_clock + % m; - //if ref_clock or m divider changed, we need to update the filter settings - if (ref_clock != this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX) or m != _max2118_write_regs.m_divider) update_filter_settings = true; + // if ref_clock or m divider changed, we need to update the filter settings + if (ref_clock != this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX) + or m != _max2118_write_regs.m_divider) + update_filter_settings = true; - //compute resulting output frequency + // compute resulting output frequency actual_freq = pfd_freq * N; - //apply ref_clock, R, and N settings + // apply ref_clock, R, and N settings this->get_iface()->set_clock_rate(dboard_iface::UNIT_RX, ref_clock); ref_clock = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); _max2118_write_regs.m_divider = m; - _max2118_write_regs.r_divider = (max2118_write_regs_t::r_divider_t) r; + _max2118_write_regs.r_divider = (max2118_write_regs_t::r_divider_t)r; _max2118_write_regs.set_n_divider(N); _max2118_write_regs.ade_vco_ade_read = max2118_write_regs_t::ADE_VCO_ADE_READ_ENABLED; - //compute prescaler variables - int scaler = actual_freq > 1125e6 ? 2 : 4; - _max2118_write_regs.div2 = scaler == 4 ? max2118_write_regs_t::DIV2_DIV4 : max2118_write_regs_t::DIV2_DIV2; + // compute prescaler variables + int scaler = actual_freq > 1125e6 ? 2 : 4; + _max2118_write_regs.div2 = scaler == 4 ? max2118_write_regs_t::DIV2_DIV4 + : max2118_write_regs_t::DIV2_DIV2; - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: scaler %d, actual_freq %f MHz, register bit: %d" - ) % scaler % (actual_freq/1e6) % int(_max2118_write_regs.div2) ; + UHD_LOGGER_TRACE("DBSRX") + << boost::format("DBSRX: scaler %d, actual_freq %f MHz, register bit: %d") + % scaler % (actual_freq / 1e6) % int(_max2118_write_regs.div2); - //compute vco frequency and select vco + // compute vco frequency and select vco double vco_freq = actual_freq * scaler; if (vco_freq < 2433e6) _max2118_write_regs.osc_band = 0; @@ -351,82 +382,94 @@ double dbsrx::set_lo_freq(double target_freq){ else _max2118_write_regs.osc_band = 7; - //send settings over i2c + // send settings over i2c send_reg(0x0, 0x4); - //check vtune for lock condition + // check vtune for lock condition read_reg(0x0, 0x0); UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: initial guess for vco %d, vtune adc %d" - ) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) ; - - //if we are out of lock for chosen vco, change vco - while ((_max2118_read_regs.adc == 0) or (_max2118_read_regs.adc == 7)){ - - //vtune is too low, try lower frequency vco - if (_max2118_read_regs.adc == 0){ - if (_max2118_write_regs.osc_band == 0){ - UHD_LOGGER_WARNING("DBSRX") << boost::format( - "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n" - ) % int(_max2118_write_regs.osc_band); - UHD_ASSERT_THROW(_max2118_read_regs.adc != 0); //just to cause a throw + "DBSRX: initial guess for vco %d, vtune adc %d") + % int(_max2118_write_regs.osc_band) + % int(_max2118_read_regs.adc); + + // if we are out of lock for chosen vco, change vco + while ((_max2118_read_regs.adc == 0) or (_max2118_read_regs.adc == 7)) { + // vtune is too low, try lower frequency vco + if (_max2118_read_regs.adc == 0) { + if (_max2118_write_regs.osc_band == 0) { + UHD_LOGGER_WARNING("DBSRX") + << boost::format("DBSRX: Tuning exceeded vco range, " + "_max2118_write_regs.osc_band == %d\n") + % int(_max2118_write_regs.osc_band); + UHD_ASSERT_THROW(_max2118_read_regs.adc != 0); // just to cause a throw } - if (_max2118_write_regs.osc_band <= 0) break; + if (_max2118_write_regs.osc_band <= 0) + break; _max2118_write_regs.osc_band -= 1; } - //vtune is too high, try higher frequency vco - if (_max2118_read_regs.adc == 7){ - if (_max2118_write_regs.osc_band == 7){ - UHD_LOGGER_WARNING("DBSRX") << boost::format( - "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n" - ) % int(_max2118_write_regs.osc_band); - UHD_ASSERT_THROW(_max2118_read_regs.adc != 7); //just to cause a throw + // vtune is too high, try higher frequency vco + if (_max2118_read_regs.adc == 7) { + if (_max2118_write_regs.osc_band == 7) { + UHD_LOGGER_WARNING("DBSRX") + << boost::format("DBSRX: Tuning exceeded vco range, " + "_max2118_write_regs.osc_band == %d\n") + % int(_max2118_write_regs.osc_band); + UHD_ASSERT_THROW(_max2118_read_regs.adc != 7); // just to cause a throw } - if (_max2118_write_regs.osc_band >= 7) break; + if (_max2118_write_regs.osc_band >= 7) + break; _max2118_write_regs.osc_band += 1; } - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: trying vco %d, vtune adc %d" - ) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX: trying vco %d, vtune adc %d") + % int(_max2118_write_regs.osc_band) + % int(_max2118_read_regs.adc); - //update vco selection and check vtune + // update vco selection and check vtune send_reg(0x2, 0x2); read_reg(0x0, 0x0); - //allow for setup time before checking condition again + // allow for setup time before checking condition again std::this_thread::sleep_for(std::chrono::milliseconds(10)); } - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: final vco %d, vtune adc %d" - ) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX: final vco %d, vtune adc %d") + % int(_max2118_write_regs.osc_band) + % int(_max2118_read_regs.adc); - //select charge pump bias current - if (_max2118_read_regs.adc <= 2) _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_100UA; - else if (_max2118_read_regs.adc >= 5) _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_400UA; - else _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_200UA; + // select charge pump bias current + if (_max2118_read_regs.adc <= 2) + _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_100UA; + else if (_max2118_read_regs.adc >= 5) + _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_400UA; + else + _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_200UA; - //update charge pump bias current setting + // update charge pump bias current setting send_reg(0x2, 0x2); - //compute actual tuned frequency - _lo_freq = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX) / std::pow(2.0,(1 + _max2118_write_regs.r_divider)) * _max2118_write_regs.get_n_divider(); + // compute actual tuned frequency + _lo_freq = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX) + / std::pow(2.0, (1 + _max2118_write_regs.r_divider)) + * _max2118_write_regs.get_n_divider(); - //debug output of calculated variables + // debug output of calculated variables UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX tune:\n") - << boost::format(" VCO=%d, CP=%d, PFD Freq=%fMHz\n") % int(_max2118_write_regs.osc_band) % _max2118_write_regs.cp_current % (pfd_freq/1e6) - << boost::format(" R=%d, N=%f, scaler=%d, div2=%d\n") % R % N % scaler % int(_max2118_write_regs.div2) - << boost::format(" Ref Freq=%fMHz\n") % (ref_clock/1e6) - << boost::format(" Target Freq=%fMHz\n") % (target_freq/1e6) - << boost::format(" Actual Freq=%fMHz\n") % (_lo_freq/1e6) - << boost::format(" VCO Freq=%fMHz\n") % (vco_freq/1e6) - ; - - if (update_filter_settings) set_bandwidth(_bandwidth); + << boost::format(" VCO=%d, CP=%d, PFD Freq=%fMHz\n") + % int(_max2118_write_regs.osc_band) % _max2118_write_regs.cp_current + % (pfd_freq / 1e6) + << boost::format(" R=%d, N=%f, scaler=%d, div2=%d\n") % R % N % scaler + % int(_max2118_write_regs.div2) + << boost::format(" Ref Freq=%fMHz\n") % (ref_clock / 1e6) + << boost::format(" Target Freq=%fMHz\n") % (target_freq / 1e6) + << boost::format(" Actual Freq=%fMHz\n") % (_lo_freq / 1e6) + << boost::format(" VCO Freq=%fMHz\n") % (vco_freq / 1e6); + + if (update_filter_settings) + set_bandwidth(_bandwidth); get_locked(); return _lo_freq; @@ -441,22 +484,22 @@ double dbsrx::set_lo_freq(double target_freq){ * \param gain the requested gain in dB * \return 5 bit the register value */ -static int gain_to_gc2_vga_reg(double &gain){ +static int gain_to_gc2_vga_reg(double& gain) +{ int reg = 0; - gain = dbsrx_gain_ranges["GC2"].clip(gain); + gain = dbsrx_gain_ranges["GC2"].clip(gain); // Half dB steps from 0-5dB, 1dB steps from 5-24dB if (gain < 5) { - reg = boost::math::iround(31.0 - gain/0.5); + reg = boost::math::iround(31.0 - gain / 0.5); gain = double(boost::math::iround(gain) * 0.5); } else { - reg = boost::math::iround(22.0 - (gain - 4.0)); + reg = boost::math::iround(22.0 - (gain - 4.0)); gain = double(boost::math::iround(gain)); } - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX GC2 Gain: %f dB, reg: %d" - ) % gain % reg ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX GC2 Gain: %f dB, reg: %d") % gain + % reg; return reg; } @@ -467,38 +510,39 @@ static int gain_to_gc2_vga_reg(double &gain){ * \param gain the requested gain in dB * \return dac voltage value */ -static double gain_to_gc1_rfvga_dac(double &gain){ - //clip the input +static double gain_to_gc1_rfvga_dac(double& gain) +{ + // clip the input gain = dbsrx_gain_ranges["GC1"].clip(gain); - //voltage level constants + // voltage level constants static const double max_volts = 1.2, min_volts = 2.7; - static const double slope = (max_volts-min_volts)/dbsrx_gain_ranges["GC1"].stop(); + static const double slope = (max_volts - min_volts) / dbsrx_gain_ranges["GC1"].stop(); - //calculate the voltage for the aux dac - double dac_volts = gain*slope + min_volts; + // calculate the voltage for the aux dac + double dac_volts = gain * slope + min_volts; - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX GC1 Gain: %f dB, dac_volts: %f V" - ) % gain % dac_volts ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX GC1 Gain: %f dB, dac_volts: %f V") + % gain % dac_volts; - //the actual gain setting - gain = (dac_volts - min_volts)/slope; + // the actual gain setting + gain = (dac_volts - min_volts) / slope; return dac_volts; } -double dbsrx::set_gain(double gain, const std::string &name){ +double dbsrx::set_gain(double gain, const std::string& name) +{ assert_has(dbsrx_gain_ranges.keys(), name, "dbsrx gain name"); - if (name == "GC2"){ + if (name == "GC2") { _max2118_write_regs.gc2 = gain_to_gc2_vga_reg(gain); send_reg(0x5, 0x5); - } - else if(name == "GC1"){ - //write the new voltage to the aux dac - this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, gain_to_gc1_rfvga_dac(gain)); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else if (name == "GC1") { + // write the new voltage to the aux dac + this->get_iface()->write_aux_dac( + dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, gain_to_gc1_rfvga_dac(gain)); + } else + UHD_THROW_INVALID_CODE_PATH(); _gains[name] = gain; return gain; @@ -507,29 +551,36 @@ double dbsrx::set_gain(double gain, const std::string &name){ /*********************************************************************** * Bandwidth Handling **********************************************************************/ -double dbsrx::set_bandwidth(double bandwidth){ - //convert complex bandpass to lowpass bandwidth - bandwidth = bandwidth/2.0; +double dbsrx::set_bandwidth(double bandwidth) +{ + // convert complex bandpass to lowpass bandwidth + bandwidth = bandwidth / 2.0; - //clip the input + // clip the input bandwidth = dbsrx_bandwidth_range.clip(bandwidth); double ref_clock = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); - //NOTE: _max2118_write_regs.m_divider set in set_lo_freq + // NOTE: _max2118_write_regs.m_divider set in set_lo_freq - //compute f_dac setting - _max2118_write_regs.f_dac = uhd::clip<int>(int((((bandwidth*_max2118_write_regs.m_divider)/ref_clock) - 4)/0.145),0,127); + // compute f_dac setting + _max2118_write_regs.f_dac = uhd::clip<int>( + int((((bandwidth * _max2118_write_regs.m_divider) / ref_clock) - 4) / 0.145), + 0, + 127); - //determine actual bandwidth - _bandwidth = double((ref_clock/(_max2118_write_regs.m_divider))*(4+0.145*_max2118_write_regs.f_dac)); + // determine actual bandwidth + _bandwidth = double((ref_clock / (_max2118_write_regs.m_divider)) + * (4 + 0.145 * _max2118_write_regs.f_dac)); UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX Filter Bandwidth: %f MHz, m: %d, f_dac: %d\n" - ) % (_bandwidth/1e6) % int(_max2118_write_regs.m_divider) % int(_max2118_write_regs.f_dac) ; + "DBSRX Filter Bandwidth: %f MHz, m: %d, f_dac: %d\n") + % (_bandwidth / 1e6) + % int(_max2118_write_regs.m_divider) + % int(_max2118_write_regs.f_dac); this->send_reg(0x3, 0x4); - //convert lowpass back to complex bandpass bandwidth - return 2.0*_bandwidth; + // convert lowpass back to complex bandpass bandwidth + return 2.0 * _bandwidth; } diff --git a/host/lib/usrp/dboard/db_dbsrx2.cpp b/host/lib/usrp/dboard/db_dbsrx2.cpp index 2d800467c..19c058ada 100644 --- a/host/lib/usrp/dboard/db_dbsrx2.cpp +++ b/host/lib/usrp/dboard/db_dbsrx2.cpp @@ -33,22 +33,21 @@ using namespace boost::assign; **********************************************************************/ static const freq_range_t dbsrx2_freq_range(0.8e9, 2.3e9); -//Multiplied by 2.0 for conversion to complex bandpass from lowpass -static const freq_range_t dbsrx2_bandwidth_range(2.0*4.0e6, 2.0*40.0e6); +// Multiplied by 2.0 for conversion to complex bandpass from lowpass +static const freq_range_t dbsrx2_bandwidth_range(2.0 * 4.0e6, 2.0 * 40.0e6); static const int dbsrx2_ref_divider = 4; // Hitachi HMC426 divider (U7) static const std::vector<std::string> dbsrx2_antennas = list_of("J3"); -static const uhd::dict<std::string, gain_range_t> dbsrx2_gain_ranges = map_list_of - ("GC1", gain_range_t(0, 73, 0.05)) - ("BBG", gain_range_t(0, 15, 1)) -; +static const uhd::dict<std::string, gain_range_t> dbsrx2_gain_ranges = + map_list_of("GC1", gain_range_t(0, 73, 0.05))("BBG", gain_range_t(0, 15, 1)); /*********************************************************************** * The DBSRX2 dboard class **********************************************************************/ -class dbsrx2 : public rx_dboard_base{ +class dbsrx2 : public rx_dboard_base +{ public: dbsrx2(ctor_args_t args); virtual ~dbsrx2(void); @@ -59,74 +58,81 @@ private: uhd::dict<std::string, double> _gains; max2112_write_regs_t _max2112_write_regs; max2112_read_regs_t _max2112_read_regs; - uint8_t _max2112_addr(){ //0x60 or 0x61 depending on which side - return (this->get_iface()->get_special_props().mangle_i2c_addrs)? 0x60 : 0x61; + uint8_t _max2112_addr() + { // 0x60 or 0x61 depending on which side + return (this->get_iface()->get_special_props().mangle_i2c_addrs) ? 0x60 : 0x61; } double set_lo_freq(double target_freq); - double set_gain(double gain, const std::string &name); + double set_gain(double gain, const std::string& name); double set_bandwidth(double bandwidth); - void send_reg(uint8_t start_reg, uint8_t stop_reg){ + void send_reg(uint8_t start_reg, uint8_t stop_reg) + { start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0xB)); - stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0xB)); + stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0xB)); - for(uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(uint32_t) - 1){ - int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) - 1 ? sizeof(uint32_t) - 1 : stop_reg - start_addr + 1; + for (uint8_t start_addr = start_reg; start_addr <= stop_reg; + start_addr += sizeof(uint32_t) - 1) { + int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) - 1 + ? sizeof(uint32_t) - 1 + : stop_reg - start_addr + 1; - //create buffer for register data (+1 for start address) + // create buffer for register data (+1 for start address) byte_vector_t regs_vector(num_bytes + 1); - //first byte is the address of first register + // first byte is the address of first register regs_vector[0] = start_addr; - //get the register data - for(int i=0; i<num_bytes; i++){ - regs_vector[1+i] = _max2112_write_regs.get_reg(start_addr+i); - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX2: send reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d" - ) % int(start_addr+i) % int(regs_vector[1+i]) % int(start_addr) % num_bytes ; + // get the register data + for (int i = 0; i < num_bytes; i++) { + regs_vector[1 + i] = _max2112_write_regs.get_reg(start_addr + i); + UHD_LOGGER_TRACE("DBSRX") + << boost::format("DBSRX2: send reg 0x%02x, value 0x%04x, start_addr " + "= 0x%04x, num_bytes %d") + % int(start_addr + i) % int(regs_vector[1 + i]) + % int(start_addr) % num_bytes; } - //send the data - this->get_iface()->write_i2c( - _max2112_addr(), regs_vector - ); + // send the data + this->get_iface()->write_i2c(_max2112_addr(), regs_vector); } } - void read_reg(uint8_t start_reg, uint8_t stop_reg){ + void read_reg(uint8_t start_reg, uint8_t stop_reg) + { static const uint8_t status_addr = 0xC; - start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0xD)); - stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0xD)); + start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0xD)); + stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0xD)); - for(uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(uint32_t)){ - int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) ? sizeof(uint32_t) : stop_reg - start_addr + 1; + for (uint8_t start_addr = start_reg; start_addr <= stop_reg; + start_addr += sizeof(uint32_t)) { + int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) + ? sizeof(uint32_t) + : stop_reg - start_addr + 1; - //create address to start reading register data + // create address to start reading register data byte_vector_t address_vector(1); address_vector[0] = start_addr; - //send the address - this->get_iface()->write_i2c( - _max2112_addr(), address_vector - ); + // send the address + this->get_iface()->write_i2c(_max2112_addr(), address_vector); - //create buffer for register data + // create buffer for register data byte_vector_t regs_vector(num_bytes); - //read from i2c - regs_vector = this->get_iface()->read_i2c( - _max2112_addr(), num_bytes - ); + // read from i2c + regs_vector = this->get_iface()->read_i2c(_max2112_addr(), num_bytes); - for(uint8_t i=0; i < num_bytes; i++){ - if (i + start_addr >= status_addr){ + for (uint8_t i = 0; i < num_bytes; i++) { + if (i + start_addr >= status_addr) { _max2112_read_regs.set_reg(i + start_addr, regs_vector[i]); } - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX2: read reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d" - ) % int(start_addr+i) % int(regs_vector[i]) % int(start_addr) % num_bytes ; + UHD_LOGGER_TRACE("DBSRX") + << boost::format("DBSRX2: read reg 0x%02x, value 0x%04x, start_addr " + "= 0x%04x, num_bytes %d") + % int(start_addr + i) % int(regs_vector[i]) % int(start_addr) + % num_bytes; } } } @@ -135,15 +141,16 @@ private: * Get the lock detect status of the LO. * \return sensor for locked */ - sensor_value_t get_locked(void){ + sensor_value_t get_locked(void) + { read_reg(0xC, 0xD); - //mask and return lock detect - bool locked = (_max2112_read_regs.ld & _max2112_read_regs.vasa & _max2112_read_regs.vase) != 0; + // mask and return lock detect + bool locked = + (_max2112_read_regs.ld & _max2112_read_regs.vasa & _max2112_read_regs.vase) + != 0; - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX2 locked: %d" - ) % locked ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX2 locked: %d") % locked; return sensor_value_t("LO", locked, "locked", "unlocked"); } @@ -154,124 +161,135 @@ private: **********************************************************************/ // FIXME 0x67 is the default i2c address on USRP2 // need to handle which side for USRP1 with different address -static dboard_base::sptr make_dbsrx2(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_dbsrx2(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new dbsrx2(args)); } -UHD_STATIC_BLOCK(reg_dbsrx2_dboard){ - //register the factory function for the rx dbid +UHD_STATIC_BLOCK(reg_dbsrx2_dboard) +{ + // register the factory function for the rx dbid dboard_manager::register_dboard(0x0012, &make_dbsrx2, "DBSRX2"); } /*********************************************************************** * Structors **********************************************************************/ -dbsrx2::dbsrx2(ctor_args_t args) : rx_dboard_base(args){ - //send initial register settings +dbsrx2::dbsrx2(ctor_args_t args) : rx_dboard_base(args) +{ + // send initial register settings send_reg(0x0, 0xB); - //for (uint8_t addr=0; addr<=12; addr++) this->send_reg(addr, addr); + // for (uint8_t addr=0; addr<=12; addr++) this->send_reg(addr, addr); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - this->get_rx_subtree()->create<std::string>("name") - .set("DBSRX"); - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_rx_subtree()->create<std::string>("name").set("DBSRX"); + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&dbsrx2::get_locked, this)); - for(const std::string &name: dbsrx2_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") + for (const std::string& name : dbsrx2_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") .set_coercer(std::bind(&dbsrx2::set_gain, this, std::placeholders::_1, name)) .set(dbsrx2_gain_ranges[name].start()); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(dbsrx2_gain_ranges[name]); } - this->get_rx_subtree()->create<double>("freq/value") + this->get_rx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&dbsrx2::set_lo_freq, this, std::placeholders::_1)) .set(dbsrx2_freq_range.start()); - this->get_rx_subtree()->create<meta_range_t>("freq/range") - .set(dbsrx2_freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") + this->get_rx_subtree()->create<meta_range_t>("freq/range").set(dbsrx2_freq_range); + this->get_rx_subtree() + ->create<std::string>("antenna/value") .set(dbsrx2_antennas.at(0)); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(dbsrx2_antennas); - this->get_rx_subtree()->create<std::string>("connection") - .set("QI"); - this->get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); + this->get_rx_subtree()->create<std::string>("connection").set("QI"); + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); double codec_rate = this->get_iface()->get_codec_rate(dboard_iface::UNIT_RX); - this->get_rx_subtree()->create<double>("bandwidth/value") + this->get_rx_subtree() + ->create<double>("bandwidth/value") .set_coercer(std::bind(&dbsrx2::set_bandwidth, this, std::placeholders::_1)) - .set(2.0*(0.8*codec_rate/2.0)); //bandwidth in lowpass, convert to complex bandpass - //default to anti-alias at different codec_rate - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") + .set(2.0 + * (0.8 * codec_rate + / 2.0)); // bandwidth in lowpass, convert to complex bandpass + // default to anti-alias at different codec_rate + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(dbsrx2_bandwidth_range); - //enable only the clocks we need + // enable only the clocks we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); - //set the gpio directions and atr controls (identically) + // set the gpio directions and atr controls (identically) this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0); // All unused in atr this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x0); // All Inputs get_locked(); } -dbsrx2::~dbsrx2(void){ -} +dbsrx2::~dbsrx2(void) {} /*********************************************************************** * Tuning **********************************************************************/ -double dbsrx2::set_lo_freq(double target_freq){ - //target_freq = dbsrx2_freq_range.clip(target_freq); +double dbsrx2::set_lo_freq(double target_freq) +{ + // target_freq = dbsrx2_freq_range.clip(target_freq); - //variables used in the calculation below - int scaler = target_freq >= 1125e6 ? 2 : 4; + // variables used in the calculation below + int scaler = target_freq >= 1125e6 ? 2 : 4; double ref_freq = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); int R, intdiv, fracdiv, ext_div; double N; - //compute tuning variables + // compute tuning variables ext_div = dbsrx2_ref_divider; // 12MHz < ref_freq/ext_divider < 30MHz - R = 1; //Divide by 1 is the only tested value + R = 1; // Divide by 1 is the only tested value - N = (target_freq*R*ext_div)/(ref_freq); //actual spec range is (19, 251) - intdiv = int(std::floor(N)); // if (intdiv < 19 or intdiv > 251) continue; - fracdiv = boost::math::iround((N - intdiv)*double(1 << 20)); + N = (target_freq * R * ext_div) / (ref_freq); // actual spec range is (19, 251) + intdiv = int(std::floor(N)); // if (intdiv < 19 or intdiv > 251) continue; + fracdiv = boost::math::iround((N - intdiv) * double(1 << 20)); - //calculate the actual freq from the values above - N = double(intdiv) + double(fracdiv)/double(1 << 20); - _lo_freq = (N*ref_freq)/(R*ext_div); + // calculate the actual freq from the values above + N = double(intdiv) + double(fracdiv) / double(1 << 20); + _lo_freq = (N * ref_freq) / (R * ext_div); - //load new counters into registers + // load new counters into registers _max2112_write_regs.set_n_divider(intdiv); _max2112_write_regs.set_f_divider(fracdiv); _max2112_write_regs.r_divider = R; - _max2112_write_regs.d24 = scaler == 4 ? max2112_write_regs_t::D24_DIV4 : max2112_write_regs_t::D24_DIV2; + _max2112_write_regs.d24 = scaler == 4 ? max2112_write_regs_t::D24_DIV4 + : max2112_write_regs_t::D24_DIV2; - //debug output of calculated variables + // debug output of calculated variables UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX2 tune:\n") - << boost::format(" R=%d, N=%f, scaler=%d, ext_div=%d\n") % R % N % scaler % ext_div - << boost::format(" int=%d, frac=%d, d24=%d\n") % intdiv % fracdiv % int(_max2112_write_regs.d24) - << boost::format(" Ref Freq=%fMHz\n") % (ref_freq/1e6) - << boost::format(" Target Freq=%fMHz\n") % (target_freq/1e6) - << boost::format(" Actual Freq=%fMHz\n") % (_lo_freq/1e6) - ; - - //send the registers 0x0 through 0x7 - //writing register 0x4 (F divider LSB) starts the VCO auto seletion so it must be written last + << boost::format(" R=%d, N=%f, scaler=%d, ext_div=%d\n") % R % N % scaler + % ext_div + << boost::format(" int=%d, frac=%d, d24=%d\n") % intdiv % fracdiv + % int(_max2112_write_regs.d24) + << boost::format(" Ref Freq=%fMHz\n") % (ref_freq / 1e6) + << boost::format(" Target Freq=%fMHz\n") % (target_freq / 1e6) + << boost::format(" Actual Freq=%fMHz\n") % (_lo_freq / 1e6); + + // send the registers 0x0 through 0x7 + // writing register 0x4 (F divider LSB) starts the VCO auto seletion so it must be + // written last send_reg(0x5, 0x7); send_reg(0x0, 0x4); - //FIXME: probably unnecessary to call get_locked here - //get_locked(); + // FIXME: probably unnecessary to call get_locked here + // get_locked(); return _lo_freq; } @@ -285,15 +303,14 @@ double dbsrx2::set_lo_freq(double target_freq){ * \param gain the requested gain in dB * \return 4 bit the register value */ -static int gain_to_bbg_vga_reg(double &gain){ +static int gain_to_bbg_vga_reg(double& gain) +{ int reg = boost::math::iround(dbsrx2_gain_ranges["BBG"].clip(gain)); gain = double(reg); - UHD_LOGGER_TRACE("DBSRX") - << boost::format("DBSRX2 BBG Gain:\n") - << boost::format(" %f dB, bbg: %d") % gain % reg - ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX2 BBG Gain:\n") + << boost::format(" %f dB, bbg: %d") % gain % reg; return reg; } @@ -304,39 +321,41 @@ static int gain_to_bbg_vga_reg(double &gain){ * \param gain the requested gain in dB * \return dac voltage value */ -static double gain_to_gc1_rfvga_dac(double &gain){ - //clip the input +static double gain_to_gc1_rfvga_dac(double& gain) +{ + // clip the input gain = dbsrx2_gain_ranges["GC1"].clip(gain); - //voltage level constants + // voltage level constants static const double max_volts = 0.5, min_volts = 2.7; - static const double slope = (max_volts-min_volts)/dbsrx2_gain_ranges["GC1"].stop(); + static const double slope = + (max_volts - min_volts) / dbsrx2_gain_ranges["GC1"].stop(); - //calculate the voltage for the aux dac - double dac_volts = gain*slope + min_volts; + // calculate the voltage for the aux dac + double dac_volts = gain * slope + min_volts; - UHD_LOGGER_TRACE("DBSRX") - << boost::format("DBSRX2 GC1 Gain:\n") - << boost::format(" %f dB, dac_volts: %f V") % gain % dac_volts - ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX2 GC1 Gain:\n") + << boost::format(" %f dB, dac_volts: %f V") % gain + % dac_volts; - //the actual gain setting - gain = (dac_volts - min_volts)/slope; + // the actual gain setting + gain = (dac_volts - min_volts) / slope; return dac_volts; } -double dbsrx2::set_gain(double gain, const std::string &name){ +double dbsrx2::set_gain(double gain, const std::string& name) +{ assert_has(dbsrx2_gain_ranges.keys(), name, "dbsrx2 gain name"); - if (name == "BBG"){ + if (name == "BBG") { _max2112_write_regs.bbg = gain_to_bbg_vga_reg(gain); send_reg(0x9, 0x9); - } - else if(name == "GC1"){ - //write the new voltage to the aux dac - this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, gain_to_gc1_rfvga_dac(gain)); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else if (name == "GC1") { + // write the new voltage to the aux dac + this->get_iface()->write_aux_dac( + dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, gain_to_gc1_rfvga_dac(gain)); + } else + UHD_THROW_INVALID_CODE_PATH(); _gains[name] = gain; return gain; @@ -345,23 +364,23 @@ double dbsrx2::set_gain(double gain, const std::string &name){ /*********************************************************************** * Bandwidth Handling **********************************************************************/ -double dbsrx2::set_bandwidth(double bandwidth){ - //clip the input +double dbsrx2::set_bandwidth(double bandwidth) +{ + // clip the input bandwidth = dbsrx2_bandwidth_range.clip(bandwidth); - //convert complex bandpass to lowpass bandwidth - bandwidth = bandwidth/2.0; + // convert complex bandpass to lowpass bandwidth + bandwidth = bandwidth / 2.0; - _max2112_write_regs.lp = int((bandwidth/1e6 - 4)/0.29 + 12); - _bandwidth = double(4 + (_max2112_write_regs.lp - 12) * 0.29)*1e6; + _max2112_write_regs.lp = int((bandwidth / 1e6 - 4) / 0.29 + 12); + _bandwidth = double(4 + (_max2112_write_regs.lp - 12) * 0.29) * 1e6; - UHD_LOGGER_TRACE("DBSRX") - << boost::format("DBSRX2 Bandwidth:\n") - << boost::format(" %f MHz, lp: %f V") % (_bandwidth/1e6) % int(_max2112_write_regs.lp) - ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX2 Bandwidth:\n") + << boost::format(" %f MHz, lp: %f V") + % (_bandwidth / 1e6) % int(_max2112_write_regs.lp); this->send_reg(0x8, 0x8); - //convert lowpass back to complex bandpass bandwidth - return 2.0*_bandwidth; + // convert lowpass back to complex bandpass bandwidth + return 2.0 * _bandwidth; } diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 1bf4a7228..05f5c9a0e 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -6,21 +6,21 @@ // // IO Pin functions -#define POWER_IO (1 << 7) // Low enables power supply -#define ANTSW_IO (1 << 6) // On TX DB, 0 = TX, 1 = RX, on RX DB 0 = main ant, 1 = RX2 -#define MIXER_IO (1 << 5) // Enable appropriate mixer -#define LOCKDET_MASK (1 << 2) // Input pin +#define POWER_IO (1 << 7) // Low enables power supply +#define ANTSW_IO (1 << 6) // On TX DB, 0 = TX, 1 = RX, on RX DB 0 = main ant, 1 = RX2 +#define MIXER_IO (1 << 5) // Enable appropriate mixer +#define LOCKDET_MASK (1 << 2) // Input pin // Mixer constants -#define MIXER_ENB MIXER_IO -#define MIXER_DIS 0 +#define MIXER_ENB MIXER_IO +#define MIXER_DIS 0 // Antenna constants -#define ANT_TX 0 //the tx line is transmitting -#define ANT_RX ANTSW_IO //the tx line is receiving -#define ANT_TXRX 0 //the rx line is on txrx -#define ANT_RX2 ANTSW_IO //the rx line in on rx2 -#define ANT_XX 0 //dont care how the antenna is set +#define ANT_TX 0 // the tx line is transmitting +#define ANT_RX ANTSW_IO // the tx line is receiving +#define ANT_TXRX 0 // the rx line is on txrx +#define ANT_RX2 ANTSW_IO // the rx line in on rx2 +#define ANT_XX 0 // dont care how the antenna is set #include "adf4360_regs.hpp" #include <uhd/types/dict.hpp> @@ -49,37 +49,33 @@ static const std::vector<std::string> rfx_tx_antennas = list_of("TX/RX")("CAL"); static const std::vector<std::string> rfx_rx_antennas = list_of("TX/RX")("RX2")("CAL"); -static const uhd::dict<std::string, gain_range_t> rfx_rx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 70, 0.022)) -; +static const uhd::dict<std::string, gain_range_t> rfx_rx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 70, 0.022)); -static const uhd::dict<std::string, gain_range_t> rfx400_rx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 45, 0.022)) -; +static const uhd::dict<std::string, gain_range_t> rfx400_rx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 45, 0.022)); /*********************************************************************** * The RFX series of dboards **********************************************************************/ -class rfx_xcvr : public xcvr_dboard_base{ +class rfx_xcvr : public xcvr_dboard_base +{ public: rfx_xcvr( - ctor_args_t args, - const freq_range_t &freq_range, - bool rx_div2, bool tx_div2 - ); + ctor_args_t args, const freq_range_t& freq_range, bool rx_div2, bool tx_div2); virtual ~rfx_xcvr(void); private: const freq_range_t _freq_range; const uhd::dict<std::string, gain_range_t> _rx_gain_ranges; const uhd::dict<dboard_iface::unit_t, bool> _div2; - std::string _rx_ant; + std::string _rx_ant; uhd::dict<std::string, double> _rx_gains; uint16_t _power_up; - void set_rx_ant(const std::string &ant); - void set_tx_ant(const std::string &ant); - double set_rx_gain(double gain, const std::string &name); + void set_rx_ant(const std::string& ant); + void set_tx_ant(const std::string& ant); + double set_rx_gain(double gain, const std::string& name); /*! * Set the LO frequency for the particular dboard unit. @@ -94,7 +90,8 @@ private: * \param unit which unit rx or tx * \return sensor for locked */ - sensor_value_t get_locked(dboard_iface::unit_t unit){ + sensor_value_t get_locked(dboard_iface::unit_t unit) + { const bool locked = (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0; return sensor_value_t("LO", locked, "locked", "unlocked"); } @@ -108,33 +105,44 @@ private: /*********************************************************************** * Register the RFX dboards (min freq, max freq, rx div2, tx div2) **********************************************************************/ -static dboard_base::sptr make_rfx_flex400(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_rfx_flex400(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(400e6, 500e6), true, true)); } -static dboard_base::sptr make_rfx_flex900(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_rfx_flex900(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(750e6, 1050e6), true, true)); } -static dboard_base::sptr make_rfx_flex1800(dboard_base::ctor_args_t args){ - return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(1500e6, 2100e6), false, false)); +static dboard_base::sptr make_rfx_flex1800(dboard_base::ctor_args_t args) +{ + return dboard_base::sptr( + new rfx_xcvr(args, freq_range_t(1500e6, 2100e6), false, false)); } -static dboard_base::sptr make_rfx_flex1200(dboard_base::ctor_args_t args){ - return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(1150e6, 1450e6), true, true)); +static dboard_base::sptr make_rfx_flex1200(dboard_base::ctor_args_t args) +{ + return dboard_base::sptr( + new rfx_xcvr(args, freq_range_t(1150e6, 1450e6), true, true)); } -static dboard_base::sptr make_rfx_flex2200(dboard_base::ctor_args_t args){ - return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(2000e6, 2400e6), false, false)); +static dboard_base::sptr make_rfx_flex2200(dboard_base::ctor_args_t args) +{ + return dboard_base::sptr( + new rfx_xcvr(args, freq_range_t(2000e6, 2400e6), false, false)); } -static dboard_base::sptr make_rfx_flex2400(dboard_base::ctor_args_t args){ - return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(2300e6, 2900e6), false, false)); +static dboard_base::sptr make_rfx_flex2400(dboard_base::ctor_args_t args) +{ + return dboard_base::sptr( + new rfx_xcvr(args, freq_range_t(2300e6, 2900e6), false, false)); } -UHD_STATIC_BLOCK(reg_rfx_dboards){ - dboard_manager::register_dboard(0x0024, 0x0028, &make_rfx_flex400, "RFX400"); - dboard_manager::register_dboard(0x0025, 0x0029, &make_rfx_flex900, "RFX900"); +UHD_STATIC_BLOCK(reg_rfx_dboards) +{ + dboard_manager::register_dboard(0x0024, 0x0028, &make_rfx_flex400, "RFX400"); + dboard_manager::register_dboard(0x0025, 0x0029, &make_rfx_flex900, "RFX900"); dboard_manager::register_dboard(0x0034, 0x0035, &make_rfx_flex1800, "RFX1800"); dboard_manager::register_dboard(0x0026, 0x002a, &make_rfx_flex1200, "RFX1200"); dboard_manager::register_dboard(0x002c, 0x002d, &make_rfx_flex2200, "RFX2200"); @@ -145,217 +153,274 @@ UHD_STATIC_BLOCK(reg_rfx_dboards){ * Structors **********************************************************************/ rfx_xcvr::rfx_xcvr( - ctor_args_t args, - const freq_range_t &freq_range, - bool rx_div2, bool tx_div2 -): - xcvr_dboard_base(args), - _freq_range(freq_range), - _rx_gain_ranges((get_rx_id() == 0x0024)? - rfx400_rx_gain_ranges : rfx_rx_gain_ranges - ), - _div2(map_list_of - (dboard_iface::UNIT_RX, rx_div2) - (dboard_iface::UNIT_TX, tx_div2) - ), - _power_up((get_rx_id() == 0x0024 && get_tx_id() == 0x0028) ? POWER_IO : 0) + ctor_args_t args, const freq_range_t& freq_range, bool rx_div2, bool tx_div2) + : xcvr_dboard_base(args) + , _freq_range(freq_range) + , _rx_gain_ranges( + (get_rx_id() == 0x0024) ? rfx400_rx_gain_ranges : rfx_rx_gain_ranges) + , _div2(map_list_of(dboard_iface::UNIT_RX, rx_div2)(dboard_iface::UNIT_TX, tx_div2)) + , _power_up((get_rx_id() == 0x0024 && get_tx_id() == 0x0028) ? POWER_IO : 0) { //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// - if(get_rx_id() == 0x0024) this->get_rx_subtree()->create<std::string>("name").set("RFX400 RX"); - else if(get_rx_id() == 0x0025) this->get_rx_subtree()->create<std::string>("name").set("RFX900 RX"); - else if(get_rx_id() == 0x0034) this->get_rx_subtree()->create<std::string>("name").set("RFX1800 RX"); - else if(get_rx_id() == 0x0026) this->get_rx_subtree()->create<std::string>("name").set("RFX1200 RX"); - else if(get_rx_id() == 0x002c) this->get_rx_subtree()->create<std::string>("name").set("RFX2200 RX"); - else if(get_rx_id() == 0x0027) this->get_rx_subtree()->create<std::string>("name").set("RFX2400 RX"); - else this->get_rx_subtree()->create<std::string>("name").set("RFX RX"); - - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + if (get_rx_id() == 0x0024) + this->get_rx_subtree()->create<std::string>("name").set("RFX400 RX"); + else if (get_rx_id() == 0x0025) + this->get_rx_subtree()->create<std::string>("name").set("RFX900 RX"); + else if (get_rx_id() == 0x0034) + this->get_rx_subtree()->create<std::string>("name").set("RFX1800 RX"); + else if (get_rx_id() == 0x0026) + this->get_rx_subtree()->create<std::string>("name").set("RFX1200 RX"); + else if (get_rx_id() == 0x002c) + this->get_rx_subtree()->create<std::string>("name").set("RFX2200 RX"); + else if (get_rx_id() == 0x0027) + this->get_rx_subtree()->create<std::string>("name").set("RFX2400 RX"); + else + this->get_rx_subtree()->create<std::string>("name").set("RFX RX"); + + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&rfx_xcvr::get_locked, this, dboard_iface::UNIT_RX)); - for(const std::string &name: _rx_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&rfx_xcvr::set_rx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : _rx_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer( + std::bind(&rfx_xcvr::set_rx_gain, this, std::placeholders::_1, name)) .set(_rx_gain_ranges[name].start()); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(_rx_gain_ranges[name]); } - this->get_rx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) - .set((_freq_range.start() + _freq_range.stop())/2.0); + this->get_rx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind( + &rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) + .set((_freq_range.start() + _freq_range.stop()) / 2.0); this->get_rx_subtree()->create<meta_range_t>("freq/range").set(_freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&rfx_xcvr::set_rx_ant, this, std::placeholders::_1)) + this->get_rx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&rfx_xcvr::set_rx_ant, this, std::placeholders::_1)) .set("RX2"); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(rfx_rx_antennas); this->get_rx_subtree()->create<std::string>("connection").set("QI"); - this->get_rx_subtree()->create<bool>("enabled").set(true); //always enabled + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); - this->get_rx_subtree()->create<double>("bandwidth/value").set(2*20.0e6); //20MHz low-pass, we want complex double-sided - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(2*20.0e6, 2*20.0e6)); + this->get_rx_subtree() + ->create<double>("bandwidth/value") + .set(2 * 20.0e6); // 20MHz low-pass, we want complex double-sided + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(2 * 20.0e6, 2 * 20.0e6)); //////////////////////////////////////////////////////////////////// // Register TX properties //////////////////////////////////////////////////////////////////// - if(get_tx_id() == 0x0028) this->get_tx_subtree()->create<std::string>("name").set("RFX400 TX"); - else if(get_tx_id() == 0x0029) this->get_tx_subtree()->create<std::string>("name").set("RFX900 TX"); - else if(get_tx_id() == 0x0035) this->get_tx_subtree()->create<std::string>("name").set("RFX1800 TX"); - else if(get_tx_id() == 0x002a) this->get_tx_subtree()->create<std::string>("name").set("RFX1200 TX"); - else if(get_tx_id() == 0x002d) this->get_tx_subtree()->create<std::string>("name").set("RFX2200 TX"); - else if(get_tx_id() == 0x002b) this->get_tx_subtree()->create<std::string>("name").set("RFX2400 TX"); - else this->get_tx_subtree()->create<std::string>("name").set("RFX TX"); - - this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked") + if (get_tx_id() == 0x0028) + this->get_tx_subtree()->create<std::string>("name").set("RFX400 TX"); + else if (get_tx_id() == 0x0029) + this->get_tx_subtree()->create<std::string>("name").set("RFX900 TX"); + else if (get_tx_id() == 0x0035) + this->get_tx_subtree()->create<std::string>("name").set("RFX1800 TX"); + else if (get_tx_id() == 0x002a) + this->get_tx_subtree()->create<std::string>("name").set("RFX1200 TX"); + else if (get_tx_id() == 0x002d) + this->get_tx_subtree()->create<std::string>("name").set("RFX2200 TX"); + else if (get_tx_id() == 0x002b) + this->get_tx_subtree()->create<std::string>("name").set("RFX2400 TX"); + else + this->get_tx_subtree()->create<std::string>("name").set("RFX TX"); + + this->get_tx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&rfx_xcvr::get_locked, this, dboard_iface::UNIT_TX)); - this->get_tx_subtree()->create<int>("gains"); //phony property so this dir exists - this->get_tx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) - .set((_freq_range.start() + _freq_range.stop())/2.0); + this->get_tx_subtree()->create<int>("gains"); // phony property so this dir exists + this->get_tx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind( + &rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) + .set((_freq_range.start() + _freq_range.stop()) / 2.0); this->get_tx_subtree()->create<meta_range_t>("freq/range").set(_freq_range); - this->get_tx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&rfx_xcvr::set_tx_ant, this, std::placeholders::_1)).set(rfx_tx_antennas.at(0)); - this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_tx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&rfx_xcvr::set_tx_ant, this, std::placeholders::_1)) + .set(rfx_tx_antennas.at(0)); + this->get_tx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(rfx_tx_antennas); this->get_tx_subtree()->create<std::string>("connection").set("IQ"); - this->get_tx_subtree()->create<bool>("enabled").set(true); //always enabled + this->get_tx_subtree()->create<bool>("enabled").set(true); // always enabled this->get_tx_subtree()->create<bool>("use_lo_offset").set(true); - this->get_tx_subtree()->create<double>("bandwidth/value").set(2*20.0e6); //20MHz low-pass, we want complex double-sided - this->get_tx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(2*20.0e6, 2*20.0e6)); - - //enable the clocks that we need + this->get_tx_subtree() + ->create<double>("bandwidth/value") + .set(2 * 20.0e6); // 20MHz low-pass, we want complex double-sided + this->get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(2 * 20.0e6, 2 * 20.0e6)); + + // enable the clocks that we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); - //set the gpio directions and atr controls (identically) + // set the gpio directions and atr controls (identically) uint16_t output_enables = POWER_IO | ANTSW_IO | MIXER_IO; this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, output_enables); this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, output_enables); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, output_enables); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, output_enables); - //setup the tx atr (this does not change with antenna) - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, _power_up | ANT_RX | MIXER_DIS); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_TX | MIXER_ENB); - - //setup the rx atr (this does not change with antenna) - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX2| MIXER_ENB); + // setup the tx atr (this does not change with antenna) + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, _power_up | ANT_RX | MIXER_DIS); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _power_up | ANT_TX | MIXER_ENB); + + // setup the rx atr (this does not change with antenna) + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _power_up | ANT_RX2 | MIXER_ENB); } -rfx_xcvr::~rfx_xcvr(void){ +rfx_xcvr::~rfx_xcvr(void) +{ /* NOP */ } /*********************************************************************** * Antenna Handling **********************************************************************/ -void rfx_xcvr::set_rx_ant(const std::string &ant){ - //validate input +void rfx_xcvr::set_rx_ant(const std::string& ant) +{ + // validate input assert_has(rfx_rx_antennas, ant, "rfx rx antenna name"); - //set the rx atr regs that change with antenna setting + // set the rx atr regs that change with antenna setting if (ant == "CAL") { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TXRX | MIXER_ENB); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_TXRX | MIXER_ENB); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _power_up | MIXER_ENB | ANT_TXRX ); - } - else { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX2| MIXER_ENB); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _power_up | MIXER_ENB | - ((ant == "TX/RX")? ANT_TXRX : ANT_RX2)); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_TX_ONLY, + _power_up | ANT_TXRX | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _power_up | ANT_TXRX | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + _power_up | MIXER_ENB | ANT_TXRX); + } else { + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_TX_ONLY, + _power_up | ANT_XX | MIXER_DIS); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _power_up | ANT_RX2 | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + _power_up | MIXER_ENB | ((ant == "TX/RX") ? ANT_TXRX : ANT_RX2)); } - //shadow the setting + // shadow the setting _rx_ant = ant; } -void rfx_xcvr::set_tx_ant(const std::string &ant){ +void rfx_xcvr::set_tx_ant(const std::string& ant) +{ assert_has(rfx_tx_antennas, ant, "rfx tx antenna name"); - //set the tx atr regs that change with antenna setting + // set the tx atr regs that change with antenna setting if (ant == "CAL") { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_RX | MIXER_ENB); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX | MIXER_ENB); - } - else { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_TX | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + _power_up | ANT_RX | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _power_up | ANT_RX | MIXER_ENB); + } else { + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + _power_up | ANT_TX | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _power_up | ANT_TX | MIXER_ENB); } } /*********************************************************************** * Gain Handling **********************************************************************/ -static double rx_pga0_gain_to_dac_volts(double &gain, double range){ - //voltage level constants (negative slope) +static double rx_pga0_gain_to_dac_volts(double& gain, double range) +{ + // voltage level constants (negative slope) static const double max_volts = .2, min_volts = 1.2; - static const double slope = (max_volts-min_volts)/(range); + static const double slope = (max_volts - min_volts) / (range); - //calculate the voltage for the aux dac - double dac_volts = uhd::clip<double>(gain*slope + min_volts, max_volts, min_volts); + // calculate the voltage for the aux dac + double dac_volts = uhd::clip<double>(gain * slope + min_volts, max_volts, min_volts); - //the actual gain setting - gain = (dac_volts - min_volts)/slope; + // the actual gain setting + gain = (dac_volts - min_volts) / slope; return dac_volts; } -double rfx_xcvr::set_rx_gain(double gain, const std::string &name){ +double rfx_xcvr::set_rx_gain(double gain, const std::string& name) +{ assert_has(_rx_gain_ranges.keys(), name, "rfx rx gain name"); - if(name == "PGA0"){ - double dac_volts = rx_pga0_gain_to_dac_volts(gain, - (_rx_gain_ranges["PGA0"].stop() - _rx_gain_ranges["PGA0"].start())); + if (name == "PGA0") { + double dac_volts = rx_pga0_gain_to_dac_volts( + gain, (_rx_gain_ranges["PGA0"].stop() - _rx_gain_ranges["PGA0"].start())); - //write the new voltage to the aux dac - this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, dac_volts); + // write the new voltage to the aux dac + this->get_iface()->write_aux_dac( + dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, dac_volts); return gain; - } - else UHD_THROW_INVALID_CODE_PATH(); + } else + UHD_THROW_INVALID_CODE_PATH(); } /*********************************************************************** * Tuning **********************************************************************/ -double rfx_xcvr::set_lo_freq( - dboard_iface::unit_t unit, - double target_freq -){ - UHD_LOGGER_TRACE("RFX") << boost::format( - "RFX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; +double rfx_xcvr::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + UHD_LOGGER_TRACE("RFX") << boost::format("RFX tune: target frequency %f MHz") + % (target_freq / 1e6); - //clip the input + // clip the input target_freq = _freq_range.clip(target_freq); - if (_div2[unit]) target_freq *= 2; + if (_div2[unit]) + target_freq *= 2; - //rfx400 rx is a special case with div2 in mixer, so adf4360 must output fundamental + // rfx400 rx is a special case with div2 in mixer, so adf4360 must output fundamental bool is_rx_rfx400 = ((get_rx_id() == 0x0024) && unit != dboard_iface::UNIT_TX); - //map prescalers to the register enums - static const uhd::dict<int, adf4360_regs_t::prescaler_value_t> prescaler_to_enum = map_list_of - (8, adf4360_regs_t::PRESCALER_VALUE_8_9) - (16, adf4360_regs_t::PRESCALER_VALUE_16_17) - (32, adf4360_regs_t::PRESCALER_VALUE_32_33) - ; + // map prescalers to the register enums + static const uhd::dict<int, adf4360_regs_t::prescaler_value_t> prescaler_to_enum = + map_list_of(8, adf4360_regs_t::PRESCALER_VALUE_8_9)( + 16, adf4360_regs_t::PRESCALER_VALUE_16_17)( + 32, adf4360_regs_t::PRESCALER_VALUE_32_33); - //map band select clock dividers to enums - static const uhd::dict<int, adf4360_regs_t::band_select_clock_div_t> bandsel_to_enum = map_list_of - (1, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_1) - (2, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_2) - (4, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_4) - (8, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_8) - ; + // map band select clock dividers to enums + static const uhd::dict<int, adf4360_regs_t::band_select_clock_div_t> bandsel_to_enum = + map_list_of(1, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_1)( + 2, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_2)( + 4, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_4)( + 8, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_8); - double actual_freq=0, ref_freq = this->get_iface()->get_clock_rate(unit); - int R=0, BS=0, P=0, B=0, A=0; + double actual_freq = 0, ref_freq = this->get_iface()->get_clock_rate(unit); + int R = 0, BS = 0, P = 0, B = 0, A = 0; /* * The goal here to to loop through possible R dividers, @@ -393,10 +458,11 @@ double rfx_xcvr::set_lo_freq( done_loop: UHD_LOGGER_TRACE("RFX") << boost::format( - "RFX tune: R=%d, BS=%d, P=%d, B=%d, A=%d, DIV2=%d" - ) % R % BS % P % B % A % int(_div2[unit] && (!is_rx_rfx400)) ; + "RFX tune: R=%d, BS=%d, P=%d, B=%d, A=%d, DIV2=%d") + % R % BS % P % B % A + % int(_div2[unit] && (!is_rx_rfx400)); - //load the register values + // load the register values adf4360_regs_t regs; regs.core_power_level = adf4360_regs_t::CORE_POWER_LEVEL_10MA; regs.counter_operation = adf4360_regs_t::COUNTER_OPERATION_NORMAL; @@ -413,33 +479,31 @@ done_loop: regs.a_counter = A; regs.b_counter = B; regs.cp_gain_1 = adf4360_regs_t::CP_GAIN_1_SET1; - regs.divide_by_2_output = (_div2[unit] && (!is_rx_rfx400)) ? // Special case RFX400 RX Mixer divides by two - adf4360_regs_t::DIVIDE_BY_2_OUTPUT_DIV2 : - adf4360_regs_t::DIVIDE_BY_2_OUTPUT_FUND ; - regs.divide_by_2_prescaler = adf4360_regs_t::DIVIDE_BY_2_PRESCALER_FUND; - regs.r_counter = R; - regs.ablpw = adf4360_regs_t::ABLPW_3_0NS; - regs.lock_detect_precision = adf4360_regs_t::LOCK_DETECT_PRECISION_5CYCLES; - regs.test_mode_bit = 0; - regs.band_select_clock_div = bandsel_to_enum[BS]; - - //write the registers - std::vector<adf4360_regs_t::addr_t> addrs = list_of //correct power-up sequence to write registers (R, C, N) - (adf4360_regs_t::ADDR_RCOUNTER) - (adf4360_regs_t::ADDR_CONTROL) - (adf4360_regs_t::ADDR_NCOUNTER) - ; - for(adf4360_regs_t::addr_t addr: addrs){ + regs.divide_by_2_output = (_div2[unit] && (!is_rx_rfx400)) + ? // Special case RFX400 RX Mixer divides by two + adf4360_regs_t::DIVIDE_BY_2_OUTPUT_DIV2 + : adf4360_regs_t::DIVIDE_BY_2_OUTPUT_FUND; + regs.divide_by_2_prescaler = adf4360_regs_t::DIVIDE_BY_2_PRESCALER_FUND; + regs.r_counter = R; + regs.ablpw = adf4360_regs_t::ABLPW_3_0NS; + regs.lock_detect_precision = adf4360_regs_t::LOCK_DETECT_PRECISION_5CYCLES; + regs.test_mode_bit = 0; + regs.band_select_clock_div = bandsel_to_enum[BS]; + + // write the registers + std::vector<adf4360_regs_t::addr_t> addrs = + list_of // correct power-up sequence to write registers (R, C, N) + (adf4360_regs_t::ADDR_RCOUNTER)(adf4360_regs_t::ADDR_CONTROL)( + adf4360_regs_t::ADDR_NCOUNTER); + for (adf4360_regs_t::addr_t addr : addrs) { this->get_iface()->write_spi( - unit, spi_config_t::EDGE_RISE, - regs.get_reg(addr), 24 - ); + unit, spi_config_t::EDGE_RISE, regs.get_reg(addr), 24); } - //return the actual frequency - if (_div2[unit]) actual_freq /= 2; - UHD_LOGGER_TRACE("RFX") << boost::format( - "RFX tune: actual frequency %f MHz" - ) % (actual_freq/1e6) ; + // return the actual frequency + if (_div2[unit]) + actual_freq /= 2; + UHD_LOGGER_TRACE("RFX") << boost::format("RFX tune: actual frequency %f MHz") + % (actual_freq / 1e6); return actual_freq; } diff --git a/host/lib/usrp/dboard/db_sbx_common.cpp b/host/lib/usrp/dboard/db_sbx_common.cpp index dc49a97aa..f79b70f53 100644 --- a/host/lib/usrp/dboard/db_sbx_common.cpp +++ b/host/lib/usrp/dboard/db_sbx_common.cpp @@ -16,11 +16,13 @@ using namespace boost::assign; /*********************************************************************** * Register the SBX dboard (min freq, max freq, rx div2, tx div2) **********************************************************************/ -static dboard_base::sptr make_sbx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_sbx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new sbx_xcvr(args)); } -UHD_STATIC_BLOCK(reg_sbx_dboards){ +UHD_STATIC_BLOCK(reg_sbx_dboards) +{ dboard_manager::register_dboard(0x0054, 0x0055, &make_sbx, "SBX"); dboard_manager::register_dboard(0x0065, 0x0064, &make_sbx, "SBX v4"); dboard_manager::register_dboard(0x0067, 0x0066, &make_sbx, "CBX"); @@ -33,71 +35,75 @@ UHD_STATIC_BLOCK(reg_sbx_dboards){ /*********************************************************************** * Gain Handling **********************************************************************/ -static int rx_pga0_gain_to_iobits(double &gain){ - //clip the input +static int rx_pga0_gain_to_iobits(double& gain) +{ + // clip the input gain = sbx_rx_gain_ranges["PGA0"].clip(gain); - //convert to attenuation and update iobits for atr + // convert to attenuation and update iobits for atr double attn = sbx_rx_gain_ranges["PGA0"].stop() - gain; - //calculate the RX attenuation - int attn_code = int(floor(attn*2)); - int iobits = ((~attn_code) << RX_ATTN_SHIFT) & RX_ATTN_MASK; + // calculate the RX attenuation + int attn_code = int(floor(attn * 2)); + int iobits = ((~attn_code) << RX_ATTN_SHIFT) & RX_ATTN_MASK; - UHD_LOGGER_TRACE("SBX") << boost::format( - "SBX RX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x" - ) % attn % attn_code % (iobits & RX_ATTN_MASK) % RX_ATTN_MASK ; + UHD_LOGGER_TRACE("SBX") + << boost::format("SBX RX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x") + % attn % attn_code % (iobits & RX_ATTN_MASK) % RX_ATTN_MASK; - //the actual gain setting - gain = sbx_rx_gain_ranges["PGA0"].stop() - double(attn_code)/2; + // the actual gain setting + gain = sbx_rx_gain_ranges["PGA0"].stop() - double(attn_code) / 2; return iobits; } -static int tx_pga0_gain_to_iobits(double &gain){ - //clip the input +static int tx_pga0_gain_to_iobits(double& gain) +{ + // clip the input gain = sbx_tx_gain_ranges["PGA0"].clip(gain); - //convert to attenuation and update iobits for atr + // convert to attenuation and update iobits for atr double attn = sbx_tx_gain_ranges["PGA0"].stop() - gain; - //calculate the TX attenuation - int attn_code = int(floor(attn*2)); - int iobits = ((~attn_code) << TX_ATTN_SHIFT) & TX_ATTN_MASK; + // calculate the TX attenuation + int attn_code = int(floor(attn * 2)); + int iobits = ((~attn_code) << TX_ATTN_SHIFT) & TX_ATTN_MASK; - UHD_LOGGER_TRACE("SBX") << boost::format( - "SBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x" - ) % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK ; + UHD_LOGGER_TRACE("SBX") + << boost::format("SBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x") + % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK; - //the actual gain setting - gain = sbx_tx_gain_ranges["PGA0"].stop() - double(attn_code)/2; + // the actual gain setting + gain = sbx_tx_gain_ranges["PGA0"].stop() - double(attn_code) / 2; return iobits; } -double sbx_xcvr::set_tx_gain(double gain, const std::string &name){ +double sbx_xcvr::set_tx_gain(double gain, const std::string& name) +{ assert_has(sbx_tx_gain_ranges.keys(), name, "sbx tx gain name"); - if(name == "PGA0"){ + if (name == "PGA0") { tx_pga0_gain_to_iobits(gain); _tx_gains[name] = gain; - //write the new gain to atr regs + // write the new gain to atr regs update_atr(); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else + UHD_THROW_INVALID_CODE_PATH(); return _tx_gains[name]; } -double sbx_xcvr::set_rx_gain(double gain, const std::string &name){ +double sbx_xcvr::set_rx_gain(double gain, const std::string& name) +{ assert_has(sbx_rx_gain_ranges.keys(), name, "sbx rx gain name"); - if(name == "PGA0"){ + if (name == "PGA0") { rx_pga0_gain_to_iobits(gain); _rx_gains[name] = gain; - //write the new gain to atr regs + // write the new gain to atr regs update_atr(); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else + UHD_THROW_INVALID_CODE_PATH(); return _rx_gains[name]; } @@ -105,26 +111,27 @@ double sbx_xcvr::set_rx_gain(double gain, const std::string &name){ /*********************************************************************** * Structors **********************************************************************/ -sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){ - switch(get_rx_id().to_uint16()) { +sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args) +{ + switch (get_rx_id().to_uint16()) { case 0x0054: - db_actual = sbx_versionx_sptr(new sbx_version3(this)); - freq_range = sbx_freq_range; + db_actual = sbx_versionx_sptr(new sbx_version3(this)); + freq_range = sbx_freq_range; enable_rx_lo_filter = sbx_enable_rx_lo_filter; enable_tx_lo_filter = sbx_enable_tx_lo_filter; break; case 0x0065: case 0x0069: case 0x0083: - db_actual = sbx_versionx_sptr(new sbx_version4(this)); - freq_range = sbx_freq_range; + db_actual = sbx_versionx_sptr(new sbx_version4(this)); + freq_range = sbx_freq_range; enable_rx_lo_filter = sbx_enable_rx_lo_filter; enable_tx_lo_filter = sbx_enable_tx_lo_filter; break; case 0x0067: case 0x0085: - db_actual = sbx_versionx_sptr(new cbx(this)); - freq_range = cbx_freq_range; + db_actual = sbx_versionx_sptr(new cbx(this)); + freq_range = cbx_freq_range; enable_rx_lo_filter = cbx_enable_rx_lo_filter; enable_tx_lo_filter = cbx_enable_tx_lo_filter; break; @@ -139,40 +146,56 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){ this->get_rx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); uint16_t rx_id = get_rx_id().to_uint16(); - if(rx_id == 0x0054) this->get_rx_subtree()->create<std::string>("name").set("SBXv3 RX"); - else if(rx_id == 0x0065) this->get_rx_subtree()->create<std::string>("name").set("SBXv4 RX"); - else if(rx_id == 0x0067) this->get_rx_subtree()->create<std::string>("name").set("CBX RX"); - else if(rx_id == 0x0083) this->get_rx_subtree()->create<std::string>("name").set("SBX-120 RX"); - else if(rx_id == 0x0085) this->get_rx_subtree()->create<std::string>("name").set("CBX-120 RX"); - else this->get_rx_subtree()->create<std::string>("name").set("SBX/CBX RX"); - - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + if (rx_id == 0x0054) + this->get_rx_subtree()->create<std::string>("name").set("SBXv3 RX"); + else if (rx_id == 0x0065) + this->get_rx_subtree()->create<std::string>("name").set("SBXv4 RX"); + else if (rx_id == 0x0067) + this->get_rx_subtree()->create<std::string>("name").set("CBX RX"); + else if (rx_id == 0x0083) + this->get_rx_subtree()->create<std::string>("name").set("SBX-120 RX"); + else if (rx_id == 0x0085) + this->get_rx_subtree()->create<std::string>("name").set("CBX-120 RX"); + else + this->get_rx_subtree()->create<std::string>("name").set("SBX/CBX RX"); + + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_RX)); - for(const std::string &name: sbx_rx_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&sbx_xcvr::set_rx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : sbx_rx_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer( + std::bind(&sbx_xcvr::set_rx_gain, this, std::placeholders::_1, name)) .set(sbx_rx_gain_ranges[name].start()); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(sbx_rx_gain_ranges[name]); } - this->get_rx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) - .set((freq_range.start() + freq_range.stop())/2.0); + this->get_rx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind( + &sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) + .set((freq_range.start() + freq_range.stop()) / 2.0); this->get_rx_subtree()->create<meta_range_t>("freq/range").set(freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&sbx_xcvr::set_rx_ant, this, std::placeholders::_1)) + this->get_rx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&sbx_xcvr::set_rx_ant, this, std::placeholders::_1)) .set("RX2"); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(sbx_rx_antennas); this->get_rx_subtree()->create<std::string>("connection").set("IQ"); - this->get_rx_subtree()->create<bool>("enabled").set(true); //always enabled + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); - //Value of bw low-pass dependent on board, we want complex double-sided + // Value of bw low-pass dependent on board, we want complex double-sided double rx_bw = ((rx_id != 0x0083) && (rx_id != 0x0085)) ? 20.0e6 : 60.0e6; - this->get_rx_subtree()->create<double>("bandwidth/value").set(2*rx_bw); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(2*rx_bw, 2*rx_bw)); + this->get_rx_subtree()->create<double>("bandwidth/value").set(2 * rx_bw); + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(2 * rx_bw, 2 * rx_bw)); //////////////////////////////////////////////////////////////////// // Register TX properties @@ -180,156 +203,180 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){ this->get_tx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); uint16_t tx_id = get_tx_id().to_uint16(); - if(tx_id == 0x0055) this->get_tx_subtree()->create<std::string>("name").set("SBXv3 TX"); - else if(tx_id == 0x0064) this->get_tx_subtree()->create<std::string>("name").set("SBXv4 TX"); - else if(tx_id == 0x0066) this->get_tx_subtree()->create<std::string>("name").set("CBX TX"); - else if(tx_id == 0x0082) this->get_tx_subtree()->create<std::string>("name").set("SBX-120 TX"); - else if(tx_id == 0x0084) this->get_tx_subtree()->create<std::string>("name").set("CBX-120 TX"); - else this->get_tx_subtree()->create<std::string>("name").set("SBX/CBX TX"); - - this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked") + if (tx_id == 0x0055) + this->get_tx_subtree()->create<std::string>("name").set("SBXv3 TX"); + else if (tx_id == 0x0064) + this->get_tx_subtree()->create<std::string>("name").set("SBXv4 TX"); + else if (tx_id == 0x0066) + this->get_tx_subtree()->create<std::string>("name").set("CBX TX"); + else if (tx_id == 0x0082) + this->get_tx_subtree()->create<std::string>("name").set("SBX-120 TX"); + else if (tx_id == 0x0084) + this->get_tx_subtree()->create<std::string>("name").set("CBX-120 TX"); + else + this->get_tx_subtree()->create<std::string>("name").set("SBX/CBX TX"); + + this->get_tx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_TX)); - for(const std::string &name: sbx_tx_gain_ranges.keys()){ - this->get_tx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&sbx_xcvr::set_tx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : sbx_tx_gain_ranges.keys()) { + this->get_tx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer( + std::bind(&sbx_xcvr::set_tx_gain, this, std::placeholders::_1, name)) .set(sbx_tx_gain_ranges[name].start()); - this->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_tx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(sbx_tx_gain_ranges[name]); } - this->get_tx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) - .set((freq_range.start() + freq_range.stop())/2.0); + this->get_tx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind( + &sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) + .set((freq_range.start() + freq_range.stop()) / 2.0); this->get_tx_subtree()->create<meta_range_t>("freq/range").set(freq_range); - this->get_tx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&sbx_xcvr::set_tx_ant, this, std::placeholders::_1)) + this->get_tx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&sbx_xcvr::set_tx_ant, this, std::placeholders::_1)) .set(sbx_tx_antennas.at(0)); - this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_tx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(sbx_tx_antennas); this->get_tx_subtree()->create<std::string>("connection").set("QI"); - this->get_tx_subtree()->create<bool>("enabled").set(true); //always enabled + this->get_tx_subtree()->create<bool>("enabled").set(true); // always enabled this->get_tx_subtree()->create<bool>("use_lo_offset").set(false); - //Value of bw low-pass dependent on board, we want complex double-sided + // Value of bw low-pass dependent on board, we want complex double-sided double tx_bw = ((tx_id != 0x0082) && (tx_id != 0x0084)) ? 20.0e6 : 60.0e6; - this->get_tx_subtree()->create<double>("bandwidth/value").set(2*tx_bw); - this->get_tx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(2*tx_bw, 2*tx_bw)); + this->get_tx_subtree()->create<double>("bandwidth/value").set(2 * tx_bw); + this->get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(2 * tx_bw, 2 * tx_bw)); - //enable the clocks that we need + // enable the clocks that we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); - //set the gpio directions and atr controls (identically) - this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO)); - this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO)); - this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO)); - this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO)); + // set the gpio directions and atr controls (identically) + this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, (TXIO_MASK | TX_LED_IO)); + this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, (RXIO_MASK | RX_LED_IO)); + this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK | TX_LED_IO)); + this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK | RX_LED_IO)); - //Initialize ATR registers after direction and pin ctrl configuration + // Initialize ATR registers after direction and pin ctrl configuration update_atr(); - UHD_LOGGER_TRACE("SBX") << boost::format( - "SBX GPIO Direction: RX: 0x%08x, TX: 0x%08x" - ) % RXIO_MASK % TXIO_MASK ; + UHD_LOGGER_TRACE("SBX") << boost::format("SBX GPIO Direction: RX: 0x%08x, TX: 0x%08x") + % RXIO_MASK % TXIO_MASK; } -sbx_xcvr::~sbx_xcvr(void){ +sbx_xcvr::~sbx_xcvr(void) +{ /* NOP */ } /*********************************************************************** * Antenna Handling **********************************************************************/ -void sbx_xcvr::update_atr(void){ - //calculate atr pins +void sbx_xcvr::update_atr(void) +{ + // calculate atr pins int rx_pga0_iobits = rx_pga0_gain_to_iobits(_rx_gains["PGA0"]); int tx_pga0_iobits = tx_pga0_gain_to_iobits(_tx_gains["PGA0"]); - int rx_lo_lpf_en = (_rx_lo_freq == enable_rx_lo_filter.clip(_rx_lo_freq)) ? LO_LPF_EN : 0; - int tx_lo_lpf_en = (_tx_lo_freq == enable_tx_lo_filter.clip(_tx_lo_freq)) ? LO_LPF_EN : 0; - int rx_ld_led = _rx_lo_lock_cache ? 0 : RX_LED_LD; - int tx_ld_led = _tx_lo_lock_cache ? 0 : TX_LED_LD; + int rx_lo_lpf_en = (_rx_lo_freq == enable_rx_lo_filter.clip(_rx_lo_freq)) ? LO_LPF_EN + : 0; + int tx_lo_lpf_en = (_tx_lo_freq == enable_tx_lo_filter.clip(_tx_lo_freq)) ? LO_LPF_EN + : 0; + int rx_ld_led = _rx_lo_lock_cache ? 0 : RX_LED_LD; + int tx_ld_led = _tx_lo_lock_cache ? 0 : TX_LED_LD; int rx_ant_led = _rx_ant == "TX/RX" ? RX_LED_RX1RX2 : 0; int tx_ant_led = _tx_ant == "TX/RX" ? 0 : TX_LED_TXRX; - //setup the tx atr (this does not change with antenna) - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_IDLE, 0 | tx_lo_lpf_en \ - | tx_ld_led | tx_ant_led | TX_POWER_UP | ANT_XX | TX_MIXER_DIS); - - //setup the rx atr (this does not change with antenna) - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_IDLE, rx_pga0_iobits | rx_lo_lpf_en \ - | rx_ld_led | rx_ant_led | RX_POWER_UP | ANT_XX | RX_MIXER_DIS); - - //set the RX atr regs that change with antenna setting - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_RX_ONLY, rx_pga0_iobits | rx_lo_lpf_en \ - | rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_ENB \ - | ((_rx_ant != "RX2")? ANT_TXRX : ANT_RX2)); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_TX_ONLY, rx_pga0_iobits | rx_lo_lpf_en \ - | rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_DIS \ - | ((_rx_ant == "CAL")? ANT_TXRX : ANT_RX2)); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_FULL_DUPLEX, rx_pga0_iobits | rx_lo_lpf_en \ - | rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_ENB \ - | ((_rx_ant == "CAL")? ANT_TXRX : ANT_RX2)); - - //set the TX atr regs that change with antenna setting - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_RX_ONLY, 0 | tx_lo_lpf_en \ - | tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_DIS \ - | ((_rx_ant != "RX2")? ANT_RX : ANT_TX)); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_TX_ONLY, tx_pga0_iobits | tx_lo_lpf_en \ - | tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_ENB \ - | ((_tx_ant == "CAL")? ANT_RX : ANT_TX)); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_FULL_DUPLEX, tx_pga0_iobits | tx_lo_lpf_en \ - | tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_ENB \ - | ((_tx_ant == "CAL")? ANT_RX : ANT_TX)); + // setup the tx atr (this does not change with antenna) + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_IDLE, + 0 | tx_lo_lpf_en | tx_ld_led | tx_ant_led | TX_POWER_UP | ANT_XX | TX_MIXER_DIS); + + // setup the rx atr (this does not change with antenna) + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_IDLE, + rx_pga0_iobits | rx_lo_lpf_en | rx_ld_led | rx_ant_led | RX_POWER_UP | ANT_XX + | RX_MIXER_DIS); + + // set the RX atr regs that change with antenna setting + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + rx_pga0_iobits | rx_lo_lpf_en | rx_ld_led | rx_ant_led | RX_POWER_UP + | RX_MIXER_ENB | ((_rx_ant != "RX2") ? ANT_TXRX : ANT_RX2)); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_TX_ONLY, + rx_pga0_iobits | rx_lo_lpf_en | rx_ld_led | rx_ant_led | RX_POWER_UP + | RX_MIXER_DIS | ((_rx_ant == "CAL") ? ANT_TXRX : ANT_RX2)); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + rx_pga0_iobits | rx_lo_lpf_en | rx_ld_led | rx_ant_led | RX_POWER_UP + | RX_MIXER_ENB | ((_rx_ant == "CAL") ? ANT_TXRX : ANT_RX2)); + + // set the TX atr regs that change with antenna setting + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_RX_ONLY, + 0 | tx_lo_lpf_en | tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_DIS + | ((_rx_ant != "RX2") ? ANT_RX : ANT_TX)); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + tx_pga0_iobits | tx_lo_lpf_en | tx_ld_led | tx_ant_led | TX_POWER_UP + | TX_MIXER_ENB | ((_tx_ant == "CAL") ? ANT_RX : ANT_TX)); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + tx_pga0_iobits | tx_lo_lpf_en | tx_ld_led | tx_ant_led | TX_POWER_UP + | TX_MIXER_ENB | ((_tx_ant == "CAL") ? ANT_RX : ANT_TX)); } -void sbx_xcvr::set_rx_ant(const std::string &ant){ - //validate input +void sbx_xcvr::set_rx_ant(const std::string& ant) +{ + // validate input assert_has(sbx_rx_antennas, ant, "sbx rx antenna name"); - //shadow the setting + // shadow the setting _rx_ant = ant; - //write the new antenna setting to atr regs + // write the new antenna setting to atr regs update_atr(); } -void sbx_xcvr::set_tx_ant(const std::string &ant){ +void sbx_xcvr::set_tx_ant(const std::string& ant) +{ assert_has(sbx_tx_antennas, ant, "sbx tx antenna name"); - //shadow the setting + // shadow the setting _tx_ant = ant; - //write the new antenna setting to atr regs + // write the new antenna setting to atr regs update_atr(); } /*********************************************************************** * Tuning **********************************************************************/ -double sbx_xcvr::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { +double sbx_xcvr::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ const double actual = db_actual->set_lo_freq(unit, target_freq); - if (unit == dboard_iface::UNIT_RX){ + if (unit == dboard_iface::UNIT_RX) { _rx_lo_lock_cache = false; - _rx_lo_freq = actual; + _rx_lo_freq = actual; } - if (unit == dboard_iface::UNIT_TX){ + if (unit == dboard_iface::UNIT_TX) { _tx_lo_lock_cache = false; - _tx_lo_freq = actual; + _tx_lo_freq = actual; } update_atr(); return actual; } -sensor_value_t sbx_xcvr::get_locked(dboard_iface::unit_t unit) { +sensor_value_t sbx_xcvr::get_locked(dboard_iface::unit_t unit) +{ const bool locked = (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0; bool& lock_cache = (unit == dboard_iface::UNIT_RX) ? _rx_lo_lock_cache : _tx_lo_lock_cache; diff --git a/host/lib/usrp/dboard/db_sbx_common.hpp b/host/lib/usrp/dboard/db_sbx_common.hpp index 9c09f21a3..c11f0bbe2 100644 --- a/host/lib/usrp/dboard/db_sbx_common.hpp +++ b/host/lib/usrp/dboard/db_sbx_common.hpp @@ -10,73 +10,76 @@ #include <uhdlib/usrp/common/max287x.hpp> // LO Related -#define ADF435X_CE (1 << 3) -#define ADF435X_PDBRF (1 << 2) -#define ADF435X_MUXOUT (1 << 1) // INPUT!!! -#define LOCKDET_MASK (1 << 0) // INPUT!!! +#define ADF435X_CE (1 << 3) +#define ADF435X_PDBRF (1 << 2) +#define ADF435X_MUXOUT (1 << 1) // INPUT!!! +#define LOCKDET_MASK (1 << 0) // INPUT!!! // Common IO Pins -#define LO_LPF_EN (1 << 15) +#define LO_LPF_EN (1 << 15) // TX IO Pins -#define TRSW (1 << 14) // 0 = TX, 1 = RX -#define TX_LED_TXRX (1 << 7) // LED for TX Antenna Selection TX/RX -#define TX_LED_LD (1 << 6) // LED for TX Lock Detect -#define DIS_POWER_TX (1 << 5) // on UNIT_TX, 0 powers up TX -#define TX_ENABLE (1 << 4) // on UNIT_TX, 0 disables TX Mixer +#define TRSW (1 << 14) // 0 = TX, 1 = RX +#define TX_LED_TXRX (1 << 7) // LED for TX Antenna Selection TX/RX +#define TX_LED_LD (1 << 6) // LED for TX Lock Detect +#define DIS_POWER_TX (1 << 5) // on UNIT_TX, 0 powers up TX +#define TX_ENABLE (1 << 4) // on UNIT_TX, 0 disables TX Mixer // RX IO Pins -#define LNASW (1 << 14) // 0 = TX/RX, 1 = RX2 -#define RX_LED_RX1RX2 (1 << 7) // LED for RX Antenna Selection RX1/RX2 -#define RX_LED_LD (1 << 6) // LED for RX Lock Detect -#define DIS_POWER_RX (1 << 5) // on UNIT_RX, 0 powers up RX -#define RX_DISABLE (1 << 4) // on UNIT_RX, 1 disables RX Mixer and Baseband -#define RX_ATTN_SHIFT 8 //lsb of RX Attenuator Control -#define RX_ATTN_MASK (63 << RX_ATTN_SHIFT) //valid bits of RX Attenuator Control +#define LNASW (1 << 14) // 0 = TX/RX, 1 = RX2 +#define RX_LED_RX1RX2 (1 << 7) // LED for RX Antenna Selection RX1/RX2 +#define RX_LED_LD (1 << 6) // LED for RX Lock Detect +#define DIS_POWER_RX (1 << 5) // on UNIT_RX, 0 powers up RX +#define RX_DISABLE (1 << 4) // on UNIT_RX, 1 disables RX Mixer and Baseband +#define RX_ATTN_SHIFT 8 // lsb of RX Attenuator Control +#define RX_ATTN_MASK (63 << RX_ATTN_SHIFT) // valid bits of RX Attenuator Control // TX Attenuator Pins -#define TX_ATTN_SHIFT 8 // lsb of TX Attenuator Control -#define TX_ATTN_MASK (63 << TX_ATTN_SHIFT) // valid bits of TX Attenuator Control +#define TX_ATTN_SHIFT 8 // lsb of TX Attenuator Control +#define TX_ATTN_MASK (63 << TX_ATTN_SHIFT) // valid bits of TX Attenuator Control // Mixer functions -#define TX_MIXER_ENB (ADF435X_PDBRF|TX_ENABLE) -#define TX_MIXER_DIS 0 +#define TX_MIXER_ENB (ADF435X_PDBRF | TX_ENABLE) +#define TX_MIXER_DIS 0 -#define RX_MIXER_ENB (ADF435X_PDBRF) -#define RX_MIXER_DIS 0 +#define RX_MIXER_ENB (ADF435X_PDBRF) +#define RX_MIXER_DIS 0 // Pin functions -#define TX_LED_IO (TX_LED_TXRX|TX_LED_LD) // LED gpio lines, pull down for LED -#define TXIO_MASK (LO_LPF_EN|TRSW|ADF435X_CE|ADF435X_PDBRF|TX_ATTN_MASK|DIS_POWER_TX|TX_ENABLE) +#define TX_LED_IO (TX_LED_TXRX | TX_LED_LD) // LED gpio lines, pull down for LED +#define TXIO_MASK \ + (LO_LPF_EN | TRSW | ADF435X_CE | ADF435X_PDBRF | TX_ATTN_MASK | DIS_POWER_TX \ + | TX_ENABLE) -#define RX_LED_IO (RX_LED_RX1RX2|RX_LED_LD) // LED gpio lines, pull down for LED -#define RXIO_MASK (LO_LPF_EN|LNASW|ADF435X_CE|ADF435X_PDBRF|RX_ATTN_MASK|DIS_POWER_RX|RX_DISABLE) +#define RX_LED_IO (RX_LED_RX1RX2 | RX_LED_LD) // LED gpio lines, pull down for LED +#define RXIO_MASK \ + (LO_LPF_EN | LNASW | ADF435X_CE | ADF435X_PDBRF | RX_ATTN_MASK | DIS_POWER_RX \ + | RX_DISABLE) // Power functions -#define TX_POWER_UP (ADF435X_CE) -#define TX_POWER_DOWN (DIS_POWER_TX) +#define TX_POWER_UP (ADF435X_CE) +#define TX_POWER_DOWN (DIS_POWER_TX) -#define RX_POWER_UP (ADF435X_CE) -#define RX_POWER_DOWN (DIS_POWER_RX) +#define RX_POWER_UP (ADF435X_CE) +#define RX_POWER_DOWN (DIS_POWER_RX) // Antenna constants -#define ANT_TX TRSW //the tx line is transmitting -#define ANT_RX 0 //the tx line is receiving -#define ANT_TXRX 0 //the rx line is on txrx -#define ANT_RX2 LNASW //the rx line in on rx2 -#define ANT_XX LNASW //dont care how the antenna is set +#define ANT_TX TRSW // the tx line is transmitting +#define ANT_RX 0 // the tx line is receiving +#define ANT_TXRX 0 // the rx line is on txrx +#define ANT_RX2 LNASW // the rx line in on rx2 +#define ANT_XX LNASW // dont care how the antenna is set #include <uhd/types/dict.hpp> #include <uhd/types/ranges.hpp> #include <uhd/types/sensors.hpp> +#include <uhd/usrp/dboard_base.hpp> +#include <uhd/usrp/dboard_manager.hpp> +#include <uhd/utils/algorithm.hpp> #include <uhd/utils/assert_has.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/static.hpp> -#include <uhd/utils/algorithm.hpp> - -#include <uhd/usrp/dboard_base.hpp> -#include <uhd/usrp/dboard_manager.hpp> #include <boost/assign/list_of.hpp> #include <boost/format.hpp> #include <boost/math/special_functions/round.hpp> @@ -94,57 +97,45 @@ using namespace boost::assign; static const freq_range_t sbx_freq_range(400e6, 4.4e9); static const freq_range_t cbx_freq_range(1200e6, 6.0e9); -static const freq_range_t sbx_tx_lo_2dbm = list_of - (range_t(0.35e9, 0.37e9)) -; +static const freq_range_t sbx_tx_lo_2dbm = list_of(range_t(0.35e9, 0.37e9)); -static const freq_range_t sbx_enable_tx_lo_filter = list_of - (range_t(0.4e9, 1.5e9)) -; +static const freq_range_t sbx_enable_tx_lo_filter = list_of(range_t(0.4e9, 1.5e9)); -static const freq_range_t sbx_enable_rx_lo_filter = list_of - (range_t(0.4e9, 1.5e9)) -; +static const freq_range_t sbx_enable_rx_lo_filter = list_of(range_t(0.4e9, 1.5e9)); -static const freq_range_t cbx_enable_tx_lo_filter = list_of - (range_t(1.2e9, 2e9)) -; +static const freq_range_t cbx_enable_tx_lo_filter = list_of(range_t(1.2e9, 2e9)); -static const freq_range_t cbx_enable_rx_lo_filter = list_of - (range_t(1.2e9, 2e9)) -; +static const freq_range_t cbx_enable_rx_lo_filter = list_of(range_t(1.2e9, 2e9)); static const std::vector<std::string> sbx_tx_antennas = list_of("TX/RX")("CAL"); static const std::vector<std::string> sbx_rx_antennas = list_of("TX/RX")("RX2")("CAL"); -static const uhd::dict<std::string, gain_range_t> sbx_tx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 31.5, double(0.5))) -; +static const uhd::dict<std::string, gain_range_t> sbx_tx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 31.5, double(0.5))); -static const uhd::dict<std::string, gain_range_t> sbx_rx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 31.5, double(0.5))) -; +static const uhd::dict<std::string, gain_range_t> sbx_rx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 31.5, double(0.5))); /*********************************************************************** * The SBX dboard **********************************************************************/ -class sbx_xcvr : public xcvr_dboard_base{ +class sbx_xcvr : public xcvr_dboard_base +{ public: sbx_xcvr(ctor_args_t args); virtual ~sbx_xcvr(void); protected: - uhd::dict<std::string, double> _tx_gains, _rx_gains; - double _rx_lo_freq, _tx_lo_freq; - std::string _tx_ant, _rx_ant; + double _rx_lo_freq, _tx_lo_freq; + std::string _tx_ant, _rx_ant; bool _rx_lo_lock_cache, _tx_lo_lock_cache; - void set_rx_ant(const std::string &ant); - void set_tx_ant(const std::string &ant); - double set_rx_gain(double gain, const std::string &name); - double set_tx_gain(double gain, const std::string &name); + void set_rx_ant(const std::string& ant); + void set_tx_ant(const std::string& ant); + double set_rx_gain(double gain, const std::string& name); + double set_tx_gain(double gain, const std::string& name); void update_atr(void); @@ -175,7 +166,8 @@ protected: * This class is an abstract base class, and thus is impossible to * instantiate. */ - class sbx_versionx { + class sbx_versionx + { public: sbx_versionx() {} virtual ~sbx_versionx(void) {} @@ -186,19 +178,21 @@ protected: /*! * Version 3 of the SBX Daughterboard */ - class sbx_version3 : public sbx_versionx { + class sbx_version3 : public sbx_versionx + { public: - sbx_version3(sbx_xcvr *_self_sbx_xcvr); + sbx_version3(sbx_xcvr* _self_sbx_xcvr); virtual ~sbx_version3(void); double set_lo_freq(dboard_iface::unit_t unit, double target_freq); /*! This is the registered instance of the wrapper class, sbx_base. */ - sbx_xcvr *self_base; + sbx_xcvr* self_base; + private: adf435x_iface::sptr _txlo; adf435x_iface::sptr _rxlo; - void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s); + void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t>& regs); }; /*! @@ -206,19 +200,21 @@ protected: * * The only difference in the fourth revision is the ADF4351 vs the ADF4350. */ - class sbx_version4 : public sbx_versionx { + class sbx_version4 : public sbx_versionx + { public: - sbx_version4(sbx_xcvr *_self_sbx_xcvr); + sbx_version4(sbx_xcvr* _self_sbx_xcvr); virtual ~sbx_version4(void); double set_lo_freq(dboard_iface::unit_t unit, double target_freq); /*! This is the registered instance of the wrapper class, sbx_base. */ - sbx_xcvr *self_base; + sbx_xcvr* self_base; + private: adf435x_iface::sptr _txlo; adf435x_iface::sptr _rxlo; - void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s); + void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t>& regs); }; /*! @@ -231,17 +227,19 @@ protected: * There is also no LO filter switching required on CBX, but the GPIO is left * blank so we don't worry about it. */ - class cbx : public sbx_versionx { + class cbx : public sbx_versionx + { public: - cbx(sbx_xcvr *_self_sbx_xcvr); + cbx(sbx_xcvr* _self_sbx_xcvr); virtual ~cbx(void); double set_lo_freq(dboard_iface::unit_t unit, double target_freq); /*! This is the registered instance of the wrapper class, sbx_base. */ - sbx_xcvr *self_base; + sbx_xcvr* self_base; + private: - void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s); + void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t>& regs); max287x_iface::sptr _txlo; max287x_iface::sptr _rxlo; }; @@ -253,15 +251,15 @@ protected: freq_range_t freq_range; /*! - * Frequency range to use the LO LPF in RX; this is set in the constructor - * to correspond either to SBX or CBX. - */ + * Frequency range to use the LO LPF in RX; this is set in the constructor + * to correspond either to SBX or CBX. + */ freq_range_t enable_rx_lo_filter; /*! - * Frequency range to use the LO LPF in TX; this is set in the constructor - * to correspond either to SBX or CBX. - */ + * Frequency range to use the LO LPF in TX; this is set in the constructor + * to correspond either to SBX or CBX. + */ freq_range_t enable_tx_lo_filter; /*! @@ -275,4 +273,3 @@ protected: typedef std::shared_ptr<sbx_versionx> sbx_versionx_sptr; sbx_versionx_sptr db_actual; }; - diff --git a/host/lib/usrp/dboard/db_sbx_version3.cpp b/host/lib/usrp/dboard/db_sbx_version3.cpp index 835b2f725..215c50c40 100644 --- a/host/lib/usrp/dboard/db_sbx_version3.cpp +++ b/host/lib/usrp/dboard/db_sbx_version3.cpp @@ -18,21 +18,29 @@ using namespace boost::assign; /*********************************************************************** * Structors **********************************************************************/ -sbx_xcvr::sbx_version3::sbx_version3(sbx_xcvr *_self_sbx_xcvr) { - //register the handle to our base SBX class +sbx_xcvr::sbx_version3::sbx_version3(sbx_xcvr* _self_sbx_xcvr) +{ + // register the handle to our base SBX class self_base = _self_sbx_xcvr; - _txlo = adf435x_iface::make_adf4350(std::bind(&sbx_xcvr::sbx_version3::write_lo_regs, this, dboard_iface::UNIT_TX, std::placeholders::_1)); - _rxlo = adf435x_iface::make_adf4350(std::bind(&sbx_xcvr::sbx_version3::write_lo_regs, this, dboard_iface::UNIT_RX, std::placeholders::_1)); + _txlo = adf435x_iface::make_adf4350(std::bind(&sbx_xcvr::sbx_version3::write_lo_regs, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)); + _rxlo = adf435x_iface::make_adf4350(std::bind(&sbx_xcvr::sbx_version3::write_lo_regs, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)); } -sbx_xcvr::sbx_version3::~sbx_version3(void){ +sbx_xcvr::sbx_version3::~sbx_version3(void) +{ /* NOP */ } -void sbx_xcvr::sbx_version3::write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s) +void sbx_xcvr::sbx_version3::write_lo_regs( + dboard_iface::unit_t unit, const std::vector<uint32_t>& regs) { - for(uint32_t reg: regs) - { + for (uint32_t reg : regs) { self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, reg, 32); } } @@ -40,42 +48,44 @@ void sbx_xcvr::sbx_version3::write_lo_regs(dboard_iface::unit_t unit, const std: /*********************************************************************** * Tuning **********************************************************************/ -double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { - UHD_LOGGER_TRACE("SBX") << boost::format( - "SBX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; +double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + UHD_LOGGER_TRACE("SBX") << boost::format("SBX tune: target frequency %f MHz") + % (target_freq / 1e6); /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to * tune in Integer-N mode, which can result in better spur * performance on some mixers. The default is fractional tuning. */ - property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree() - : self_base->get_tx_subtree(); + property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) + ? self_base->get_rx_subtree() + : self_base->get_tx_subtree(); device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); + bool is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); - //Select the LO + // Select the LO adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo; lo_iface->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED); lo_iface->set_reference_freq(self_base->get_iface()->get_clock_rate(unit)); - //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) - lo_iface->set_prescaler(target_freq > 3e9 ? adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5); + // Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) + lo_iface->set_prescaler( + target_freq > 3e9 ? adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5); - //Configure the LO + // Configure the LO double actual_freq = 0.0; actual_freq = lo_iface->set_frequency(sbx_freq_range.clip(target_freq), is_int_n); - if ((unit == dboard_iface::UNIT_TX) and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq))) { + if ((unit == dboard_iface::UNIT_TX) + and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq))) { lo_iface->set_output_power(adf435x_iface::OUTPUT_POWER_2DBM); } else { lo_iface->set_output_power(adf435x_iface::OUTPUT_POWER_5DBM); } - //Write to hardware + // Write to hardware lo_iface->commit(); return actual_freq; } - diff --git a/host/lib/usrp/dboard/db_sbx_version4.cpp b/host/lib/usrp/dboard/db_sbx_version4.cpp index 5c76a1b12..cf6dc4553 100644 --- a/host/lib/usrp/dboard/db_sbx_version4.cpp +++ b/host/lib/usrp/dboard/db_sbx_version4.cpp @@ -18,22 +18,30 @@ using namespace boost::assign; /*********************************************************************** * Structors **********************************************************************/ -sbx_xcvr::sbx_version4::sbx_version4(sbx_xcvr *_self_sbx_xcvr) { - //register the handle to our base SBX class +sbx_xcvr::sbx_version4::sbx_version4(sbx_xcvr* _self_sbx_xcvr) +{ + // register the handle to our base SBX class self_base = _self_sbx_xcvr; - _txlo = adf435x_iface::make_adf4351(std::bind(&sbx_xcvr::sbx_version4::write_lo_regs, this, dboard_iface::UNIT_TX, std::placeholders::_1)); - _rxlo = adf435x_iface::make_adf4351(std::bind(&sbx_xcvr::sbx_version4::write_lo_regs, this, dboard_iface::UNIT_RX, std::placeholders::_1)); + _txlo = adf435x_iface::make_adf4351(std::bind(&sbx_xcvr::sbx_version4::write_lo_regs, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)); + _rxlo = adf435x_iface::make_adf4351(std::bind(&sbx_xcvr::sbx_version4::write_lo_regs, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)); } -sbx_xcvr::sbx_version4::~sbx_version4(void){ +sbx_xcvr::sbx_version4::~sbx_version4(void) +{ /* NOP */ } -void sbx_xcvr::sbx_version4::write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s) +void sbx_xcvr::sbx_version4::write_lo_regs( + dboard_iface::unit_t unit, const std::vector<uint32_t>& regs) { - for(uint32_t reg: regs) - { + for (uint32_t reg : regs) { self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, reg, 32); } } @@ -42,42 +50,44 @@ void sbx_xcvr::sbx_version4::write_lo_regs(dboard_iface::unit_t unit, const std: /*********************************************************************** * Tuning **********************************************************************/ -double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { - UHD_LOGGER_TRACE("SBX") << boost::format( - "SBX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; +double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + UHD_LOGGER_TRACE("SBX") << boost::format("SBX tune: target frequency %f MHz") + % (target_freq / 1e6); /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to * tune in Integer-N mode, which can result in better spur * performance on some mixers. The default is fractional tuning. */ - property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree() - : self_base->get_tx_subtree(); + property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) + ? self_base->get_rx_subtree() + : self_base->get_tx_subtree(); device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); + bool is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); - //Select the LO + // Select the LO adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo; lo_iface->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED); lo_iface->set_reference_freq(self_base->get_iface()->get_clock_rate(unit)); - //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) - lo_iface->set_prescaler(target_freq > 3.6e9 ? adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5); + // Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) + lo_iface->set_prescaler(target_freq > 3.6e9 ? adf435x_iface::PRESCALER_8_9 + : adf435x_iface::PRESCALER_4_5); - //Configure the LO + // Configure the LO double actual_freq = 0.0; actual_freq = lo_iface->set_frequency(sbx_freq_range.clip(target_freq), is_int_n); - if ((unit == dboard_iface::UNIT_TX) and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq))) { + if ((unit == dboard_iface::UNIT_TX) + and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq))) { lo_iface->set_output_power(adf435x_iface::OUTPUT_POWER_2DBM); } else { lo_iface->set_output_power(adf435x_iface::OUTPUT_POWER_5DBM); } - //Write to hardware + // Write to hardware lo_iface->commit(); return actual_freq; } - diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp index cd238ddc8..02fed018c 100644 --- a/host/lib/usrp/dboard/db_tvrx.cpp +++ b/host/lib/usrp/dboard/db_tvrx.cpp @@ -10,13 +10,13 @@ // RX IO Functions -//ADC/DAC functions: -//DAC 1: RF AGC -//DAC 2: IF AGC +// ADC/DAC functions: +// DAC 1: RF AGC +// DAC 2: IF AGC -//min freq: 50e6 -//max freq: 860e6 -//gain range: [0:1dB:115dB] +// min freq: 50e6 +// max freq: 860e6 +// gain range: [0:1dB:115dB] #include <uhd/types/dict.hpp> #include <uhd/types/ranges.hpp> @@ -51,79 +51,140 @@ static const freq_range_t tvrx_freq_range(50e6, 860e6); static const std::vector<std::string> tvrx_antennas = list_of("RX"); -static const uhd::dict<std::string, freq_range_t> tvrx_freq_ranges = map_list_of - ("VHFLO", freq_range_t(50e6, 158e6)) - ("VHFHI", freq_range_t(158e6, 454e6)) - ("UHF" , freq_range_t(454e6, 860e6)) -; - -static const boost::array<double, 17> vhflo_gains_db = - {{-6.00000, -6.00000, -6.00000, -4.00000, 0.00000, - 5.00000, 10.00000, 17.40000, 26.30000, 36.00000, - 43.00000, 48.00000, 49.50000, 50.10000, 50.30000, - 50.30000, 50.30000}}; - -static const boost::array<double, 17> vhfhi_gains_db = - {{-13.3000, -13.3000, -13.3000, -1.0000, 7.7000, - 11.0000, 14.7000, 19.3000, 26.1000, 36.0000, - 42.7000, 46.0000, 47.0000, 47.8000, 48.2000, - 48.2000, 48.2000}}; - -static const boost::array<double, 17> uhf_gains_db = - {{-8.0000, -8.0000, -7.0000, 4.0000, 10.2000, - 14.5000, 17.5000, 20.0000, 24.5000, 30.8000, - 37.0000, 39.8000, 40.7000, 41.6000, 42.6000, - 43.2000, 43.8000}}; - -static const boost::array<double, 17> tvrx_if_gains_db = - {{-1.50000, -1.50000, -1.50000, -1.00000, 0.20000, - 2.10000, 4.30000, 6.40000, 9.00000, 12.00000, - 14.80000, 18.20000, 26.10000, 32.50000, 32.50000, - 32.50000, 32.50000}}; - -//gain linearization data -//this is from the datasheet and is dB vs. volts (below) -//i tried to curve fit this, but it's really just so nonlinear that you'd -//need dang near as many coefficients as to just map it like this and interp. -//these numbers are culled from the 4937DI5 datasheet and are probably totally inaccurate -//but if it's better than the old linear fit i'm happy -static const uhd::dict<std::string, boost::array<double, 17> > tvrx_rf_gains_db = map_list_of - ("VHFLO", vhflo_gains_db) - ("VHFHI", vhfhi_gains_db) - ("UHF" , uhf_gains_db) -; - -//sample voltages for the above points -static const boost::array<double, 17> tvrx_gains_volts = - {{0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0}}; - -static uhd::dict<std::string, gain_range_t> get_tvrx_gain_ranges(void) { +static const uhd::dict<std::string, freq_range_t> tvrx_freq_ranges = + map_list_of("VHFLO", freq_range_t(50e6, 158e6))("VHFHI", freq_range_t(158e6, 454e6))( + "UHF", freq_range_t(454e6, 860e6)); + +static const boost::array<double, 17> vhflo_gains_db = {{-6.00000, + -6.00000, + -6.00000, + -4.00000, + 0.00000, + 5.00000, + 10.00000, + 17.40000, + 26.30000, + 36.00000, + 43.00000, + 48.00000, + 49.50000, + 50.10000, + 50.30000, + 50.30000, + 50.30000}}; + +static const boost::array<double, 17> vhfhi_gains_db = {{-13.3000, + -13.3000, + -13.3000, + -1.0000, + 7.7000, + 11.0000, + 14.7000, + 19.3000, + 26.1000, + 36.0000, + 42.7000, + 46.0000, + 47.0000, + 47.8000, + 48.2000, + 48.2000, + 48.2000}}; + +static const boost::array<double, 17> uhf_gains_db = {{-8.0000, + -8.0000, + -7.0000, + 4.0000, + 10.2000, + 14.5000, + 17.5000, + 20.0000, + 24.5000, + 30.8000, + 37.0000, + 39.8000, + 40.7000, + 41.6000, + 42.6000, + 43.2000, + 43.8000}}; + +static const boost::array<double, 17> tvrx_if_gains_db = {{-1.50000, + -1.50000, + -1.50000, + -1.00000, + 0.20000, + 2.10000, + 4.30000, + 6.40000, + 9.00000, + 12.00000, + 14.80000, + 18.20000, + 26.10000, + 32.50000, + 32.50000, + 32.50000, + 32.50000}}; + +// gain linearization data +// this is from the datasheet and is dB vs. volts (below) +// i tried to curve fit this, but it's really just so nonlinear that you'd +// need dang near as many coefficients as to just map it like this and interp. +// these numbers are culled from the 4937DI5 datasheet and are probably totally inaccurate +// but if it's better than the old linear fit i'm happy +static const uhd::dict<std::string, boost::array<double, 17>> tvrx_rf_gains_db = + map_list_of("VHFLO", vhflo_gains_db)("VHFHI", vhfhi_gains_db)("UHF", uhf_gains_db); + +// sample voltages for the above points +static const boost::array<double, 17> tvrx_gains_volts = {{0.8, + 1.0, + 1.2, + 1.4, + 1.6, + 1.8, + 2.0, + 2.2, + 2.4, + 2.6, + 2.8, + 3.0, + 3.2, + 3.4, + 3.6, + 3.8, + 4.0}}; + +static uhd::dict<std::string, gain_range_t> get_tvrx_gain_ranges(void) +{ double rfmax = 0.0, rfmin = FLT_MAX; - for(const std::string range: tvrx_rf_gains_db.keys()) { - double my_max = tvrx_rf_gains_db[range].back(); //we're assuming it's monotonic - double my_min = tvrx_rf_gains_db[range].front(); //if it's not this is wrong wrong wrong - if(my_max > rfmax) rfmax = my_max; - if(my_min < rfmin) rfmin = my_min; + for (const std::string range : tvrx_rf_gains_db.keys()) { + double my_max = tvrx_rf_gains_db[range].back(); // we're assuming it's monotonic + double my_min = + tvrx_rf_gains_db[range].front(); // if it's not this is wrong wrong wrong + if (my_max > rfmax) + rfmax = my_max; + if (my_min < rfmin) + rfmin = my_min; } double ifmin = tvrx_if_gains_db.front(); double ifmax = tvrx_if_gains_db.back(); - return map_list_of - ("RF", gain_range_t(rfmin, rfmax, (rfmax-rfmin)/4096.0)) - ("IF", gain_range_t(ifmin, ifmax, (ifmax-ifmin)/4096.0)) - ; + return map_list_of("RF", gain_range_t(rfmin, rfmax, (rfmax - rfmin) / 4096.0))( + "IF", gain_range_t(ifmin, ifmax, (ifmax - ifmin) / 4096.0)); } -static const double opamp_gain = 1.22; //onboard DAC opamp gain -static const double tvrx_if_freq = 43.75e6; //IF freq of TVRX module -static const uint16_t reference_divider = 640; //clock reference divider to use +static const double opamp_gain = 1.22; // onboard DAC opamp gain +static const double tvrx_if_freq = 43.75e6; // IF freq of TVRX module +static const uint16_t reference_divider = 640; // clock reference divider to use static const double reference_freq = 4.0e6; /*********************************************************************** * The tvrx dboard class **********************************************************************/ -class tvrx : public rx_dboard_base{ +class tvrx : public rx_dboard_base +{ public: tvrx(ctor_args_t args); virtual ~tvrx(void); @@ -132,116 +193,119 @@ private: uhd::dict<std::string, double> _gains; double _lo_freq; tuner_4937di5_regs_t _tuner_4937di5_regs; - uint8_t _tuner_4937di5_addr(void){ - return (this->get_iface()->get_special_props().mangle_i2c_addrs)? 0x61 : 0x60; //ok really? we could rename that call + uint8_t _tuner_4937di5_addr(void) + { + return (this->get_iface()->get_special_props().mangle_i2c_addrs) + ? 0x61 + : 0x60; // ok really? we could rename that call }; - double set_gain(double gain, const std::string &name); + double set_gain(double gain, const std::string& name); double set_freq(double freq); - void update_regs(void){ + void update_regs(void) + { byte_vector_t regs_vector(4); - //get the register data - for(int i=0; i<4; i++){ + // get the register data + for (int i = 0; i < 4; i++) { regs_vector[i] = _tuner_4937di5_regs.get_reg(i); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "tvrx: send reg 0x%02x, value 0x%04x" - ) % int(i) % int(regs_vector[i]) ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("tvrx: send reg 0x%02x, value 0x%04x") % int(i) + % int(regs_vector[i]); } - //send the data - this->get_iface()->write_i2c( - _tuner_4937di5_addr(), regs_vector - ); + // send the data + this->get_iface()->write_i2c(_tuner_4937di5_addr(), regs_vector); } - }; /*********************************************************************** * Register the tvrx dboard **********************************************************************/ -static dboard_base::sptr make_tvrx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_tvrx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new tvrx(args)); } -UHD_STATIC_BLOCK(reg_tvrx_dboard){ - //register the factory function for the rx dbid +UHD_STATIC_BLOCK(reg_tvrx_dboard) +{ + // register the factory function for the rx dbid dboard_manager::register_dboard(0x0040, &make_tvrx, "TVRX"); } /*********************************************************************** * Structors **********************************************************************/ -tvrx::tvrx(ctor_args_t args) : rx_dboard_base(args){ +tvrx::tvrx(ctor_args_t args) : rx_dboard_base(args) +{ //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - this->get_rx_subtree()->create<std::string>("name") - .set("TVRX"); - this->get_rx_subtree()->create<int>("sensors"); //phony property so this dir exists - for(const std::string &name: get_tvrx_gain_ranges().keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") + this->get_rx_subtree()->create<std::string>("name").set("TVRX"); + this->get_rx_subtree()->create<int>("sensors"); // phony property so this dir exists + for (const std::string& name : get_tvrx_gain_ranges().keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") .set_coercer(std::bind(&tvrx::set_gain, this, std::placeholders::_1, name)); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(get_tvrx_gain_ranges()[name]); } - this->get_rx_subtree()->create<double>("freq/value") + this->get_rx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&tvrx::set_freq, this, std::placeholders::_1)); - this->get_rx_subtree()->create<meta_range_t>("freq/range") - .set(tvrx_freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") - .set(tvrx_antennas.at(0)); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree()->create<meta_range_t>("freq/range").set(tvrx_freq_range); + this->get_rx_subtree()->create<std::string>("antenna/value").set(tvrx_antennas.at(0)); + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(tvrx_antennas); - this->get_rx_subtree()->create<std::string>("connection") - .set("I"); - this->get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_rx_subtree()->create<double>("bandwidth/value") - .set(6.0e6); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_rx_subtree()->create<std::string>("connection").set("I"); + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_rx_subtree()->create<double>("bandwidth/value").set(6.0e6); + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(freq_range_t(6.0e6, 6.0e6)); - //enable only the clocks we need + // enable only the clocks we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); - //set the gpio directions and atr controls (identically) + // set the gpio directions and atr controls (identically) this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0); // All unused in atr - if (this->get_iface()->get_special_props().soft_clock_divider){ + if (this->get_iface()->get_special_props().soft_clock_divider) { this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x1); // GPIO0 is clock - } - else{ + } else { this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x0); // All Inputs } - //send initial register settings if necessary + // send initial register settings if necessary - //set default freq - _lo_freq = tvrx_freq_range.start() + tvrx_if_freq; //init _lo_freq to a sane default + // set default freq + _lo_freq = tvrx_freq_range.start() + tvrx_if_freq; // init _lo_freq to a sane default this->get_rx_subtree()->access<double>("freq/value").set(tvrx_freq_range.start()); - //set default gains - for(const std::string &name: get_tvrx_gain_ranges().keys()){ - this->get_rx_subtree()->access<double>("gains/"+name+"/value") + // set default gains + for (const std::string& name : get_tvrx_gain_ranges().keys()) { + this->get_rx_subtree() + ->access<double>("gains/" + name + "/value") .set(get_tvrx_gain_ranges()[name].start()); } } -tvrx::~tvrx(void){ -} +tvrx::~tvrx(void) {} /*! Return a string corresponding to the relevant band * \param freq the frequency of interest * \return a string corresponding to the band */ -static std::string get_band(double freq) { - for(const std::string &band: tvrx_freq_ranges.keys()) { - if(freq >= tvrx_freq_ranges[band].start() && freq <= tvrx_freq_ranges[band].stop()){ - UHD_LOGGER_TRACE("TVRX") << "Band: " << band ; +static std::string get_band(double freq) +{ + for (const std::string& band : tvrx_freq_ranges.keys()) { + if (freq >= tvrx_freq_ranges[band].start() + && freq <= tvrx_freq_ranges[band].stop()) { + UHD_LOGGER_TRACE("TVRX") << "Band: " << band; return band; } } @@ -259,33 +323,39 @@ static std::string get_band(double freq) { * \return a voltage to feed the TVRX analog gain */ -static double gain_interp(double gain, const boost::array<double, 17>& db_vector, const boost::array<double, 17>& volts_vector) { +static double gain_interp(double gain, + const boost::array<double, 17>& db_vector, + const boost::array<double, 17>& volts_vector) +{ double volts; - gain = uhd::clip<double>(gain, db_vector.front(), db_vector.back()); //let's not get carried away here + gain = uhd::clip<double>( + gain, db_vector.front(), db_vector.back()); // let's not get carried away here uint8_t gain_step = 0; - //find which bin we're in - for(size_t i = 0; i < db_vector.size()-1; i++) { - if (gain >= db_vector[i] && gain <= db_vector[i+1]) { + // find which bin we're in + for (size_t i = 0; i < db_vector.size() - 1; i++) { + if (gain >= db_vector[i] && gain <= db_vector[i + 1]) { gain_step = uhd::narrow_cast<uint8_t>(i); } } - //find the current slope for linear interpolation + // find the current slope for linear interpolation double slope = (volts_vector[gain_step + 1] - volts_vector[gain_step]) - / (db_vector[gain_step + 1] - db_vector[gain_step]); + / (db_vector[gain_step + 1] - db_vector[gain_step]); - //the problem here is that for gains approaching the maximum, the voltage slope becomes infinite - //i.e., a small change in gain requires an infinite change in voltage - //to cope, we limit the slope + // the problem here is that for gains approaching the maximum, the voltage slope + // becomes infinite i.e., a small change in gain requires an infinite change in + // voltage to cope, we limit the slope - if(slope == std::numeric_limits<double>::infinity()) + if (slope == std::numeric_limits<double>::infinity()) return volts_vector[gain_step]; - //use the volts per dB slope to find the final interpolated voltage + // use the volts per dB slope to find the final interpolated voltage volts = volts_vector[gain_step] + (slope * (gain - db_vector[gain_step])); - UHD_LOGGER_TRACE("TVRX") << "Gain interp: gain: " << gain << ", gain_step: " << int(gain_step) << ", slope: " << slope << ", volts: " << volts ; + UHD_LOGGER_TRACE("TVRX") << "Gain interp: gain: " << gain + << ", gain_step: " << int(gain_step) << ", slope: " << slope + << ", volts: " << volts; return volts; } @@ -297,23 +367,24 @@ static double gain_interp(double gain, const boost::array<double, 17>& db_vector * \return dac voltage value */ -static double rf_gain_to_voltage(double gain, double lo_freq){ - //clip the input +static double rf_gain_to_voltage(double gain, double lo_freq) +{ + // clip the input gain = get_tvrx_gain_ranges()["RF"].clip(gain); - //first we need to find out what band we're in, because gains are different across different bands + // first we need to find out what band we're in, because gains are different across + // different bands std::string band = get_band(lo_freq - tvrx_if_freq); - //this is the voltage at the TVRX gain input + // this is the voltage at the TVRX gain input double gain_volts = gain_interp(gain, tvrx_rf_gains_db[band], tvrx_gains_volts); - //this is the voltage at the USRP DAC output + // this is the voltage at the USRP DAC output double dac_volts = gain_volts / opamp_gain; dac_volts = uhd::clip<double>(dac_volts, 0.0, 3.3); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "tvrx RF AGC gain: %f dB, dac_volts: %f V" - ) % gain % dac_volts ; + UHD_LOGGER_TRACE("TVRX") << boost::format("tvrx RF AGC gain: %f dB, dac_volts: %f V") + % gain % dac_volts; return dac_volts; } @@ -325,31 +396,34 @@ static double rf_gain_to_voltage(double gain, double lo_freq){ * \return dac voltage value */ -static double if_gain_to_voltage(double gain){ - //clip the input +static double if_gain_to_voltage(double gain) +{ + // clip the input gain = get_tvrx_gain_ranges()["IF"].clip(gain); double gain_volts = gain_interp(gain, tvrx_if_gains_db, tvrx_gains_volts); - double dac_volts = gain_volts / opamp_gain; + double dac_volts = gain_volts / opamp_gain; dac_volts = uhd::clip<double>(dac_volts, 0.0, 3.3); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "tvrx IF AGC gain: %f dB, dac_volts: %f V" - ) % gain % dac_volts ; + UHD_LOGGER_TRACE("TVRX") << boost::format("tvrx IF AGC gain: %f dB, dac_volts: %f V") + % gain % dac_volts; return dac_volts; } -double tvrx::set_gain(double gain, const std::string &name){ +double tvrx::set_gain(double gain, const std::string& name) +{ assert_has(get_tvrx_gain_ranges().keys(), name, "tvrx gain name"); - if (name == "RF"){ - this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_B, rf_gain_to_voltage(gain, _lo_freq)); - } - else if(name == "IF"){ - this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, if_gain_to_voltage(gain)); - } - else UHD_THROW_INVALID_CODE_PATH(); + if (name == "RF") { + this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, + dboard_iface::AUX_DAC_B, + rf_gain_to_voltage(gain, _lo_freq)); + } else if (name == "IF") { + this->get_iface()->write_aux_dac( + dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, if_gain_to_voltage(gain)); + } else + UHD_THROW_INVALID_CODE_PATH(); _gains[name] = gain; return gain; @@ -360,44 +434,55 @@ double tvrx::set_gain(double gain, const std::string &name){ * \param freq the requested frequency */ -double tvrx::set_freq(double freq) { - freq = tvrx_freq_range.clip(freq); +double tvrx::set_freq(double freq) +{ + freq = tvrx_freq_range.clip(freq); std::string prev_band = get_band(_lo_freq - tvrx_if_freq); - std::string new_band = get_band(freq); + std::string new_band = get_band(freq); - double target_lo_freq = freq + tvrx_if_freq; //the desired LO freq for high-side mixing - double f_ref = reference_freq / double(reference_divider); //your tuning step size + double target_lo_freq = + freq + tvrx_if_freq; // the desired LO freq for high-side mixing + double f_ref = reference_freq / double(reference_divider); // your tuning step size - int divisor = int((target_lo_freq + (f_ref * 4.0)) / (f_ref * 8)); //the divisor we'll use - double actual_lo_freq = (f_ref * 8 * divisor); //the LO freq we'll actually get + int divisor = + int((target_lo_freq + (f_ref * 4.0)) / (f_ref * 8)); // the divisor we'll use + double actual_lo_freq = (f_ref * 8 * divisor); // the LO freq we'll actually get - if((divisor & ~0x7fff)) UHD_THROW_INVALID_CODE_PATH(); + if ((divisor & ~0x7fff)) + UHD_THROW_INVALID_CODE_PATH(); - //now we update the registers + // now we update the registers _tuner_4937di5_regs.db1 = (divisor >> 8) & 0xff; _tuner_4937di5_regs.db2 = divisor & 0xff; - if(new_band == "VHFLO") _tuner_4937di5_regs.bandsel = tuner_4937di5_regs_t::BANDSEL_VHFLO; - else if(new_band == "VHFHI") _tuner_4937di5_regs.bandsel = tuner_4937di5_regs_t::BANDSEL_VHFHI; - else if(new_band == "UHF") _tuner_4937di5_regs.bandsel = tuner_4937di5_regs_t::BANDSEL_UHF; - else UHD_THROW_INVALID_CODE_PATH(); + if (new_band == "VHFLO") + _tuner_4937di5_regs.bandsel = tuner_4937di5_regs_t::BANDSEL_VHFLO; + else if (new_band == "VHFHI") + _tuner_4937di5_regs.bandsel = tuner_4937di5_regs_t::BANDSEL_VHFHI; + else if (new_band == "UHF") + _tuner_4937di5_regs.bandsel = tuner_4937di5_regs_t::BANDSEL_UHF; + else + UHD_THROW_INVALID_CODE_PATH(); _tuner_4937di5_regs.power = tuner_4937di5_regs_t::POWER_OFF; update_regs(); - //ok don't forget to reset RF gain here if the new band != the old band - //we do this because the gains are different for different band settings - //not FAR off, but we do this to be consistent - if(prev_band != new_band) set_gain(_gains["RF"], "RF"); + // ok don't forget to reset RF gain here if the new band != the old band + // we do this because the gains are different for different band settings + // not FAR off, but we do this to be consistent + if (prev_band != new_band) + set_gain(_gains["RF"], "RF"); - UHD_LOGGER_TRACE("TVRX") << boost::format("set_freq: target LO: %f f_ref: %f divisor: %i actual LO: %f") % target_lo_freq % f_ref % divisor % actual_lo_freq ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("set_freq: target LO: %f f_ref: %f divisor: %i actual LO: %f") + % target_lo_freq % f_ref % divisor % actual_lo_freq; - _lo_freq = actual_lo_freq; //for rx props + _lo_freq = actual_lo_freq; // for rx props - //Check the the IF if larger than the dsp rate and apply a corrective adjustment - //so that the cordic will be tuned to a possible rate within its range. + // Check the the IF if larger than the dsp rate and apply a corrective adjustment + // so that the cordic will be tuned to a possible rate within its range. const double codec_rate = this->get_iface()->get_codec_rate(dboard_iface::UNIT_RX); - if (tvrx_if_freq >= codec_rate/2){ + if (tvrx_if_freq >= codec_rate / 2) { return _lo_freq - codec_rate; } diff --git a/host/lib/usrp/dboard/db_tvrx2.cpp b/host/lib/usrp/dboard/db_tvrx2.cpp index 5767243d9..0f1673633 100644 --- a/host/lib/usrp/dboard/db_tvrx2.cpp +++ b/host/lib/usrp/dboard/db_tvrx2.cpp @@ -70,34 +70,50 @@ using namespace boost::assign; /*********************************************************************** * The TVRX2 types **********************************************************************/ -struct tvrx2_tda18272_rfcal_result_t { - int8_t delta_c; - int8_t c_offset; - tvrx2_tda18272_rfcal_result_t(void): delta_c(0), c_offset(0){} +struct tvrx2_tda18272_rfcal_result_t +{ + int8_t delta_c; + int8_t c_offset; + tvrx2_tda18272_rfcal_result_t(void) : delta_c(0), c_offset(0) {} }; -struct tvrx2_tda18272_rfcal_coeffs_t { - uint8_t cal_number; - int32_t RF_A1; - int32_t RF_B1; - tvrx2_tda18272_rfcal_coeffs_t(void): cal_number(0), RF_A1(0), RF_B1(0) {} - tvrx2_tda18272_rfcal_coeffs_t(uint32_t num): RF_A1(0), RF_B1(0) { cal_number = num; } +struct tvrx2_tda18272_rfcal_coeffs_t +{ + uint8_t cal_number; + int32_t RF_A1; + int32_t RF_B1; + tvrx2_tda18272_rfcal_coeffs_t(void) : cal_number(0), RF_A1(0), RF_B1(0) {} + tvrx2_tda18272_rfcal_coeffs_t(uint32_t num) : RF_A1(0), RF_B1(0) + { + cal_number = num; + } }; -struct tvrx2_tda18272_cal_map_t { - boost::array<uint32_t, 4> cal_freq; - boost::array<uint8_t, 4> c_offset; - tvrx2_tda18272_cal_map_t(boost::array<uint32_t, 4> freqs, boost::array<uint8_t, 4> offsets) - { cal_freq = freqs; c_offset = offsets; } +struct tvrx2_tda18272_cal_map_t +{ + boost::array<uint32_t, 4> cal_freq; + boost::array<uint8_t, 4> c_offset; + tvrx2_tda18272_cal_map_t( + boost::array<uint32_t, 4> freqs, boost::array<uint8_t, 4> offsets) + { + cal_freq = freqs; + c_offset = offsets; + } }; -struct tvrx2_tda18272_freq_map_t { - uint32_t rf_max; - uint8_t c_prog; - uint8_t gain_taper; - uint8_t rf_band; - tvrx2_tda18272_freq_map_t( uint32_t max, uint8_t c, uint8_t taper, uint8_t band) - { rf_max = max; c_prog = c; gain_taper = taper; rf_band = band; } +struct tvrx2_tda18272_freq_map_t +{ + uint32_t rf_max; + uint8_t c_prog; + uint8_t gain_taper; + uint8_t rf_band; + tvrx2_tda18272_freq_map_t(uint32_t max, uint8_t c, uint8_t taper, uint8_t band) + { + rf_max = max; + c_prog = c; + gain_taper = taper; + rf_band = band; + } }; /*********************************************************************** @@ -743,7 +759,8 @@ static const uhd::dict<std::string, gain_range_t> tvrx2_gain_ranges = map_list_o /*********************************************************************** * The TVRX2 dboard class **********************************************************************/ -class tvrx2 : public rx_dboard_base{ +class tvrx2 : public rx_dboard_base +{ public: tvrx2(ctor_args_t args); virtual ~tvrx2(void); @@ -763,7 +780,7 @@ private: bool set_enabled(bool); double set_lo_freq(double target_freq); - double set_gain(double gain, const std::string &name); + double set_gain(double gain, const std::string& name); double set_bandwidth(double bandwidth); void set_scaled_rf_freq(double rf_freq); @@ -785,22 +802,22 @@ private: void wait_irq(void); void test_rf_filter_robustness(void); -/*********************************************************************** - * The TVRX2 class helper functions - **********************************************************************/ + /*********************************************************************** + * The TVRX2 class helper functions + **********************************************************************/ /*! * Is the IRQ set or cleared? * \return true for set */ - bool get_irq(void){ + bool get_irq(void) + { read_reg(0x8, 0x8); - //return irq status + // return irq status bool irq = _tda18272hnm_regs.irq_status == tda18272hnm_regs_t::IRQ_STATUS_SET; - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): IRQ %d" - ) % (get_subdev_name()) % irq ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s): IRQ %d") % (get_subdev_name()) % irq; return irq; } @@ -810,15 +827,16 @@ private: * Check POR logic for reset state (causes POR to clear) * \return true for reset */ - bool get_power_reset(void){ + bool get_power_reset(void) + { read_reg(0x5, 0x5); - //return POR state + // return POR state bool por = _tda18272hnm_regs.por == tda18272hnm_regs_t::POR_RESET; - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): POR %d" - ) % (get_subdev_name()) % int(_tda18272hnm_regs.por) ; + UHD_LOGGER_TRACE("TVRX") << boost::format("TVRX2 (%s): POR %d") + % (get_subdev_name()) + % int(_tda18272hnm_regs.por); return por; } @@ -827,15 +845,15 @@ private: * Get the lock detect status of the LO. * \return sensor for locked */ - sensor_value_t get_locked(void){ + sensor_value_t get_locked(void) + { read_reg(0x5, 0x5); - //return lock detect + // return lock detect bool locked = _tda18272hnm_regs.lo_lock == tda18272hnm_regs_t::LO_LOCK_LOCKED; - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): locked %d" - ) % (get_subdev_name()) % locked ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s): locked %d") % (get_subdev_name()) % locked; return sensor_value_t("LO", locked, "locked", "unlocked"); } @@ -845,21 +863,26 @@ private: * Read the RSSI from the aux adc * \return the rssi sensor in dB(m?) FIXME */ - sensor_value_t get_rssi(void){ - //Launch RSSI calculation with MSM statemachine - _tda18272hnm_regs.set_reg(0x19, 0x80); //set MSM_byte_1 for rssi calculation - _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching rssi calculation + sensor_value_t get_rssi(void) + { + // Launch RSSI calculation with MSM statemachine + _tda18272hnm_regs.set_reg(0x19, 0x80); // set MSM_byte_1 for rssi calculation + _tda18272hnm_regs.set_reg( + 0x1A, 0x01); // set MSM_byte_2 for launching rssi calculation send_reg(0x19, 0x1A); wait_irq(); - //read rssi in dBuV + // read rssi in dBuV read_reg(0x7, 0x7); - //calculate the rssi from the voltage - double rssi_dBuV = 40.0 + double(((110.0 - 40.0)/128.0) * _tda18272hnm_regs.get_reg(0x7)); - double rssi = rssi_dBuV - 107.0; //convert to dBm in 50ohm environment ( -108.8 if 75ohm ) FIXME + // calculate the rssi from the voltage + double rssi_dBuV = + 40.0 + double(((110.0 - 40.0) / 128.0) * _tda18272hnm_regs.get_reg(0x7)); + double rssi = + rssi_dBuV + - 107.0; // convert to dBm in 50ohm environment ( -108.8 if 75ohm ) FIXME return sensor_value_t("RSSI", rssi, "dBm"); } @@ -868,19 +891,20 @@ private: * Read the Temperature from the registers * \return the temp in degC */ - sensor_value_t get_temp(void){ - //Enable Temperature reading + sensor_value_t get_temp(void) + { + // Enable Temperature reading _tda18272hnm_regs.tm_on = tda18272hnm_regs_t::TM_ON_SENSOR_ON; send_reg(0x4, 0x4); - //read temp in degC + // read temp in degC read_reg(0x3, 0x3); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): Temperature %f C" - ) % (get_subdev_name()) % (double(_tda18272hnm_regs.tm_d)) ; + UHD_LOGGER_TRACE("TVRX") << boost::format("TVRX2 (%s): Temperature %f C") + % (get_subdev_name()) + % (double(_tda18272hnm_regs.tm_d)); - //Disable Temperature reading + // Disable Temperature reading _tda18272hnm_regs.tm_on = tda18272hnm_regs_t::TM_ON_SENSOR_OFF; send_reg(0x4, 0x4); @@ -891,194 +915,205 @@ private: /*********************************************************************** * Register the TVRX2 dboard **********************************************************************/ -static dboard_base::sptr make_tvrx2(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_tvrx2(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new tvrx2(args)); } -UHD_STATIC_BLOCK(reg_tvrx2_dboard){ - //register the factory function for the rx dbid - dboard_manager::register_dboard(0x0046, &make_tvrx2, "TVRX2", tvrx2_sd_name_to_conn.keys()); +UHD_STATIC_BLOCK(reg_tvrx2_dboard) +{ + // register the factory function for the rx dbid + dboard_manager::register_dboard( + 0x0046, &make_tvrx2, "TVRX2", tvrx2_sd_name_to_conn.keys()); } /*********************************************************************** * Structors **********************************************************************/ -tvrx2::tvrx2(ctor_args_t args) : rx_dboard_base(args){ - //FIXME for USRP1, we can only support one TVRX2 installed - - _rfcal_results = map_list_of - ( 0, tvrx2_tda18272_rfcal_result_t() ) - ( 1, tvrx2_tda18272_rfcal_result_t() ) - ( 2, tvrx2_tda18272_rfcal_result_t() ) - ( 3, tvrx2_tda18272_rfcal_result_t() ) - ( 4, tvrx2_tda18272_rfcal_result_t() ) - ( 5, tvrx2_tda18272_rfcal_result_t() ) - ( 6, tvrx2_tda18272_rfcal_result_t() ) - ( 7, tvrx2_tda18272_rfcal_result_t() ) - ( 8, tvrx2_tda18272_rfcal_result_t() ) - ( 9, tvrx2_tda18272_rfcal_result_t() ) - ( 10, tvrx2_tda18272_rfcal_result_t() ) - ( 11, tvrx2_tda18272_rfcal_result_t() ) - ; - - _rfcal_coeffs = map_list_of - ( 0, tvrx2_tda18272_rfcal_coeffs_t(0) ) - ( 1, tvrx2_tda18272_rfcal_coeffs_t(1) ) - ( 2, tvrx2_tda18272_rfcal_coeffs_t(3) ) - ( 3, tvrx2_tda18272_rfcal_coeffs_t(4) ) - ( 4, tvrx2_tda18272_rfcal_coeffs_t(6) ) - ( 5, tvrx2_tda18272_rfcal_coeffs_t(7) ) - ( 6, tvrx2_tda18272_rfcal_coeffs_t(9) ) - ( 7, tvrx2_tda18272_rfcal_coeffs_t(10) ) - ; - - //set defaults for LO, gains, and filter bandwidth +tvrx2::tvrx2(ctor_args_t args) : rx_dboard_base(args) +{ + // FIXME for USRP1, we can only support one TVRX2 installed + + _rfcal_results = map_list_of(0, tvrx2_tda18272_rfcal_result_t())( + 1, tvrx2_tda18272_rfcal_result_t())(2, tvrx2_tda18272_rfcal_result_t())( + 3, tvrx2_tda18272_rfcal_result_t())(4, tvrx2_tda18272_rfcal_result_t())( + 5, tvrx2_tda18272_rfcal_result_t())(6, tvrx2_tda18272_rfcal_result_t())( + 7, tvrx2_tda18272_rfcal_result_t())(8, tvrx2_tda18272_rfcal_result_t())( + 9, tvrx2_tda18272_rfcal_result_t())(10, tvrx2_tda18272_rfcal_result_t())( + 11, tvrx2_tda18272_rfcal_result_t()); + + _rfcal_coeffs = map_list_of(0, tvrx2_tda18272_rfcal_coeffs_t(0))( + 1, tvrx2_tda18272_rfcal_coeffs_t(1))(2, tvrx2_tda18272_rfcal_coeffs_t(3))( + 3, tvrx2_tda18272_rfcal_coeffs_t(4))(4, tvrx2_tda18272_rfcal_coeffs_t(6))( + 5, tvrx2_tda18272_rfcal_coeffs_t(7))(6, tvrx2_tda18272_rfcal_coeffs_t(9))( + 7, tvrx2_tda18272_rfcal_coeffs_t(10)); + + // set defaults for LO, gains, and filter bandwidth _bandwidth = 10e6; _if_freq = 12.5e6; _enabled = false; - //send initial register settings - //this->read_reg(0x0, 0x43); - //this->send_reg(0x0, 0x43); + // send initial register settings + // this->read_reg(0x0, 0x43); + // this->send_reg(0x0, 0x43); - //send magic xtal_cal_dac setting + // send magic xtal_cal_dac setting send_reg(0x65, 0x65); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - this->get_rx_subtree()->create<std::string>("name") - .set("TVRX2"); - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_rx_subtree()->create<std::string>("name").set("TVRX2"); + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&tvrx2::get_locked, this)); - this->get_rx_subtree()->create<sensor_value_t>("sensors/rssi") + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/rssi") .set_publisher(std::bind(&tvrx2::get_rssi, this)); - this->get_rx_subtree()->create<sensor_value_t>("sensors/temperature") + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/temperature") .set_publisher(std::bind(&tvrx2::get_temp, this)); - for(const std::string &name: tvrx2_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") + for (const std::string& name : tvrx2_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") .set_coercer(std::bind(&tvrx2::set_gain, this, std::placeholders::_1, name)); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(tvrx2_gain_ranges[name]); } - this->get_rx_subtree()->create<double>("freq/value") + this->get_rx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&tvrx2::set_lo_freq, this, std::placeholders::_1)); - this->get_rx_subtree()->create<meta_range_t>("freq/range") - .set(tvrx2_freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") + this->get_rx_subtree()->create<meta_range_t>("freq/range").set(tvrx2_freq_range); + this->get_rx_subtree() + ->create<std::string>("antenna/value") .set(tvrx2_sd_name_to_antennas[get_subdev_name()]); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(list_of(tvrx2_sd_name_to_antennas[get_subdev_name()])); - this->get_rx_subtree()->create<std::string>("connection") + this->get_rx_subtree() + ->create<std::string>("connection") .set(tvrx2_sd_name_to_conn[get_subdev_name()]); - this->get_rx_subtree()->create<bool>("enabled") + this->get_rx_subtree() + ->create<bool>("enabled") .set_coercer(std::bind(&tvrx2::set_enabled, this, std::placeholders::_1)) .set(_enabled); - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_rx_subtree()->create<double>("bandwidth/value") + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_rx_subtree() + ->create<double>("bandwidth/value") .set_coercer(std::bind(&tvrx2::set_bandwidth, this, std::placeholders::_1)) .set(_bandwidth); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(tvrx2_bandwidth_range); - //set the gpio directions and atr controls (identically) + // set the gpio directions and atr controls (identically) this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0); // All unused in atr this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, OUTPUT_MASK); // Set outputs - //configure ref_clock + // configure ref_clock double ref_clock = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); if (ref_clock == 64.0e6) { this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, REFCLOCK_DIV4); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): Dividing Refclock by 4" - ) % (get_subdev_name()) ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s): Dividing Refclock by 4") % (get_subdev_name()); - _freq_scalar = (4*16.0e6)/(this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)); + _freq_scalar = + (4 * 16.0e6) / (this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)); } else if (ref_clock == 100e6) { - this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, REFCLOCK_DIV6); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): Dividing Refclock by 6" - ) % (get_subdev_name()) ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s): Dividing Refclock by 6") % (get_subdev_name()); - _freq_scalar = (6*16.0e6)/this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); - } else if (ref_clock == 200e6) { - UHD_LOGGER_WARNING("TVRX") << boost::format("ref_clock was 200e6, setting ref_clock divider for 100e6.") ; + _freq_scalar = + (6 * 16.0e6) / this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); + } else if (ref_clock == 200e6) { + UHD_LOGGER_WARNING("TVRX") + << boost::format("ref_clock was 200e6, setting ref_clock divider for 100e6."); this->get_iface()->set_clock_rate(dboard_iface::UNIT_RX, 100e6); this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, REFCLOCK_DIV6); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): Dividing Refclock by 6" - ) % (get_subdev_name()) ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s): Dividing Refclock by 6") % (get_subdev_name()); - _freq_scalar = (6*16.0e6)/this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); + _freq_scalar = + (6 * 16.0e6) / this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); } else { this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, REFCLOCK_DIV6); - UHD_LOGGER_WARNING("TVRX") << boost::format("Unsupported ref_clock %0.2f, valid options 64e6, 100e6, 200e6") % ref_clock ; + UHD_LOGGER_WARNING("TVRX") + << boost::format( + "Unsupported ref_clock %0.2f, valid options 64e6, 100e6, 200e6") + % ref_clock; _freq_scalar = 1.0; } - //enable only the clocks we need + // enable only the clocks we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): Refclock %f Hz, scalar = %f" - ) % (get_subdev_name()) % (this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)) % _freq_scalar ; + UHD_LOGGER_TRACE("TVRX") << boost::format("TVRX2 (%s): Refclock %f Hz, scalar = %f") + % (get_subdev_name()) + % (this->get_iface()->get_clock_rate( + dboard_iface::UNIT_RX)) + % _freq_scalar; _tda18272hnm_regs.irq_polarity = tda18272hnm_regs_t::IRQ_POLARITY_RAISED_VCC; - _tda18272hnm_regs.irq_clear = tda18272hnm_regs_t::IRQ_CLEAR_TRUE; + _tda18272hnm_regs.irq_clear = tda18272hnm_regs_t::IRQ_CLEAR_TRUE; send_reg(0x37, 0x37); send_reg(0xA, 0xA); - send_reg(0x31, 0x31); //N_CP_Current - send_reg(0x36, 0x36); //RSSI_Clock - send_reg(0x24, 0x25); //AGC1_Do_step - send_reg(0x2C, 0x2C); //AGC1_Do_step - send_reg(0x2E, 0x2E); //AGC2_Do_step - send_reg(0x0E, 0x0E); //AGCs_Up_step_assym - send_reg(0x11, 0x11); //AGCs_Do_step_assym - - //intialize i2c - //soft_calibration(); - //tvrx2_tda18272_init_rfcal(); + send_reg(0x31, 0x31); // N_CP_Current + send_reg(0x36, 0x36); // RSSI_Clock + send_reg(0x24, 0x25); // AGC1_Do_step + send_reg(0x2C, 0x2C); // AGC1_Do_step + send_reg(0x2E, 0x2E); // AGC2_Do_step + send_reg(0x0E, 0x0E); // AGCs_Up_step_assym + send_reg(0x11, 0x11); // AGCs_Do_step_assym + + // intialize i2c + // soft_calibration(); + // tvrx2_tda18272_init_rfcal(); transition_0(); } -bool tvrx2::set_enabled(bool enable){ - if (enable == _enabled) return _enabled; +bool tvrx2::set_enabled(bool enable) +{ + if (enable == _enabled) + return _enabled; - if (enable and not _enabled){ - //setup tuner parameters + if (enable and not _enabled) { + // setup tuner parameters transition_1(); transition_2(int(tvrx2_freq_range.start())); test_rf_filter_robustness(); - for(const std::string &name: tvrx2_gain_ranges.keys()){ - this->get_rx_subtree()->access<double>("gains/"+name+"/value") + for (const std::string& name : tvrx2_gain_ranges.keys()) { + this->get_rx_subtree() + ->access<double>("gains/" + name + "/value") .set(tvrx2_gain_ranges[name].start()); } - this->get_rx_subtree()->access<double>("bandwidth/value") + this->get_rx_subtree() + ->access<double>("bandwidth/value") .set(_bandwidth); // default bandwidth from datasheet - //transition_2 equivalent - this->get_rx_subtree()->access<double>("freq/value") + // transition_2 equivalent + this->get_rx_subtree() + ->access<double>("freq/value") .set(tvrx2_freq_range.start()); - //enter standby mode + // enter standby mode transition_3(); _enabled = true; } else { - //enter standby mode + // enter standby mode transition_3(); _enabled = false; } @@ -1086,10 +1121,10 @@ bool tvrx2::set_enabled(bool enable){ return _enabled; } -tvrx2::~tvrx2(void){ - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): Called Destructor" - ) % (get_subdev_name()) ; +tvrx2::~tvrx2(void) +{ + UHD_LOGGER_TRACE("TVRX") << boost::format("TVRX2 (%s): Called Destructor") + % (get_subdev_name()); UHD_SAFE_CALL(if (_enabled) set_enabled(false);) } @@ -1097,84 +1132,101 @@ tvrx2::~tvrx2(void){ /*********************************************************************** * TDA18272 Register IO Functions **********************************************************************/ -void tvrx2::set_scaled_rf_freq(double rf_freq){ - _tda18272hnm_regs.set_rf_freq(uint32_t(_freq_scalar*rf_freq/1e3)); +void tvrx2::set_scaled_rf_freq(double rf_freq) +{ + _tda18272hnm_regs.set_rf_freq(uint32_t(_freq_scalar * rf_freq / 1e3)); } -double tvrx2::get_scaled_rf_freq(void){ - return _tda18272hnm_regs.get_rf_freq()*1e3/_freq_scalar; +double tvrx2::get_scaled_rf_freq(void) +{ + return _tda18272hnm_regs.get_rf_freq() * 1e3 / _freq_scalar; } -void tvrx2::set_scaled_if_freq(double if_freq){ - _tda18272hnm_regs.if_freq = int(_freq_scalar*if_freq/(50e3)); //max 12.8MHz?? +void tvrx2::set_scaled_if_freq(double if_freq) +{ + _tda18272hnm_regs.if_freq = int(_freq_scalar * if_freq / (50e3)); // max 12.8MHz?? } -double tvrx2::get_scaled_if_freq(void){ - return _tda18272hnm_regs.if_freq*50e3/_freq_scalar; +double tvrx2::get_scaled_if_freq(void) +{ + return _tda18272hnm_regs.if_freq * 50e3 / _freq_scalar; } -void tvrx2::send_reg(uint8_t start_reg, uint8_t stop_reg){ +void tvrx2::send_reg(uint8_t start_reg, uint8_t stop_reg) +{ start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0x43)); - stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x43)); + stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x43)); - for(uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(uint32_t) - 1){ - int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) - 1 ? sizeof(uint32_t) - 1 : stop_reg - start_addr + 1; + for (uint8_t start_addr = start_reg; start_addr <= stop_reg; + start_addr += sizeof(uint32_t) - 1) { + int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) - 1 + ? sizeof(uint32_t) - 1 + : stop_reg - start_addr + 1; - //create buffer for register data (+1 for start address) + // create buffer for register data (+1 for start address) byte_vector_t regs_vector(num_bytes + 1); - //first byte is the address of first register + // first byte is the address of first register regs_vector[0] = start_addr; - //get the register data - for(int i=0; i<num_bytes; i++){ - regs_vector[1+i] = _tda18272hnm_regs.get_reg(start_addr+i); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s, 0x%02x): send reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d" - ) % (get_subdev_name()) % int(tvrx2_sd_name_to_i2c_addr[get_subdev_name()]) % int(start_addr+i) % int(regs_vector[1+i]) % int(start_addr) % num_bytes ; + // get the register data + for (int i = 0; i < num_bytes; i++) { + regs_vector[1 + i] = _tda18272hnm_regs.get_reg(start_addr + i); + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s, 0x%02x): send reg 0x%02x, value 0x%04x, " + "start_addr = 0x%04x, num_bytes %d") + % (get_subdev_name()) + % int(tvrx2_sd_name_to_i2c_addr[get_subdev_name()]) + % int(start_addr + i) % int(regs_vector[1 + i]) % int(start_addr) + % num_bytes; } - //send the data + // send the data this->get_iface()->write_i2c( - tvrx2_sd_name_to_i2c_addr[get_subdev_name()], regs_vector - ); + tvrx2_sd_name_to_i2c_addr[get_subdev_name()], regs_vector); } } -void tvrx2::read_reg(uint8_t start_reg, uint8_t stop_reg){ +void tvrx2::read_reg(uint8_t start_reg, uint8_t stop_reg) +{ static const uint8_t status_addr = 0x0; - start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0x43)); - stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x43)); + start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0x43)); + stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x43)); - for(uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(uint32_t)){ - int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) ? sizeof(uint32_t) : stop_reg - start_addr + 1; + for (uint8_t start_addr = start_reg; start_addr <= stop_reg; + start_addr += sizeof(uint32_t)) { + int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) + ? sizeof(uint32_t) + : stop_reg - start_addr + 1; - //create buffer for starting address + // create buffer for starting address byte_vector_t start_address_vector(1); - //first byte is the address of first register + // first byte is the address of first register start_address_vector[0] = start_addr; - //send the start address + // send the start address this->get_iface()->write_i2c( - tvrx2_sd_name_to_i2c_addr[get_subdev_name()], start_address_vector - ); + tvrx2_sd_name_to_i2c_addr[get_subdev_name()], start_address_vector); - //create buffer for register data + // create buffer for register data byte_vector_t regs_vector(num_bytes); - //read from i2c + // read from i2c regs_vector = this->get_iface()->read_i2c( - tvrx2_sd_name_to_i2c_addr[get_subdev_name()], num_bytes - ); + tvrx2_sd_name_to_i2c_addr[get_subdev_name()], num_bytes); - for(uint8_t i=0; i < num_bytes; i++){ - if (i + start_addr >= status_addr){ + for (uint8_t i = 0; i < num_bytes; i++) { + if (i + start_addr >= status_addr) { _tda18272hnm_regs.set_reg(i + start_addr, regs_vector[i]); } - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s, 0x%02x): read reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d" - ) % (get_subdev_name()) % int(tvrx2_sd_name_to_i2c_addr[get_subdev_name()]) % int(start_addr+i) % int(regs_vector[i]) % int(start_addr) % num_bytes ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s, 0x%02x): read reg 0x%02x, value 0x%04x, " + "start_addr = 0x%04x, num_bytes %d") + % (get_subdev_name()) + % int(tvrx2_sd_name_to_i2c_addr[get_subdev_name()]) + % int(start_addr + i) % int(regs_vector[i]) % int(start_addr) + % num_bytes; } } } @@ -1185,56 +1237,65 @@ void tvrx2::read_reg(uint8_t start_reg, uint8_t stop_reg){ **********************************************************************/ freq_range_t tvrx2::get_tda18272_rfcal_result_freq_range(uint32_t result) { - - uhd::dict<uint32_t, freq_range_t> result_to_cal_freq_ranges_map = map_list_of - ( 0, freq_range_t( - (double) tvrx2_tda18272_cal_map[0].cal_freq[_tda18272hnm_regs.rfcal_freq0] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[1].cal_freq[_tda18272hnm_regs.rfcal_freq1] * _freq_scalar - ) ) - ( 1, freq_range_t( - (double) tvrx2_tda18272_cal_map[1].cal_freq[_tda18272hnm_regs.rfcal_freq1] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[2].cal_freq[_tda18272hnm_regs.rfcal_freq2] * _freq_scalar - ) ) - ( 2, freq_range_t( - (double) tvrx2_tda18272_cal_map[2].cal_freq[_tda18272hnm_regs.rfcal_freq2] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[3].cal_freq[_tda18272hnm_regs.rfcal_freq3] * _freq_scalar - ) ) - ( 3, freq_range_t( - (double) tvrx2_tda18272_cal_map[3].cal_freq[_tda18272hnm_regs.rfcal_freq3] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[4].cal_freq[_tda18272hnm_regs.rfcal_freq4] * _freq_scalar - ) ) - ( 4, freq_range_t( - (double) tvrx2_tda18272_cal_map[4].cal_freq[_tda18272hnm_regs.rfcal_freq4] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[5].cal_freq[_tda18272hnm_regs.rfcal_freq5] * _freq_scalar - ) ) - ( 5, freq_range_t( - (double) tvrx2_tda18272_cal_map[5].cal_freq[_tda18272hnm_regs.rfcal_freq5] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[6].cal_freq[_tda18272hnm_regs.rfcal_freq6] * _freq_scalar - ) ) - ( 6, freq_range_t( - (double) tvrx2_tda18272_cal_map[6].cal_freq[_tda18272hnm_regs.rfcal_freq6] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[7].cal_freq[_tda18272hnm_regs.rfcal_freq7] * _freq_scalar - ) ) - ( 7, freq_range_t( - (double) tvrx2_tda18272_cal_map[7].cal_freq[_tda18272hnm_regs.rfcal_freq7] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[8].cal_freq[_tda18272hnm_regs.rfcal_freq8] * _freq_scalar - ) ) - ( 8, freq_range_t( - (double) tvrx2_tda18272_cal_map[8].cal_freq[_tda18272hnm_regs.rfcal_freq8] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[9].cal_freq[_tda18272hnm_regs.rfcal_freq9] * _freq_scalar - ) ) - ( 9, freq_range_t( - (double) tvrx2_tda18272_cal_map[9].cal_freq[_tda18272hnm_regs.rfcal_freq9] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[10].cal_freq[_tda18272hnm_regs.rfcal_freq10] * _freq_scalar - ) ) - (10, freq_range_t( - (double) tvrx2_tda18272_cal_map[10].cal_freq[_tda18272hnm_regs.rfcal_freq10] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[11].cal_freq[_tda18272hnm_regs.rfcal_freq11] * _freq_scalar - ) ) - ; + uhd::dict<uint32_t, freq_range_t> result_to_cal_freq_ranges_map = map_list_of(0, + freq_range_t( + (double)tvrx2_tda18272_cal_map[0].cal_freq[_tda18272hnm_regs.rfcal_freq0] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[1].cal_freq[_tda18272hnm_regs.rfcal_freq1] + * _freq_scalar))(1, + freq_range_t( + (double)tvrx2_tda18272_cal_map[1].cal_freq[_tda18272hnm_regs.rfcal_freq1] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[2].cal_freq[_tda18272hnm_regs.rfcal_freq2] + * _freq_scalar))(2, + freq_range_t( + (double)tvrx2_tda18272_cal_map[2].cal_freq[_tda18272hnm_regs.rfcal_freq2] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[3].cal_freq[_tda18272hnm_regs.rfcal_freq3] + * _freq_scalar))(3, + freq_range_t( + (double)tvrx2_tda18272_cal_map[3].cal_freq[_tda18272hnm_regs.rfcal_freq3] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[4].cal_freq[_tda18272hnm_regs.rfcal_freq4] + * _freq_scalar))(4, + freq_range_t( + (double)tvrx2_tda18272_cal_map[4].cal_freq[_tda18272hnm_regs.rfcal_freq4] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[5].cal_freq[_tda18272hnm_regs.rfcal_freq5] + * _freq_scalar))(5, + freq_range_t( + (double)tvrx2_tda18272_cal_map[5].cal_freq[_tda18272hnm_regs.rfcal_freq5] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[6].cal_freq[_tda18272hnm_regs.rfcal_freq6] + * _freq_scalar))(6, + freq_range_t( + (double)tvrx2_tda18272_cal_map[6].cal_freq[_tda18272hnm_regs.rfcal_freq6] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[7].cal_freq[_tda18272hnm_regs.rfcal_freq7] + * _freq_scalar))(7, + freq_range_t( + (double)tvrx2_tda18272_cal_map[7].cal_freq[_tda18272hnm_regs.rfcal_freq7] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[8].cal_freq[_tda18272hnm_regs.rfcal_freq8] + * _freq_scalar))(8, + freq_range_t( + (double)tvrx2_tda18272_cal_map[8].cal_freq[_tda18272hnm_regs.rfcal_freq8] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[9].cal_freq[_tda18272hnm_regs.rfcal_freq9] + * _freq_scalar))(9, + freq_range_t( + (double)tvrx2_tda18272_cal_map[9].cal_freq[_tda18272hnm_regs.rfcal_freq9] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[10].cal_freq[_tda18272hnm_regs.rfcal_freq10] + * _freq_scalar))(10, + freq_range_t( + (double)tvrx2_tda18272_cal_map[10].cal_freq[_tda18272hnm_regs.rfcal_freq10] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[11].cal_freq[_tda18272hnm_regs.rfcal_freq11] + * _freq_scalar)); if (result < 11) - return result_to_cal_freq_ranges_map[result]; + return result_to_cal_freq_ranges_map[result]; else return freq_range_t(0.0, 0.0); } @@ -1245,53 +1306,52 @@ freq_range_t tvrx2::get_tda18272_rfcal_result_freq_range(uint32_t result) */ void tvrx2::tvrx2_tda18272_init_rfcal(void) { - /* read byte 0x38-0x43 */ read_reg(0x38, 0x43); - uhd::dict<uint32_t, uint8_t> result_to_cal_regs = map_list_of - ( 0, _tda18272hnm_regs.rfcal_log_1) - ( 1, _tda18272hnm_regs.rfcal_log_2) - ( 2, _tda18272hnm_regs.rfcal_log_3) - ( 3, _tda18272hnm_regs.rfcal_log_4) - ( 4, _tda18272hnm_regs.rfcal_log_5) - ( 5, _tda18272hnm_regs.rfcal_log_6) - ( 6, _tda18272hnm_regs.rfcal_log_7) - ( 7, _tda18272hnm_regs.rfcal_log_8) - ( 8, _tda18272hnm_regs.rfcal_log_9) - ( 9, _tda18272hnm_regs.rfcal_log_10) - (10, _tda18272hnm_regs.rfcal_log_11) - (11, _tda18272hnm_regs.rfcal_log_12) - ; + uhd::dict<uint32_t, uint8_t> result_to_cal_regs = + map_list_of(0, _tda18272hnm_regs.rfcal_log_1)(1, _tda18272hnm_regs.rfcal_log_2)( + 2, _tda18272hnm_regs.rfcal_log_3)(3, _tda18272hnm_regs.rfcal_log_4)( + 4, _tda18272hnm_regs.rfcal_log_5)(5, _tda18272hnm_regs.rfcal_log_6)( + 6, _tda18272hnm_regs.rfcal_log_7)(7, _tda18272hnm_regs.rfcal_log_8)( + 8, _tda18272hnm_regs.rfcal_log_9)(9, _tda18272hnm_regs.rfcal_log_10)( + 10, _tda18272hnm_regs.rfcal_log_11)(11, _tda18272hnm_regs.rfcal_log_12); // Loop through rfcal_log_* registers, initialize _rfcal_results - for(const uint32_t &result: result_to_cal_regs.keys()) - _rfcal_results[result].delta_c = result_to_cal_regs[result] > 63 ? result_to_cal_regs[result] - 128 : result_to_cal_regs[result]; + for (const uint32_t& result : result_to_cal_regs.keys()) + _rfcal_results[result].delta_c = result_to_cal_regs[result] > 63 + ? result_to_cal_regs[result] - 128 + : result_to_cal_regs[result]; /* read byte 0x26-0x2B */ read_reg(0x26, 0x2B); // Loop through rfcal_byte_* registers, initialize _rfcal_coeffs - for(const uint32_t &subband: _rfcal_coeffs.keys()) - { + for (const uint32_t& subband : _rfcal_coeffs.keys()) { freq_range_t subband_freqs; uint32_t result = _rfcal_coeffs[subband].cal_number; subband_freqs = get_tda18272_rfcal_result_freq_range(result); - _rfcal_coeffs[subband].RF_B1 = _rfcal_results[result].delta_c + tvrx2_tda18272_cal_map[result].c_offset[_rfcal_results[result].c_offset]; + _rfcal_coeffs[subband].RF_B1 = + _rfcal_results[result].delta_c + + tvrx2_tda18272_cal_map[result].c_offset[_rfcal_results[result].c_offset]; - uint32_t quotient = (((_rfcal_results[result+1].delta_c + tvrx2_tda18272_cal_map[result+1].c_offset[_rfcal_results[result].c_offset]) - - (_rfcal_results[result].delta_c + tvrx2_tda18272_cal_map[result].c_offset[_rfcal_results[result].c_offset])) * 1000000); + uint32_t quotient = (((_rfcal_results[result + 1].delta_c + + tvrx2_tda18272_cal_map[result + 1] + .c_offset[_rfcal_results[result].c_offset]) + - (_rfcal_results[result].delta_c + + tvrx2_tda18272_cal_map[result] + .c_offset[_rfcal_results[result].c_offset])) + * 1000000); - uint32_t divisor = ((int32_t)(subband_freqs.stop() - subband_freqs.start())/1000); + uint32_t divisor = + ((int32_t)(subband_freqs.stop() - subband_freqs.start()) / 1000); _rfcal_coeffs[subband].RF_A1 = quotient / divisor; - } - } /* @@ -1299,97 +1359,101 @@ void tvrx2::tvrx2_tda18272_init_rfcal(void) */ void tvrx2::tvrx2_tda18272_tune_rf_filter(uint32_t uRF) { - uint32_t uCounter = 0; - uint8_t cal_result = 0; - uint32_t uRFCal0 = 0; - uint32_t uRFCal1 = 0; - uint8_t subband = 0; - int32_t cProg = 0; - uint8_t gain_taper = 0; - uint8_t RFBand = 0; - int32_t RF_A1 = 0; - int32_t RF_B1 = 0; - freq_range_t subband_freqs; + uint32_t uCounter = 0; + uint8_t cal_result = 0; + uint32_t uRFCal0 = 0; + uint32_t uRFCal1 = 0; + uint8_t subband = 0; + int32_t cProg = 0; + uint8_t gain_taper = 0; + uint8_t RFBand = 0; + int32_t RF_A1 = 0; + int32_t RF_B1 = 0; + freq_range_t subband_freqs; /* read byte 0x26-0x2B */ read_reg(0x26, 0x2B); subband_freqs = get_tda18272_rfcal_result_freq_range(1); - uRFCal0 = uint32_t(subband_freqs.start()); + uRFCal0 = uint32_t(subband_freqs.start()); subband_freqs = get_tda18272_rfcal_result_freq_range(4); - uRFCal1 = uint32_t(subband_freqs.start()); + uRFCal1 = uint32_t(subband_freqs.start()); - if(uRF < uRFCal0) + if (uRF < uRFCal0) subband = 0; - else if(uRF < 145700000) + else if (uRF < 145700000) subband = 1; - else if(uRF < uRFCal1) + else if (uRF < uRFCal1) subband = 2; - else if(uRF < 367400000) + else if (uRF < 367400000) subband = 3; - else - { + else { subband_freqs = get_tda18272_rfcal_result_freq_range(7); - uRFCal0 = uint32_t(subband_freqs.start()); + uRFCal0 = uint32_t(subband_freqs.start()); subband_freqs = get_tda18272_rfcal_result_freq_range(10); - uRFCal1 = uint32_t(subband_freqs.start()); + uRFCal1 = uint32_t(subband_freqs.start()); - if(uRF < uRFCal0) + if (uRF < uRFCal0) subband = 4; - else if(uRF < 625000000) + else if (uRF < 625000000) subband = 5; - else if(uRF < uRFCal1) + else if (uRF < uRFCal1) subband = 6; else subband = 7; } - cal_result = _rfcal_coeffs[subband].cal_number; + cal_result = _rfcal_coeffs[subband].cal_number; subband_freqs = get_tda18272_rfcal_result_freq_range(cal_result); - uRFCal0 = uint32_t(subband_freqs.start()); + uRFCal0 = uint32_t(subband_freqs.start()); RF_A1 = _rfcal_coeffs[subband].RF_A1; RF_B1 = _rfcal_coeffs[subband].RF_B1; uCounter = 0; - do uCounter ++; - while (uRF >= tvrx2_tda18272_freq_map[uCounter].rf_max && uCounter < TVRX2_TDA18272_FREQ_MAP_ENTRIES); + do + uCounter++; + while (uRF >= tvrx2_tda18272_freq_map[uCounter].rf_max + && uCounter < TVRX2_TDA18272_FREQ_MAP_ENTRIES); - cProg = tvrx2_tda18272_freq_map[uCounter - 1].c_prog; + cProg = tvrx2_tda18272_freq_map[uCounter - 1].c_prog; gain_taper = tvrx2_tda18272_freq_map[uCounter - 1].gain_taper; - RFBand = tvrx2_tda18272_freq_map[uCounter - 1].rf_band; + RFBand = tvrx2_tda18272_freq_map[uCounter - 1].rf_band; - cProg = (int32_t)(cProg + RF_B1 + (RF_A1*((int32_t)(uRF - uRFCal0)/1000))/1000000); + cProg = + (int32_t)(cProg + RF_B1 + (RF_A1 * ((int32_t)(uRF - uRFCal0) / 1000)) / 1000000); - if(cProg>255) cProg = 255; - if(cProg<0) cProg = 0; + if (cProg > 255) + cProg = 255; + if (cProg < 0) + cProg = 0; _tda18272hnm_regs.rf_filter_bypass = 1; - _tda18272hnm_regs.rf_filter_cap = (uint8_t) cProg; - _tda18272hnm_regs.gain_taper = gain_taper; - _tda18272hnm_regs.rf_filter_band = RFBand; - - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Software Calibration:\n" - "\tRF Filter Bypass = %d\n" - "\tRF Filter Cap = %d\n" - "\tRF Filter Band = %d\n" - "\tGain Taper = %d\n") - % (get_subdev_name()) - % int(_tda18272hnm_regs.rf_filter_bypass) - % int(_tda18272hnm_regs.rf_filter_cap) - % int(_tda18272hnm_regs.rf_filter_band) - % int(_tda18272hnm_regs.gain_taper) - ; + _tda18272hnm_regs.rf_filter_cap = (uint8_t)cProg; + _tda18272hnm_regs.gain_taper = gain_taper; + _tda18272hnm_regs.rf_filter_band = RFBand; + + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): Software Calibration:\n" + "\tRF Filter Bypass = %d\n" + "\tRF Filter Cap = %d\n" + "\tRF Filter Band = %d\n" + "\tGain Taper = %d\n") + % (get_subdev_name()) + % int(_tda18272hnm_regs.rf_filter_bypass) + % int(_tda18272hnm_regs.rf_filter_cap) + % int(_tda18272hnm_regs.rf_filter_band) + % int(_tda18272hnm_regs.gain_taper); send_reg(0x2c, 0x2f); } -void tvrx2::soft_calibration(void){ - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Software Calibration: Initialize Tuner, Calibrate and Standby\n") % (get_subdev_name()) ; +void tvrx2::soft_calibration(void) +{ + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): Software Calibration: " + "Initialize Tuner, Calibrate and Standby\n") + % (get_subdev_name()); - _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL; + _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL; _tda18272hnm_regs.sm_lna = tda18272hnm_regs_t::SM_LNA_ON; _tda18272hnm_regs.sm_pll = tda18272hnm_regs_t::SM_PLL_ON; @@ -1414,20 +1478,20 @@ void tvrx2::soft_calibration(void){ send_reg(0x26, 0x2B); - _tda18272hnm_regs.set_reg(0x19, 0x3B); //set MSM_byte_1 for calibration per datasheet - _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching calibration + _tda18272hnm_regs.set_reg(0x19, 0x3B); // set MSM_byte_1 for calibration per datasheet + _tda18272hnm_regs.set_reg(0x1A, 0x01); // set MSM_byte_2 for launching calibration send_reg(0x19, 0x1A); wait_irq(); - send_reg(0x1D, 0x1D); //Fmax_LO - send_reg(0x0C, 0x0C); //LT_Enable - send_reg(0x1B, 0x1B); //PSM_AGC1 - send_reg(0x0C, 0x0C); //AGC1_6_15dB + send_reg(0x1D, 0x1D); // Fmax_LO + send_reg(0x0C, 0x0C); // LT_Enable + send_reg(0x1B, 0x1B); // PSM_AGC1 + send_reg(0x0C, 0x0C); // AGC1_6_15dB - //set spread spectrum for clock - //FIXME: NXP turns clock spread on and off + // set spread spectrum for clock + // FIXME: NXP turns clock spread on and off // based on where clock spurs would be relative to RF frequency // we should do this also _tda18272hnm_regs.digital_clock = tda18272hnm_regs_t::DIGITAL_CLOCK_SPREAD_OFF; @@ -1437,18 +1501,19 @@ void tvrx2::soft_calibration(void){ else //_tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_NO; _tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_16MHZ; - + send_reg(0x14, 0x14); - _tda18272hnm_regs.set_reg(0x36, 0x0E); //sets clock mode + _tda18272hnm_regs.set_reg(0x36, 0x0E); // sets clock mode send_reg(0x36, 0x36); - //go to standby mode + // go to standby mode _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_STANDBY; send_reg(0x6, 0x6); } -void tvrx2::test_rf_filter_robustness(void){ +void tvrx2::test_rf_filter_robustness(void) +{ typedef uhd::dict<std::string, std::string> tvrx2_filter_ratings_t; typedef uhd::dict<std::string, double> tvrx2_filter_margins_t; @@ -1457,62 +1522,123 @@ void tvrx2::test_rf_filter_robustness(void){ read_reg(0x38, 0x43); - uhd::dict<std::string, uint8_t> filter_cal_regs = map_list_of - ("VHFLow_0", 0x38) - ("VHFLow_1", 0x3a) - ("VHFHigh_0", 0x3b) - ("VHFHigh_1", 0x3d) - ("UHFLow_0", 0x3e) - ("UHFLow_1", 0x40) - ("UHFHigh_0", 0x41) - ("UHFHigh_1", 0x43) - ; - - for(const std::string &name: filter_cal_regs.keys()){ + uhd::dict<std::string, uint8_t> filter_cal_regs = map_list_of("VHFLow_0", 0x38)( + "VHFLow_1", 0x3a)("VHFHigh_0", 0x3b)("VHFHigh_1", 0x3d)("UHFLow_0", 0x3e)( + "UHFLow_1", 0x40)("UHFHigh_0", 0x41)("UHFHigh_1", 0x43); + + for (const std::string& name : filter_cal_regs.keys()) { uint8_t cal_result = _tda18272hnm_regs.get_reg(filter_cal_regs[name]); if (cal_result & 0x80) { _filter_ratings.set(name, "E"); _filter_margins.set(name, 0.0); - } - else { + } else { double partial; if (name == "VHFLow_0") - partial = 100 * (45 - 39.8225 * (1 + (0.31 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0)) / 45.0; + partial = 100 + * (45 + - 39.8225 + * (1 + + (0.31 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0)) + / 45.0; else if (name == "VHFLow_1") - partial = 100 * (152.1828 * (1 + (1.53 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0) - (144.896 - 6)) / (144.896 - 6); + partial = 100 + * (152.1828 + * (1 + + (1.53 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0) + - (144.896 - 6)) + / (144.896 - 6); else if (name == "VHFHigh_0") - partial = 100 * ((144.896 + 6) - 135.4063 * (1 + (0.27 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0)) / (144.896 + 6); + partial = 100 + * ((144.896 + 6) + - 135.4063 + * (1 + + (0.27 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0)) + / (144.896 + 6); else if (name == "VHFHigh_1") - partial = 100 * (383.1455 * (1 + (0.91 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0) - (367.104 - 8)) / (367.104 - 8); + partial = 100 + * (383.1455 + * (1 + + (0.91 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0) + - (367.104 - 8)) + / (367.104 - 8); else if (name == "UHFLow_0") - partial = 100 * ((367.104 + 8) - 342.6224 * (1 + (0.21 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0)) / (367.104 + 8); + partial = 100 + * ((367.104 + 8) + - 342.6224 + * (1 + + (0.21 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0)) + / (367.104 + 8); else if (name == "UHFLow_1") - partial = 100 * (662.5595 * (1 + (0.33 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0) - (624.128 - 2)) / (624.128 - 2); + partial = 100 + * (662.5595 + * (1 + + (0.33 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0) + - (624.128 - 2)) + / (624.128 - 2); else if (name == "UHFHigh_0") - partial = 100 * ((624.128 + 2) - 508.2747 * (1 + (0.23 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0)) / (624.128 + 2); + partial = 100 + * ((624.128 + 2) + - 508.2747 + * (1 + + (0.23 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0)) + / (624.128 + 2); else if (name == "UHFHigh_1") - partial = 100 * (947.8913 * (1 + (0.3 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0) - (866 - 14)) / (866 - 14); + partial = 100 + * (947.8913 + * (1 + + (0.3 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0) + - (866 - 14)) + / (866 - 14); else UHD_THROW_INVALID_CODE_PATH(); - _filter_margins.set(name, 0.0024 * partial * partial * partial - 0.101 * partial * partial + 1.629 * partial + 1.8266); + _filter_margins.set(name, + 0.0024 * partial * partial * partial - 0.101 * partial * partial + + 1.629 * partial + 1.8266); _filter_ratings.set(name, _filter_margins[name] >= 0.0 ? "H" : "L"); } } std::stringstream robustness_message; - robustness_message << boost::format("TVRX2 (%s): RF Filter Robustness Results:") % (get_subdev_name()); - for(const std::string &name: uhd::sorted(_filter_ratings.keys())){ - robustness_message << boost::format("\t%s:\tMargin = %0.2f,\tRobustness = %c") % name % (_filter_margins[name]) % (_filter_ratings[name]); + robustness_message << boost::format("TVRX2 (%s): RF Filter Robustness Results:") + % (get_subdev_name()); + for (const std::string& name : uhd::sorted(_filter_ratings.keys())) { + robustness_message << boost::format("\t%s:\tMargin = %0.2f,\tRobustness = %c") + % name % (_filter_margins[name]) + % (_filter_ratings[name]); } UHD_LOGGER_DEBUG("TVRX") << robustness_message.str(); @@ -1521,14 +1647,17 @@ void tvrx2::test_rf_filter_robustness(void){ /*********************************************************************** * TDA18272 State Functions **********************************************************************/ -void tvrx2::transition_0(void){ - //Transition 0: Initialize Tuner and place in standby - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Transition 0: Initialize Tuner, Calibrate and Standby\n") % (get_subdev_name()) ; +void tvrx2::transition_0(void) +{ + // Transition 0: Initialize Tuner and place in standby + UHD_LOGGER_TRACE("TVRX") + << boost::format( + "\nTVRX2 (%s): Transition 0: Initialize Tuner, Calibrate and Standby\n") + % (get_subdev_name()); - //Check for Power-On Reset, if reset, initialze tuner + // Check for Power-On Reset, if reset, initialze tuner if (get_power_reset()) { - _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL; + _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL; _tda18272hnm_regs.sm_lna = tda18272hnm_regs_t::SM_LNA_ON; _tda18272hnm_regs.sm_pll = tda18272hnm_regs_t::SM_PLL_ON; @@ -1537,24 +1666,25 @@ void tvrx2::transition_0(void){ read_reg(0x19, 0x1A); - _tda18272hnm_regs.set_reg(0x19, 0x3B); //set MSM_byte_1 for calibration per datasheet - _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching calibration + _tda18272hnm_regs.set_reg( + 0x19, 0x3B); // set MSM_byte_1 for calibration per datasheet + _tda18272hnm_regs.set_reg(0x1A, 0x01); // set MSM_byte_2 for launching calibration send_reg(0x19, 0x1A); wait_irq(); } - //send magic xtal_cal_dac setting + // send magic xtal_cal_dac setting send_reg(0x65, 0x65); - send_reg(0x1D, 0x1D); //Fmax_LO - send_reg(0x0C, 0x0C); //LT_Enable - send_reg(0x1B, 0x1B); //PSM_AGC1 - send_reg(0x0C, 0x0C); //AGC1_6_15dB + send_reg(0x1D, 0x1D); // Fmax_LO + send_reg(0x0C, 0x0C); // LT_Enable + send_reg(0x1B, 0x1B); // PSM_AGC1 + send_reg(0x0C, 0x0C); // AGC1_6_15dB - //set spread spectrum for clock - //FIXME: NXP turns clock spread on and off + // set spread spectrum for clock + // FIXME: NXP turns clock spread on and off // based on where clock spurs would be relative to RF frequency // we should do this also _tda18272hnm_regs.digital_clock = tda18272hnm_regs_t::DIGITAL_CLOCK_SPREAD_OFF; @@ -1564,199 +1694,224 @@ void tvrx2::transition_0(void){ else //_tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_NO; _tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_16MHZ; - + send_reg(0x14, 0x14); - _tda18272hnm_regs.set_reg(0x36, 0x0E); //sets clock mode + _tda18272hnm_regs.set_reg(0x36, 0x0E); // sets clock mode send_reg(0x36, 0x36); - //go to standby mode + // go to standby mode _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_STANDBY; send_reg(0x6, 0x6); } -void tvrx2::transition_1(void){ - //Transition 1: Select TV Standard +void tvrx2::transition_1(void) +{ + // Transition 1: Select TV Standard UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Transition 1: Select TV Standard\n") % (get_subdev_name()) ; + "\nTVRX2 (%s): Transition 1: Select TV Standard\n") + % (get_subdev_name()); - //send magic xtal_cal_dac setting + // send magic xtal_cal_dac setting send_reg(0x65, 0x65); - //Choose IF Byte 1 Setting + // Choose IF Byte 1 Setting //_tda18272hnm_regs.if_hp_fc = tda18272hnm_regs_t::IF_HP_FC_0_4MHZ; //_tda18272hnm_regs.if_notch = tda18272hnm_regs_t::IF_NOTCH_OFF; //_tda18272hnm_regs.lp_fc_offset = tda18272hnm_regs_t::LP_FC_OFFSET_0_PERCENT; //_tda18272hnm_regs.lp_fc = tda18272hnm_regs_t::LP_FC_10_0MHZ; - //send_reg(0x13, 0x13); + // send_reg(0x13, 0x13); - //Choose IR Mixer Byte 2 Setting + // Choose IR Mixer Byte 2 Setting //_tda18272hnm_regs.hi_pass = tda18272hnm_regs_t::HI_PASS_DISABLE; //_tda18272hnm_regs.dc_notch = tda18272hnm_regs_t::DC_NOTCH_OFF; send_reg(0x23, 0x23); - //Set AGC TOP Bytes + // Set AGC TOP Bytes send_reg(0x0C, 0x13); - //Set PSM Byt1 + // Set PSM Byt1 send_reg(0x1B, 0x1B); - //Choose IF Frequency, setting is 50KHz steps + // Choose IF Frequency, setting is 50KHz steps set_scaled_if_freq(_if_freq); send_reg(0x15, 0x15); } -void tvrx2::transition_2(int rf_freq){ - //Transition 2: Select RF Frequency after changing TV Standard - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Transition 2: Select RF Frequency after changing TV Standard\n") % (get_subdev_name()) ; +void tvrx2::transition_2(int rf_freq) +{ + // Transition 2: Select RF Frequency after changing TV Standard + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): Transition 2: Select RF " + "Frequency after changing TV Standard\n") + % (get_subdev_name()); - //send magic xtal_cal_dac setting + // send magic xtal_cal_dac setting send_reg(0x65, 0x65); - //Wake up from Standby - _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL; + // Wake up from Standby + _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL; _tda18272hnm_regs.sm_lna = tda18272hnm_regs_t::SM_LNA_ON; _tda18272hnm_regs.sm_pll = tda18272hnm_regs_t::SM_PLL_ON; - + send_reg(0x6, 0x6); - - //Set Clock Mode + + // Set Clock Mode _tda18272hnm_regs.set_reg(0x36, 0x00); send_reg(0x36, 0x36); - - //Set desired RF Frequency + + // Set desired RF Frequency set_scaled_rf_freq(rf_freq); send_reg(0x16, 0x18); - - //Lock PLL and tune RF Filters - _tda18272hnm_regs.set_reg(0x19, 0x41); //set MSM_byte_1 for RF Filters Tuning, PLL Locking - _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching calibration - + + // Lock PLL and tune RF Filters + _tda18272hnm_regs.set_reg( + 0x19, 0x41); // set MSM_byte_1 for RF Filters Tuning, PLL Locking + _tda18272hnm_regs.set_reg(0x1A, 0x01); // set MSM_byte_2 for launching calibration + send_reg(0x19, 0x1A); - + wait_irq(); tvrx2_tda18272_tune_rf_filter(rf_freq); ////LO Lock state in Reg 0x5 LSB - //read_reg(0x6, 0x6); - + // read_reg(0x6, 0x6); } -void tvrx2::transition_3(void){ - //Transition 3: Standby Mode +void tvrx2::transition_3(void) +{ + // Transition 3: Standby Mode UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Transition 3: Standby Mode\n") % (get_subdev_name()) ; + "\nTVRX2 (%s): Transition 3: Standby Mode\n") + % (get_subdev_name()); - //send magic xtal_cal_dac setting + // send magic xtal_cal_dac setting send_reg(0x65, 0x65); - //Set clock mode + // Set clock mode _tda18272hnm_regs.set_reg(0x36, 0x0E); send_reg(0x36, 0x36); - //go to standby mode - _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_STANDBY; + // go to standby mode + _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_STANDBY; _tda18272hnm_regs.sm_lna = tda18272hnm_regs_t::SM_LNA_OFF; _tda18272hnm_regs.sm_pll = tda18272hnm_regs_t::SM_PLL_OFF; send_reg(0x6, 0x6); } -void tvrx2::transition_4(int rf_freq){ - //Transition 4: Change RF Frequency without changing TV Standard - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Transition 4: Change RF Frequency without changing TV Standard\n") % (get_subdev_name()) ; +void tvrx2::transition_4(int rf_freq) +{ + // Transition 4: Change RF Frequency without changing TV Standard + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): Transition 4: Change RF " + "Frequency without changing TV Standard\n") + % (get_subdev_name()); - //send magic xtal_cal_dac setting + // send magic xtal_cal_dac setting send_reg(0x65, 0x65); - //Set desired RF Frequency + // Set desired RF Frequency set_scaled_rf_freq(rf_freq); send_reg(0x16, 0x18); - - //Lock PLL and tune RF Filters - _tda18272hnm_regs.set_reg(0x19, 0x41); //set MSM_byte_1 for RF Filters Tuning, PLL Locking - _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching calibration - + + // Lock PLL and tune RF Filters + _tda18272hnm_regs.set_reg( + 0x19, 0x41); // set MSM_byte_1 for RF Filters Tuning, PLL Locking + _tda18272hnm_regs.set_reg(0x1A, 0x01); // set MSM_byte_2 for launching calibration + send_reg(0x19, 0x1A); - + wait_irq(); tvrx2_tda18272_tune_rf_filter(rf_freq); ////LO Lock state in Reg 0x5 LSB - //read_reg(0x5, 0x6); - + // read_reg(0x5, 0x6); } -void tvrx2::wait_irq(void){ - int timeout = 20; //irq waiting timeout in milliseconds - //int irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & int(tvrx2_sd_name_to_irq_io[get_subdev_name()])); +void tvrx2::wait_irq(void) +{ + int timeout = 20; // irq waiting timeout in milliseconds + // int irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & + // int(tvrx2_sd_name_to_irq_io[get_subdev_name()])); bool irq = get_irq(); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Waiting on IRQ, subdev = %d, mask = 0x%x, Status: 0x%x\n") % (get_subdev_name()) % get_subdev_name() % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq ; + UHD_LOGGER_TRACE("TVRX") + << boost::format( + "\nTVRX2 (%s): Waiting on IRQ, subdev = %d, mask = 0x%x, Status: 0x%x\n") + % (get_subdev_name()) % get_subdev_name() + % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq; while (not irq and timeout > 0) { - //irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & tvrx2_sd_name_to_irq_io[get_subdev_name()]); + // irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & + // tvrx2_sd_name_to_irq_io[get_subdev_name()]); irq = get_irq(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); timeout -= 1; } - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): IRQ Raised, subdev = %d, mask = 0x%x, Status: 0x%x, Timeout: %d\n") % (get_subdev_name()) % get_subdev_name() % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq % timeout ; + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): IRQ Raised, subdev = %d, " + "mask = 0x%x, Status: 0x%x, Timeout: %d\n") + % (get_subdev_name()) % get_subdev_name() + % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) + % irq % timeout; read_reg(0xA, 0xB); - //UHD_ASSERT_THROW(timeout > 0); - if(timeout <= 0) UHD_LOGGER_WARNING("TVRX") << boost::format( - "\nTVRX2 (%s): Timeout waiting on IRQ\n") % (get_subdev_name()) ; + // UHD_ASSERT_THROW(timeout > 0); + if (timeout <= 0) + UHD_LOGGER_WARNING("TVRX") + << boost::format("\nTVRX2 (%s): Timeout waiting on IRQ\n") + % (get_subdev_name()); _tda18272hnm_regs.irq_clear = tda18272hnm_regs_t::IRQ_CLEAR_TRUE; send_reg(0xA, 0xA); read_reg(0xA, 0xB); - irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & tvrx2_sd_name_to_irq_io[get_subdev_name()]) > 0; + irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) + & tvrx2_sd_name_to_irq_io[get_subdev_name()]) + > 0; - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Cleared IRQ, subdev = %d, mask = 0x%x, Status: 0x%x\n") % (get_subdev_name()) % get_subdev_name() % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq ; + UHD_LOGGER_TRACE("TVRX") + << boost::format( + "\nTVRX2 (%s): Cleared IRQ, subdev = %d, mask = 0x%x, Status: 0x%x\n") + % (get_subdev_name()) % get_subdev_name() + % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq; } - /*********************************************************************** * Tuning **********************************************************************/ -double tvrx2::set_lo_freq(double target_freq){ - //target_freq = std::clip(target_freq, tvrx2_freq_range.min, tvrx2_freq_range.max); +double tvrx2::set_lo_freq(double target_freq) +{ + // target_freq = std::clip(target_freq, tvrx2_freq_range.min, tvrx2_freq_range.max); read_reg(0x6, 0x6); if (_tda18272hnm_regs.sm == tda18272hnm_regs_t::SM_STANDBY) { - transition_2(int(target_freq + _bandwidth/2 - get_scaled_if_freq())); + transition_2(int(target_freq + _bandwidth / 2 - get_scaled_if_freq())); } else { - transition_4(int(target_freq + _bandwidth/2 - get_scaled_if_freq())); + transition_4(int(target_freq + _bandwidth / 2 - get_scaled_if_freq())); } read_reg(0x16, 0x18); - //compute actual tuned frequency + // compute actual tuned frequency _lo_freq = get_scaled_rf_freq() + get_scaled_if_freq(); // - _bandwidth/2; - //debug output of calculated variables - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): LO Frequency\n" - "\tRequested: \t%f\n" - "\tComputed: \t%f\n" - "\tReadback: \t%f\n" - "\tIF Frequency: \t%f\n") % (get_subdev_name()) % target_freq % double(int(target_freq/1e3)*1e3) % get_scaled_rf_freq() % get_scaled_if_freq() ; + // debug output of calculated variables + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): LO Frequency\n" + "\tRequested: \t%f\n" + "\tComputed: \t%f\n" + "\tReadback: \t%f\n" + "\tIF Frequency: \t%f\n") + % (get_subdev_name()) % target_freq + % double(int(target_freq / 1e3) * 1e3) + % get_scaled_rf_freq() % get_scaled_if_freq(); get_locked(); test_rf_filter_robustness(); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): RSSI = %f dBm\n" - ) % (get_subdev_name()) % (get_rssi().to_real()) ; + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): RSSI = %f dBm\n") + % (get_subdev_name()) % (get_rssi().to_real()); return _lo_freq; } @@ -1767,37 +1922,40 @@ double tvrx2::set_lo_freq(double target_freq){ /* * Convert the requested gain into a dac voltage */ -static double gain_to_if_gain_dac(double &gain){ - //clip the input +static double gain_to_if_gain_dac(double& gain) +{ + // clip the input gain = tvrx2_gain_ranges["IF"].clip(gain); - //voltage level constants + // voltage level constants static const double max_volts = double(1.7), min_volts = double(0.5); - static const double slope = (max_volts-min_volts)/tvrx2_gain_ranges["IF"].stop(); + static const double slope = (max_volts - min_volts) / tvrx2_gain_ranges["IF"].stop(); - //calculate the voltage for the aux dac - double dac_volts = gain*slope + min_volts; + // calculate the voltage for the aux dac + double dac_volts = gain * slope + min_volts; - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 IF Gain: %f dB, dac_volts: %f V" - ) % gain % dac_volts ; + UHD_LOGGER_TRACE("TVRX") << boost::format("TVRX2 IF Gain: %f dB, dac_volts: %f V") + % gain % dac_volts; - //the actual gain setting - gain = (dac_volts - min_volts)/slope; + // the actual gain setting + gain = (dac_volts - min_volts) / slope; return dac_volts; } -double tvrx2::set_gain(double gain, const std::string &name){ +double tvrx2::set_gain(double gain, const std::string& name) +{ assert_has(tvrx2_gain_ranges.keys(), name, "tvrx2 gain name"); - if (name == "IF"){ - //write voltage to aux_dac - this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, tvrx2_sd_name_to_dac[get_subdev_name()], gain_to_if_gain_dac(gain)); - } - else UHD_THROW_INVALID_CODE_PATH(); + if (name == "IF") { + // write voltage to aux_dac + this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, + tvrx2_sd_name_to_dac[get_subdev_name()], + gain_to_if_gain_dac(gain)); + } else + UHD_THROW_INVALID_CODE_PATH(); - //shadow gain setting + // shadow gain setting _gains[name] = gain; return gain; @@ -1806,45 +1964,48 @@ double tvrx2::set_gain(double gain, const std::string &name){ /*********************************************************************** * Bandwidth Handling **********************************************************************/ -static tda18272hnm_regs_t::lp_fc_t bandwidth_to_lp_fc_reg(double &bandwidth){ - int reg = uhd::clip(boost::math::iround((bandwidth-5.0e6)/1.0e6), 0, 4); - - switch(reg){ - case 0: - bandwidth = 1.7e6; - return tda18272hnm_regs_t::LP_FC_1_7MHZ; - case 1: - bandwidth = 6e6; - return tda18272hnm_regs_t::LP_FC_6_0MHZ; - case 2: - bandwidth = 7e6; - return tda18272hnm_regs_t::LP_FC_7_0MHZ; - case 3: - bandwidth = 8e6; - return tda18272hnm_regs_t::LP_FC_8_0MHZ; - case 4: - bandwidth = 10e6; - return tda18272hnm_regs_t::LP_FC_10_0MHZ; +static tda18272hnm_regs_t::lp_fc_t bandwidth_to_lp_fc_reg(double& bandwidth) +{ + int reg = uhd::clip(boost::math::iround((bandwidth - 5.0e6) / 1.0e6), 0, 4); + + switch (reg) { + case 0: + bandwidth = 1.7e6; + return tda18272hnm_regs_t::LP_FC_1_7MHZ; + case 1: + bandwidth = 6e6; + return tda18272hnm_regs_t::LP_FC_6_0MHZ; + case 2: + bandwidth = 7e6; + return tda18272hnm_regs_t::LP_FC_7_0MHZ; + case 3: + bandwidth = 8e6; + return tda18272hnm_regs_t::LP_FC_8_0MHZ; + case 4: + bandwidth = 10e6; + return tda18272hnm_regs_t::LP_FC_10_0MHZ; } UHD_THROW_INVALID_CODE_PATH(); } -double tvrx2::set_bandwidth(double bandwidth){ - //clip the input +double tvrx2::set_bandwidth(double bandwidth) +{ + // clip the input bandwidth = tvrx2_bandwidth_range.clip(bandwidth); - //compute low pass cutoff frequency setting + // compute low pass cutoff frequency setting _tda18272hnm_regs.lp_fc = bandwidth_to_lp_fc_reg(bandwidth); - //shadow bandwidth setting + // shadow bandwidth setting _bandwidth = bandwidth; - //update register + // update register send_reg(0x13, 0x13); UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s) Bandwidth (lp_fc): %f Hz, reg: %d" - ) % (get_subdev_name()) % _bandwidth % (int(_tda18272hnm_regs.lp_fc)) ; + "TVRX2 (%s) Bandwidth (lp_fc): %f Hz, reg: %d") + % (get_subdev_name()) % _bandwidth + % (int(_tda18272hnm_regs.lp_fc)); return _bandwidth; } diff --git a/host/lib/usrp/dboard/db_twinrx.cpp b/host/lib/usrp/dboard/db_twinrx.cpp index 9f9efd158..258dc95a4 100644 --- a/host/lib/usrp/dboard/db_twinrx.cpp +++ b/host/lib/usrp/dboard/db_twinrx.cpp @@ -39,76 +39,105 @@ class twinrx_rcvr_fe : public rx_dboard_base { public: twinrx_rcvr_fe( - ctor_args_t args, - expert_container::sptr expert, - twinrx_ctrl::sptr ctrl - ) : - rx_dboard_base(args), _expert(expert), _ctrl(ctrl), - _ch_name(dboard_ctor_args_t::cast(args).sd_name) + ctor_args_t args, expert_container::sptr expert, twinrx_ctrl::sptr ctrl) + : rx_dboard_base(args) + , _expert(expert) + , _ctrl(ctrl) + , _ch_name(dboard_ctor_args_t::cast(args).sd_name) { //--------------------------------------------------------- // Add user-visible, channel specific properties to front-end tree //--------------------------------------------------------- - //Generic - get_rx_subtree()->create<std::string>("name") - .set("TwinRX RX" + _ch_name); - get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - get_rx_subtree()->create<std::string>("connection") - .set(_ch_name == "0" ? "II" : "QQ"); //Ch->ADC port mapping + // Generic + get_rx_subtree()->create<std::string>("name").set("TwinRX RX" + _ch_name); + get_rx_subtree()->create<bool>("use_lo_offset").set(false); + get_rx_subtree() + ->create<std::string>("connection") + .set(_ch_name == "0" ? "II" : "QQ"); // Ch->ADC port mapping static const double BW = 80e6; - get_rx_subtree()->create<double>("bandwidth/value") - .set(BW); - get_rx_subtree()->create<meta_range_t>("bandwidth/range") + get_rx_subtree()->create<double>("bandwidth/value").set(BW); + get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(freq_range_t(BW, BW)); // Command Time - expert_factory::add_data_node<time_spec_t>(_expert, prepend_ch("time/rx_frontend", _ch_name), time_spec_t(0.0)); - expert_factory::add_prop_node<time_spec_t>(_expert, get_rx_subtree(), - "time/cmd", prepend_ch("time/cmd", _ch_name), time_spec_t(0.0)); + expert_factory::add_data_node<time_spec_t>( + _expert, prepend_ch("time/rx_frontend", _ch_name), time_spec_t(0.0)); + expert_factory::add_prop_node<time_spec_t>(_expert, + get_rx_subtree(), + "time/cmd", + prepend_ch("time/cmd", _ch_name), + time_spec_t(0.0)); - //Frequency Specific - get_rx_subtree()->create<meta_range_t>("freq/range") + // Frequency Specific + get_rx_subtree() + ->create<meta_range_t>("freq/range") .set(freq_range_t(10e6, 6.0e9)); - expert_factory::add_dual_prop_node<double>(_expert, get_rx_subtree(), - "freq/value", prepend_ch("freq/desired", _ch_name), prepend_ch("freq/coerced", _ch_name), - 1.0e9, AUTO_RESOLVE_ON_READ_WRITE); - get_rx_subtree()->create<device_addr_t>("tune_args") - .set(device_addr_t()); + expert_factory::add_dual_prop_node<double>(_expert, + get_rx_subtree(), + "freq/value", + prepend_ch("freq/desired", _ch_name), + prepend_ch("freq/coerced", _ch_name), + 1.0e9, + AUTO_RESOLVE_ON_READ_WRITE); + get_rx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); static const double DEFAULT_IF_FREQ = 150e6; meta_range_t if_freq_range; - if_freq_range.push_back(range_t(-DEFAULT_IF_FREQ-(BW/2), -DEFAULT_IF_FREQ+(BW/2))); - if_freq_range.push_back(range_t( DEFAULT_IF_FREQ-(BW/2), DEFAULT_IF_FREQ+(BW/2))); - get_rx_subtree()->create<meta_range_t>("if_freq/range") - .set(if_freq_range); - expert_factory::add_dual_prop_node<double>(_expert, get_rx_subtree(), - "if_freq/value", prepend_ch("if_freq/desired", _ch_name), prepend_ch("if_freq/coerced", _ch_name), - DEFAULT_IF_FREQ, AUTO_RESOLVE_ON_WRITE); - - //LO Specific - get_rx_subtree()->create<meta_range_t>("los/LO1/freq/range") + if_freq_range.push_back( + range_t(-DEFAULT_IF_FREQ - (BW / 2), -DEFAULT_IF_FREQ + (BW / 2))); + if_freq_range.push_back( + range_t(DEFAULT_IF_FREQ - (BW / 2), DEFAULT_IF_FREQ + (BW / 2))); + get_rx_subtree()->create<meta_range_t>("if_freq/range").set(if_freq_range); + expert_factory::add_dual_prop_node<double>(_expert, + get_rx_subtree(), + "if_freq/value", + prepend_ch("if_freq/desired", _ch_name), + prepend_ch("if_freq/coerced", _ch_name), + DEFAULT_IF_FREQ, + AUTO_RESOLVE_ON_WRITE); + + // LO Specific + get_rx_subtree() + ->create<meta_range_t>("los/LO1/freq/range") .set(freq_range_t(2.0e9, 6.8e9)); - expert_factory::add_dual_prop_node<double>(_expert, get_rx_subtree(), - "los/LO1/freq/value", prepend_ch("los/LO1/freq/desired", _ch_name), prepend_ch("los/LO1/freq/coerced", _ch_name), - 0.0, AUTO_RESOLVE_ON_READ_WRITE); - get_rx_subtree()->create<meta_range_t>("los/LO2/freq/range") + expert_factory::add_dual_prop_node<double>(_expert, + get_rx_subtree(), + "los/LO1/freq/value", + prepend_ch("los/LO1/freq/desired", _ch_name), + prepend_ch("los/LO1/freq/coerced", _ch_name), + 0.0, + AUTO_RESOLVE_ON_READ_WRITE); + get_rx_subtree() + ->create<meta_range_t>("los/LO2/freq/range") .set(freq_range_t(1.0e9, 3.0e9)); - expert_factory::add_dual_prop_node<double>(_expert, get_rx_subtree(), - "los/LO2/freq/value", prepend_ch("los/LO2/freq/desired", _ch_name), prepend_ch("los/LO2/freq/coerced", _ch_name), - 0.0, AUTO_RESOLVE_ON_READ_WRITE); - get_rx_subtree()->create<std::vector<std::string>>("los/all/source/options") + expert_factory::add_dual_prop_node<double>(_expert, + get_rx_subtree(), + "los/LO2/freq/value", + prepend_ch("los/LO2/freq/desired", _ch_name), + prepend_ch("los/LO2/freq/coerced", _ch_name), + 0.0, + AUTO_RESOLVE_ON_READ_WRITE); + get_rx_subtree() + ->create<std::vector<std::string>>("los/all/source/options") .set({"internal", "external", "companion", "disabled", "reimport"}); - expert_factory::add_prop_node<std::string>(_expert, get_rx_subtree(), - "los/all/source/value", prepend_ch("los/all/source", _ch_name), - "internal", AUTO_RESOLVE_ON_WRITE); - expert_factory::add_prop_node<bool>(_expert, get_rx_subtree(), - "los/all/export", prepend_ch("los/all/export", _ch_name), - false, AUTO_RESOLVE_ON_WRITE); + expert_factory::add_prop_node<std::string>(_expert, + get_rx_subtree(), + "los/all/source/value", + prepend_ch("los/all/source", _ch_name), + "internal", + AUTO_RESOLVE_ON_WRITE); + expert_factory::add_prop_node<bool>(_expert, + get_rx_subtree(), + "los/all/export", + prepend_ch("los/all/export", _ch_name), + false, + AUTO_RESOLVE_ON_WRITE); // LO1 Charge Pump - get_rx_subtree()->create<meta_range_t>("los/LO1/charge_pump/range") + get_rx_subtree() + ->create<meta_range_t>("los/LO1/charge_pump/range") .set(_ctrl->get_lo1_charge_pump_range()); expert_factory::add_dual_prop_node<double>(_expert, get_rx_subtree(), @@ -119,7 +148,8 @@ public: AUTO_RESOLVE_ON_READ_WRITE); // LO2 Charge Pump - get_rx_subtree()->create<meta_range_t>("los/LO2/charge_pump/range") + get_rx_subtree() + ->create<meta_range_t>("los/LO2/charge_pump/range") .set(_ctrl->get_lo2_charge_pump_range()); expert_factory::add_dual_prop_node<double>(_expert, get_rx_subtree(), @@ -129,29 +159,44 @@ public: 1.25e-6, AUTO_RESOLVE_ON_READ_WRITE); - //Gain Specific - get_rx_subtree()->create<meta_range_t>("gains/all/range") + // Gain Specific + get_rx_subtree() + ->create<meta_range_t>("gains/all/range") .set(gain_range_t(0, 93, double(1.0))); - expert_factory::add_prop_node<double>(_expert, get_rx_subtree(), - "gains/all/value", prepend_ch("gain", _ch_name), - 0.0, AUTO_RESOLVE_ON_WRITE); - get_rx_subtree()->create<std::vector<std::string> >("gains/all/profile/options") + expert_factory::add_prop_node<double>(_expert, + get_rx_subtree(), + "gains/all/value", + prepend_ch("gain", _ch_name), + 0.0, + AUTO_RESOLVE_ON_WRITE); + get_rx_subtree() + ->create<std::vector<std::string>>("gains/all/profile/options") .set({"low-noise", "low-distortion", "default"}); - expert_factory::add_prop_node<std::string>(_expert, get_rx_subtree(), - "gains/all/profile/value", prepend_ch("gain_profile", _ch_name), - "default", AUTO_RESOLVE_ON_WRITE); + expert_factory::add_prop_node<std::string>(_expert, + get_rx_subtree(), + "gains/all/profile/value", + prepend_ch("gain_profile", _ch_name), + "default", + AUTO_RESOLVE_ON_WRITE); - //Antenna Specific - get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + // Antenna Specific + get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set({"RX1", "RX2"}); - expert_factory::add_prop_node<std::string>(_expert, get_rx_subtree(), - "antenna/value", prepend_ch("antenna", _ch_name), - (_ch_name == "0" ? "RX1" : "RX2"), AUTO_RESOLVE_ON_WRITE); - expert_factory::add_prop_node<bool>(_expert, get_rx_subtree(), - "enabled", prepend_ch("enabled", _ch_name), - false, AUTO_RESOLVE_ON_WRITE); - - //Readback + expert_factory::add_prop_node<std::string>(_expert, + get_rx_subtree(), + "antenna/value", + prepend_ch("antenna", _ch_name), + (_ch_name == "0" ? "RX1" : "RX2"), + AUTO_RESOLVE_ON_WRITE); + expert_factory::add_prop_node<bool>(_expert, + get_rx_subtree(), + "enabled", + prepend_ch("enabled", _ch_name), + false, + AUTO_RESOLVE_ON_WRITE); + + // Readback get_rx_subtree() ->create<sensor_value_t>("sensors/lo_locked") .set_publisher([this]() { return this->get_lo_locked(); }); @@ -159,55 +204,53 @@ public: //--------------------------------------------------------- // Add internal channel-specific data nodes to expert //--------------------------------------------------------- - expert_factory::add_data_node<lo_inj_side_t>(_expert, - prepend_ch("ch/LO1/inj_side", _ch_name), INJ_LOW_SIDE); - expert_factory::add_data_node<lo_inj_side_t>(_expert, - prepend_ch("ch/LO2/inj_side", _ch_name), INJ_LOW_SIDE); - expert_factory::add_data_node<twinrx_ctrl::signal_path_t>(_expert, - prepend_ch("ch/signal_path", _ch_name), twinrx_ctrl::PATH_LOWBAND); - expert_factory::add_data_node<twinrx_ctrl::preselector_path_t>(_expert, - prepend_ch("ch/lb_presel", _ch_name), twinrx_ctrl::PRESEL_PATH1); - expert_factory::add_data_node<twinrx_ctrl::preselector_path_t>(_expert, - prepend_ch("ch/hb_presel", _ch_name), twinrx_ctrl::PRESEL_PATH1); - expert_factory::add_data_node<bool>(_expert, - prepend_ch("ch/lb_preamp_presel", _ch_name), false); - expert_factory::add_data_node<bool>(_expert, - prepend_ch("ant/lb_preamp_presel", _ch_name), false); - expert_factory::add_data_node<twinrx_ctrl::preamp_state_t>(_expert, - prepend_ch("ch/preamp1", _ch_name), twinrx_ctrl::PREAMP_BYPASS); - expert_factory::add_data_node<twinrx_ctrl::preamp_state_t>(_expert, - prepend_ch("ant/preamp1", _ch_name), twinrx_ctrl::PREAMP_BYPASS); - expert_factory::add_data_node<bool>(_expert, - prepend_ch("ch/preamp2", _ch_name), false); - expert_factory::add_data_node<bool>(_expert, - prepend_ch("ant/preamp2", _ch_name), false); - expert_factory::add_data_node<uint8_t>(_expert, - prepend_ch("ch/input_atten", _ch_name), 0); - expert_factory::add_data_node<uint8_t>(_expert, - prepend_ch("ant/input_atten", _ch_name), 0); - expert_factory::add_data_node<uint8_t>(_expert, - prepend_ch("ch/lb_atten", _ch_name), 0); - expert_factory::add_data_node<uint8_t>(_expert, - prepend_ch("ch/hb_atten", _ch_name), 0); - expert_factory::add_data_node<twinrx_ctrl::lo_source_t>(_expert, - prepend_ch("ch/LO1/source", _ch_name), twinrx_ctrl::LO_INTERNAL); - expert_factory::add_data_node<twinrx_ctrl::lo_source_t>(_expert, - prepend_ch("ch/LO2/source", _ch_name), twinrx_ctrl::LO_INTERNAL); - expert_factory::add_data_node<lo_synth_mapping_t>(_expert, - prepend_ch("synth/LO1/mapping", _ch_name), MAPPING_NONE); - expert_factory::add_data_node<lo_synth_mapping_t>(_expert, - prepend_ch("synth/LO2/mapping", _ch_name), MAPPING_NONE); - + expert_factory::add_data_node<lo_inj_side_t>( + _expert, prepend_ch("ch/LO1/inj_side", _ch_name), INJ_LOW_SIDE); + expert_factory::add_data_node<lo_inj_side_t>( + _expert, prepend_ch("ch/LO2/inj_side", _ch_name), INJ_LOW_SIDE); + expert_factory::add_data_node<twinrx_ctrl::signal_path_t>( + _expert, prepend_ch("ch/signal_path", _ch_name), twinrx_ctrl::PATH_LOWBAND); + expert_factory::add_data_node<twinrx_ctrl::preselector_path_t>( + _expert, prepend_ch("ch/lb_presel", _ch_name), twinrx_ctrl::PRESEL_PATH1); + expert_factory::add_data_node<twinrx_ctrl::preselector_path_t>( + _expert, prepend_ch("ch/hb_presel", _ch_name), twinrx_ctrl::PRESEL_PATH1); + expert_factory::add_data_node<bool>( + _expert, prepend_ch("ch/lb_preamp_presel", _ch_name), false); + expert_factory::add_data_node<bool>( + _expert, prepend_ch("ant/lb_preamp_presel", _ch_name), false); + expert_factory::add_data_node<twinrx_ctrl::preamp_state_t>( + _expert, prepend_ch("ch/preamp1", _ch_name), twinrx_ctrl::PREAMP_BYPASS); + expert_factory::add_data_node<twinrx_ctrl::preamp_state_t>( + _expert, prepend_ch("ant/preamp1", _ch_name), twinrx_ctrl::PREAMP_BYPASS); + expert_factory::add_data_node<bool>( + _expert, prepend_ch("ch/preamp2", _ch_name), false); + expert_factory::add_data_node<bool>( + _expert, prepend_ch("ant/preamp2", _ch_name), false); + expert_factory::add_data_node<uint8_t>( + _expert, prepend_ch("ch/input_atten", _ch_name), 0); + expert_factory::add_data_node<uint8_t>( + _expert, prepend_ch("ant/input_atten", _ch_name), 0); + expert_factory::add_data_node<uint8_t>( + _expert, prepend_ch("ch/lb_atten", _ch_name), 0); + expert_factory::add_data_node<uint8_t>( + _expert, prepend_ch("ch/hb_atten", _ch_name), 0); + expert_factory::add_data_node<twinrx_ctrl::lo_source_t>( + _expert, prepend_ch("ch/LO1/source", _ch_name), twinrx_ctrl::LO_INTERNAL); + expert_factory::add_data_node<twinrx_ctrl::lo_source_t>( + _expert, prepend_ch("ch/LO2/source", _ch_name), twinrx_ctrl::LO_INTERNAL); + expert_factory::add_data_node<lo_synth_mapping_t>( + _expert, prepend_ch("synth/LO1/mapping", _ch_name), MAPPING_NONE); + expert_factory::add_data_node<lo_synth_mapping_t>( + _expert, prepend_ch("synth/LO2/mapping", _ch_name), MAPPING_NONE); } - virtual ~twinrx_rcvr_fe(void) - { - } + virtual ~twinrx_rcvr_fe(void) {} sensor_value_t get_lo_locked() { - bool locked = true; - twinrx_ctrl::channel_t ch = (_ch_name == "0") ? twinrx_ctrl::CH1 : twinrx_ctrl::CH2; + bool locked = true; + twinrx_ctrl::channel_t ch = (_ch_name == "0") ? twinrx_ctrl::CH1 + : twinrx_ctrl::CH2; locked &= _ctrl->read_lo1_locked(ch); locked &= _ctrl->read_lo2_locked(ch); return sensor_value_t("LO", locked, "locked", "unlocked"); @@ -215,8 +258,8 @@ public: private: expert_container::sptr _expert; - twinrx_ctrl::sptr _ctrl; - const std::string _ch_name; + twinrx_ctrl::sptr _ctrl; + const std::string _ch_name; }; /*! @@ -233,23 +276,23 @@ public: twinrx_rcvr(ctor_args_t args) : rx_dboard_base(args) { - _db_iface = get_iface(); - twinrx_gpio::sptr gpio_iface = std::make_shared<twinrx_gpio>(_db_iface); + _db_iface = get_iface(); + twinrx_gpio::sptr gpio_iface = std::make_shared<twinrx_gpio>(_db_iface); twinrx_cpld_regmap::sptr cpld_regs = std::make_shared<twinrx_cpld_regmap>(); cpld_regs->initialize(*gpio_iface, false); - _ctrl = twinrx_ctrl::make(_db_iface, gpio_iface, cpld_regs, get_rx_id()); + _ctrl = twinrx_ctrl::make(_db_iface, gpio_iface, cpld_regs, get_rx_id()); _expert = expert_factory::create_container("twinrx_expert"); } - virtual ~twinrx_rcvr(void) - { - } + virtual ~twinrx_rcvr(void) {} - inline expert_container::sptr get_expert() { + inline expert_container::sptr get_expert() + { return _expert; } - inline twinrx_ctrl::sptr get_ctrl() { + inline twinrx_ctrl::sptr get_ctrl() + { return _ctrl; } @@ -258,38 +301,49 @@ public: //--------------------------------------------------------- // Add internal channel-agnostic data nodes to expert //--------------------------------------------------------- - expert_factory::add_data_node<twinrx_ctrl::lo_export_source_t>(_expert, - "com/LO1/export_source", twinrx_ctrl::LO_EXPORT_DISABLED); - expert_factory::add_data_node<twinrx_ctrl::lo_export_source_t>(_expert, - "com/LO2/export_source", twinrx_ctrl::LO_EXPORT_DISABLED); - expert_factory::add_data_node<twinrx_ctrl::antenna_mapping_t>(_expert, - "com/ant_mapping", twinrx_ctrl::ANTX_NATIVE); - expert_factory::add_data_node<twinrx_ctrl::cal_mode_t>(_expert, - "com/cal_mode", twinrx_ctrl::CAL_DISABLED); - expert_factory::add_data_node<bool>(_expert, - "com/synth/LO1/hopping_enabled", false); - expert_factory::add_data_node<bool>(_expert, - "com/synth/LO2/hopping_enabled", false); + expert_factory::add_data_node<twinrx_ctrl::lo_export_source_t>( + _expert, "com/LO1/export_source", twinrx_ctrl::LO_EXPORT_DISABLED); + expert_factory::add_data_node<twinrx_ctrl::lo_export_source_t>( + _expert, "com/LO2/export_source", twinrx_ctrl::LO_EXPORT_DISABLED); + expert_factory::add_data_node<twinrx_ctrl::antenna_mapping_t>( + _expert, "com/ant_mapping", twinrx_ctrl::ANTX_NATIVE); + expert_factory::add_data_node<twinrx_ctrl::cal_mode_t>( + _expert, "com/cal_mode", twinrx_ctrl::CAL_DISABLED); + expert_factory::add_data_node<bool>( + _expert, "com/synth/LO1/hopping_enabled", false); + expert_factory::add_data_node<bool>( + _expert, "com/synth/LO2/hopping_enabled", false); //--------------------------------------------------------- // Add workers to expert //--------------------------------------------------------- - //Channel (front-end) specific - for(const std::string& fe: _fe_names) { - expert_factory::add_worker_node<twinrx_freq_path_expert>(_expert, _expert->node_retriever(), fe); - expert_factory::add_worker_node<twinrx_freq_coercion_expert>(_expert, _expert->node_retriever(), fe); - expert_factory::add_worker_node<twinrx_chan_gain_expert>(_expert, _expert->node_retriever(), fe); - expert_factory::add_worker_node<twinrx_scheduling_expert>(_expert, _expert->node_retriever(), fe); - expert_factory::add_worker_node<twinrx_nyquist_expert>(_expert, _expert->node_retriever(), fe, _db_iface); + // Channel (front-end) specific + for (const std::string& fe : _fe_names) { + expert_factory::add_worker_node<twinrx_freq_path_expert>( + _expert, _expert->node_retriever(), fe); + expert_factory::add_worker_node<twinrx_freq_coercion_expert>( + _expert, _expert->node_retriever(), fe); + expert_factory::add_worker_node<twinrx_chan_gain_expert>( + _expert, _expert->node_retriever(), fe); + expert_factory::add_worker_node<twinrx_scheduling_expert>( + _expert, _expert->node_retriever(), fe); + expert_factory::add_worker_node<twinrx_nyquist_expert>( + _expert, _expert->node_retriever(), fe, _db_iface); } - //Channel (front-end) agnostic - expert_factory::add_worker_node<twinrx_lo_config_expert>(_expert, _expert->node_retriever()); - expert_factory::add_worker_node<twinrx_lo_mapping_expert>(_expert, _expert->node_retriever(), STAGE_LO1); - expert_factory::add_worker_node<twinrx_lo_mapping_expert>(_expert, _expert->node_retriever(), STAGE_LO2); - expert_factory::add_worker_node<twinrx_antenna_expert>(_expert, _expert->node_retriever()); - expert_factory::add_worker_node<twinrx_ant_gain_expert>(_expert, _expert->node_retriever()); - expert_factory::add_worker_node<twinrx_settings_expert>(_expert, _expert->node_retriever(), _ctrl); + // Channel (front-end) agnostic + expert_factory::add_worker_node<twinrx_lo_config_expert>( + _expert, _expert->node_retriever()); + expert_factory::add_worker_node<twinrx_lo_mapping_expert>( + _expert, _expert->node_retriever(), STAGE_LO1); + expert_factory::add_worker_node<twinrx_lo_mapping_expert>( + _expert, _expert->node_retriever(), STAGE_LO2); + expert_factory::add_worker_node<twinrx_antenna_expert>( + _expert, _expert->node_retriever()); + expert_factory::add_worker_node<twinrx_ant_gain_expert>( + _expert, _expert->node_retriever()); + expert_factory::add_worker_node<twinrx_settings_expert>( + _expert, _expert->node_retriever(), _ctrl); /*//Expert debug code std::ofstream dot_file("/tmp/twinrx.dot", std::ios::out); @@ -316,24 +370,27 @@ public: } protected: - inline void add_twinrx_fe(const std::string& name) { + inline void add_twinrx_fe(const std::string& name) + { _fe_names.push_back(name); } private: typedef std::map<std::string, dboard_base::sptr> twinrx_fe_map_t; - dboard_iface::sptr _db_iface; - twinrx_ctrl::sptr _ctrl; - std::vector<std::string> _fe_names; - expert_container::sptr _expert; + dboard_iface::sptr _db_iface; + twinrx_ctrl::sptr _ctrl; + std::vector<std::string> _fe_names; + expert_container::sptr _expert; }; /*! * Initialization Sequence for each TwinRX board: * - make_twinrx_container is called which creates an instance of twinrx_rcvr - * - twinrx_rcvr::make_twinrx_fe is called with channel "0" which creates an instance of twinrx_rcvr_fe - * - twinrx_rcvr::make_twinrx_fe is called with channel "1" which creates an instance of twinrx_rcvr_fe + * - twinrx_rcvr::make_twinrx_fe is called with channel "0" which creates an instance of + * twinrx_rcvr_fe + * - twinrx_rcvr::make_twinrx_fe is called with channel "1" which creates an instance of + * twinrx_rcvr_fe * - twinrx_rcvr::initialize is called with finishes the init sequence * */ @@ -344,27 +401,21 @@ static dboard_base::sptr make_twinrx_container(dboard_base::ctor_args_t args) UHD_STATIC_BLOCK(reg_twinrx_dboards) { - dboard_manager::register_dboard_restricted( - twinrx::TWINRX_REV_A_ID, + dboard_manager::register_dboard_restricted(twinrx::TWINRX_REV_A_ID, &twinrx_rcvr::make_twinrx_fe, "TwinRX Rev A", {"0", "1"}, - &make_twinrx_container - ); + &make_twinrx_container); - dboard_manager::register_dboard_restricted( - twinrx::TWINRX_REV_B_ID, + dboard_manager::register_dboard_restricted(twinrx::TWINRX_REV_B_ID, &twinrx_rcvr::make_twinrx_fe, "TwinRX Rev B", {"0", "1"}, - &make_twinrx_container - ); + &make_twinrx_container); - dboard_manager::register_dboard_restricted( - twinrx::TWINRX_REV_C_ID, + dboard_manager::register_dboard_restricted(twinrx::TWINRX_REV_C_ID, &twinrx_rcvr::make_twinrx_fe, "TwinRX Rev C", {"0", "1"}, - &make_twinrx_container - ); + &make_twinrx_container); } diff --git a/host/lib/usrp/dboard/db_ubx.cpp b/host/lib/usrp/dboard/db_ubx.cpp index 3771c9f2d..8ac96a2fe 100644 --- a/host/lib/usrp/dboard/db_ubx.cpp +++ b/host/lib/usrp/dboard/db_ubx.cpp @@ -34,8 +34,7 @@ using namespace uhd::usrp; /*********************************************************************** * UBX Data Structures **********************************************************************/ -enum ubx_gpio_field_id_t -{ +enum ubx_gpio_field_id_t { SPI_ADDR, TX_EN_N, RX_EN_N, @@ -51,34 +50,33 @@ enum ubx_gpio_field_id_t TXLO2_SYNC }; -enum ubx_cpld_field_id_t -{ - TXHB_SEL = 0, - TXLB_SEL = 1, - TXLO1_FSEL1 = 2, - TXLO1_FSEL2 = 3, - TXLO1_FSEL3 = 4, - RXHB_SEL = 5, - RXLB_SEL = 6, - RXLO1_FSEL1 = 7, - RXLO1_FSEL2 = 8, - RXLO1_FSEL3 = 9, - SEL_LNA1 = 10, - SEL_LNA2 = 11, - TXLO1_FORCEON = 12, - TXLO2_FORCEON = 13, - TXMOD_FORCEON = 14, +enum ubx_cpld_field_id_t { + TXHB_SEL = 0, + TXLB_SEL = 1, + TXLO1_FSEL1 = 2, + TXLO1_FSEL2 = 3, + TXLO1_FSEL3 = 4, + RXHB_SEL = 5, + RXLB_SEL = 6, + RXLO1_FSEL1 = 7, + RXLO1_FSEL2 = 8, + RXLO1_FSEL3 = 9, + SEL_LNA1 = 10, + SEL_LNA2 = 11, + TXLO1_FORCEON = 12, + TXLO2_FORCEON = 13, + TXMOD_FORCEON = 14, TXMIXER_FORCEON = 15, - TXDRV_FORCEON = 16, - RXLO1_FORCEON = 17, - RXLO2_FORCEON = 18, + TXDRV_FORCEON = 16, + RXLO1_FORCEON = 17, + RXLO2_FORCEON = 18, RXDEMOD_FORCEON = 19, RXMIXER_FORCEON = 20, - RXDRV_FORCEON = 21, - RXAMP_FORCEON = 22, - RXLNA1_FORCEON = 23, - RXLNA2_FORCEON = 24, - CAL_ENABLE = 25 + RXDRV_FORCEON = 21, + RXAMP_FORCEON = 22, + RXLNA1_FORCEON = 23, + RXLNA2_FORCEON = 24, + CAL_ENABLE = 25 }; struct ubx_gpio_field_info_t @@ -88,7 +86,7 @@ struct ubx_gpio_field_info_t uint32_t offset; uint32_t mask; uint32_t width; - enum {OUTPUT,INPUT} direction; + enum { OUTPUT, INPUT } direction; bool is_atr_controlled; uint32_t atr_idle; uint32_t atr_tx; @@ -125,12 +123,12 @@ struct ubx_cpld_reg_t }; enum spi_dest_t { - TXLO1 = 0x0, // 0x00: TXLO1, the main TXLO from 400MHz to 6000MHz - TXLO2 = 0x1, // 0x01: TXLO2, the low band mixer TXLO 10MHz to 400MHz - RXLO1 = 0x2, // 0x02: RXLO1, the main RXLO from 400MHz to 6000MHz - RXLO2 = 0x3, // 0x03: RXLO2, the low band mixer RXLO 10MHz to 400MHz - CPLD = 0x4 // 0x04: CPLD SPI Register - }; + TXLO1 = 0x0, // 0x00: TXLO1, the main TXLO from 400MHz to 6000MHz + TXLO2 = 0x1, // 0x01: TXLO2, the low band mixer TXLO 10MHz to 400MHz + RXLO1 = 0x2, // 0x02: RXLO1, the main RXLO from 400MHz to 6000MHz + RXLO2 = 0x3, // 0x03: RXLO2, the low band mixer RXLO 10MHz to 400MHz + CPLD = 0x4 // 0x04: CPLD SPI Register +}; /*********************************************************************** * UBX Constants @@ -198,11 +196,11 @@ static const ubx_gpio_field_info_t ubx_v1_gpio_info[] = { /*********************************************************************** * Macros for routing and writing SPI registers **********************************************************************/ -#define ROUTE_SPI(iface, dest) \ +#define ROUTE_SPI(iface, dest) \ set_gpio_field(SPI_ADDR, dest); \ write_gpio(); -#define WRITE_SPI(iface, val) \ +#define WRITE_SPI(iface, val) \ iface->write_spi(dboard_iface::UNIT_TX, spi_config_t::EDGE_RISE, val, 32); /*********************************************************************** @@ -213,91 +211,85 @@ class ubx_xcvr : public xcvr_dboard_base public: ubx_xcvr(ctor_args_t args) : xcvr_dboard_base(args) { - double bw = 40e6; + double bw = 40e6; double pfd_freq_max = 25e6; //////////////////////////////////////////////////////////////////// // Setup GPIO hardware //////////////////////////////////////////////////////////////////// - _iface = get_iface(); + _iface = get_iface(); dboard_id_t rx_id = get_rx_id(); dboard_id_t tx_id = get_tx_id(); - size_t revision = 1; // default to rev A + size_t revision = 1; // default to rev A // Get revision if programmed const std::string revision_str = get_rx_eeprom().revision; - if (not revision_str.empty()) - { + if (not revision_str.empty()) { revision = boost::lexical_cast<size_t>(revision_str); } _high_isolation = false; if (rx_id == UBX_PROTO_V3_RX_ID and tx_id == UBX_PROTO_V3_TX_ID) { _rev = 0; - } - else if (rx_id == UBX_PROTO_V4_RX_ID and tx_id == UBX_PROTO_V4_TX_ID) { + } else if (rx_id == UBX_PROTO_V4_RX_ID and tx_id == UBX_PROTO_V4_TX_ID) { _rev = 1; - } - else if (rx_id == UBX_V1_40MHZ_RX_ID and tx_id == UBX_V1_40MHZ_TX_ID) { + } else if (rx_id == UBX_V1_40MHZ_RX_ID and tx_id == UBX_V1_40MHZ_TX_ID) { _rev = 1; - } - else if (rx_id == UBX_V2_40MHZ_RX_ID and tx_id == UBX_V2_40MHZ_TX_ID) { + } else if (rx_id == UBX_V2_40MHZ_RX_ID and tx_id == UBX_V2_40MHZ_TX_ID) { _rev = 2; - if (revision >= 4) - { + if (revision >= 4) { _high_isolation = true; } - } - else if (rx_id == UBX_V1_160MHZ_RX_ID and tx_id == UBX_V1_160MHZ_TX_ID) { - bw = 160e6; + } else if (rx_id == UBX_V1_160MHZ_RX_ID and tx_id == UBX_V1_160MHZ_TX_ID) { + bw = 160e6; _rev = 1; - } - else if (rx_id == UBX_V2_160MHZ_RX_ID and tx_id == UBX_V2_160MHZ_TX_ID) { - bw = 160e6; + } else if (rx_id == UBX_V2_160MHZ_RX_ID and tx_id == UBX_V2_160MHZ_TX_ID) { + bw = 160e6; _rev = 2; - if (revision >= 4) - { + if (revision >= 4) { _high_isolation = true; } - } - else if (rx_id == UBX_LP_160MHZ_RX_ID and tx_id == UBX_LP_160MHZ_TX_ID) { + } else if (rx_id == UBX_LP_160MHZ_RX_ID and tx_id == UBX_LP_160MHZ_TX_ID) { // The LP version behaves and looks like a regular UBX-160 v2 - bw = 160e6; - _rev = 2; - } - else if (rx_id == UBX_TDD_160MHZ_RX_ID and tx_id == UBX_TDD_160MHZ_TX_ID) { - bw = 160e6; + bw = 160e6; _rev = 2; + } else if (rx_id == UBX_TDD_160MHZ_RX_ID and tx_id == UBX_TDD_160MHZ_TX_ID) { + bw = 160e6; + _rev = 2; _high_isolation = true; - } - else { + } else { UHD_THROW_INVALID_CODE_PATH(); } - switch(_rev) - { - case 0: - for (size_t i = 0; i < sizeof(ubx_proto_gpio_info) / sizeof(ubx_gpio_field_info_t); i++) - _gpio_map[ubx_proto_gpio_info[i].id] = ubx_proto_gpio_info[i]; - pfd_freq_max = 25e6; - break; - case 1: - case 2: - for (size_t i = 0; i < sizeof(ubx_v1_gpio_info) / sizeof(ubx_gpio_field_info_t); i++) - _gpio_map[ubx_v1_gpio_info[i].id] = ubx_v1_gpio_info[i]; - pfd_freq_max = 50e6; - break; + switch (_rev) { + case 0: + for (size_t i = 0; + i < sizeof(ubx_proto_gpio_info) / sizeof(ubx_gpio_field_info_t); + i++) + _gpio_map[ubx_proto_gpio_info[i].id] = ubx_proto_gpio_info[i]; + pfd_freq_max = 25e6; + break; + case 1: + case 2: + for (size_t i = 0; + i < sizeof(ubx_v1_gpio_info) / sizeof(ubx_gpio_field_info_t); + i++) + _gpio_map[ubx_v1_gpio_info[i].id] = ubx_v1_gpio_info[i]; + pfd_freq_max = 50e6; + break; } // Initialize GPIO registers - memset(&_tx_gpio_reg,0,sizeof(ubx_gpio_reg_t)); - memset(&_rx_gpio_reg,0,sizeof(ubx_gpio_reg_t)); - for (std::map<ubx_gpio_field_id_t,ubx_gpio_field_info_t>::iterator entry = _gpio_map.begin(); entry != _gpio_map.end(); entry++) - { + memset(&_tx_gpio_reg, 0, sizeof(ubx_gpio_reg_t)); + memset(&_rx_gpio_reg, 0, sizeof(ubx_gpio_reg_t)); + for (std::map<ubx_gpio_field_id_t, ubx_gpio_field_info_t>::iterator entry = + _gpio_map.begin(); + entry != _gpio_map.end(); + entry++) { ubx_gpio_field_info_t info = entry->second; - ubx_gpio_reg_t *reg = (info.unit == dboard_iface::UNIT_TX ? &_tx_gpio_reg : &_rx_gpio_reg); + ubx_gpio_reg_t* reg = + (info.unit == dboard_iface::UNIT_TX ? &_tx_gpio_reg : &_rx_gpio_reg); if (info.direction == ubx_gpio_field_info_t::INPUT) reg->ddr |= info.mask; - if (info.is_atr_controlled) - { + if (info.is_atr_controlled) { reg->atr_mask |= info.mask; reg->atr_idle |= (info.atr_idle << info.offset) & info.mask; reg->atr_tx |= (info.atr_tx << info.offset) & info.mask; @@ -309,44 +301,40 @@ public: // Enable the reference clocks that we need _rx_target_pfd_freq = pfd_freq_max; _tx_target_pfd_freq = pfd_freq_max; - if (_rev >= 1) - { + if (_rev >= 1) { bool can_set_clock_rate = true; // set dboard clock rates to as close to the max PFD freq as possible - if (_iface->get_clock_rate(dboard_iface::UNIT_RX) > pfd_freq_max) - { - std::vector<double> rates = _iface->get_clock_rates(dboard_iface::UNIT_RX); + if (_iface->get_clock_rate(dboard_iface::UNIT_RX) > pfd_freq_max) { + std::vector<double> rates = + _iface->get_clock_rates(dboard_iface::UNIT_RX); double highest_rate = 0.0; - for(double rate: rates) - { + for (double rate : rates) { if (rate <= pfd_freq_max and rate > highest_rate) highest_rate = rate; } try { _iface->set_clock_rate(dboard_iface::UNIT_RX, highest_rate); - } catch (const uhd::not_implemented_error &) { - UHD_LOG_WARNING("UBX", - "Unable to set dboard clock rate - phase will vary" - ); + } catch (const uhd::not_implemented_error&) { + UHD_LOG_WARNING( + "UBX", "Unable to set dboard clock rate - phase will vary"); can_set_clock_rate = false; } _rx_target_pfd_freq = highest_rate; } - if (can_set_clock_rate and _iface->get_clock_rate(dboard_iface::UNIT_TX) > pfd_freq_max) - { - std::vector<double> rates = _iface->get_clock_rates(dboard_iface::UNIT_TX); + if (can_set_clock_rate + and _iface->get_clock_rate(dboard_iface::UNIT_TX) > pfd_freq_max) { + std::vector<double> rates = + _iface->get_clock_rates(dboard_iface::UNIT_TX); double highest_rate = 0.0; - for(double rate: rates) - { + for (double rate : rates) { if (rate <= pfd_freq_max and rate > highest_rate) highest_rate = rate; } try { _iface->set_clock_rate(dboard_iface::UNIT_TX, highest_rate); - } catch (const uhd::not_implemented_error &) { - UHD_LOG_WARNING("UBX", - "Unable to set dboard clock rate - phase will vary" - ); + } catch (const uhd::not_implemented_error&) { + UHD_LOG_WARNING( + "UBX", "Unable to set dboard clock rate - phase will vary"); } _tx_target_pfd_freq = highest_rate; } @@ -373,97 +361,127 @@ public: write_gpio(); // Configure ATR - _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, _tx_gpio_reg.atr_idle); - _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _tx_gpio_reg.atr_tx); - _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, _tx_gpio_reg.atr_rx); - _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _tx_gpio_reg.atr_full_duplex); - _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, _rx_gpio_reg.atr_idle); - _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _rx_gpio_reg.atr_tx); - _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _rx_gpio_reg.atr_rx); - _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _rx_gpio_reg.atr_full_duplex); + _iface->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, _tx_gpio_reg.atr_idle); + _iface->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _tx_gpio_reg.atr_tx); + _iface->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, _tx_gpio_reg.atr_rx); + _iface->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _tx_gpio_reg.atr_full_duplex); + _iface->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, _rx_gpio_reg.atr_idle); + _iface->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _rx_gpio_reg.atr_tx); + _iface->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _rx_gpio_reg.atr_rx); + _iface->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _rx_gpio_reg.atr_full_duplex); // Engage ATR control (1 is ATR control, 0 is manual control) _iface->set_pin_ctrl(dboard_iface::UNIT_TX, _tx_gpio_reg.atr_mask); _iface->set_pin_ctrl(dboard_iface::UNIT_RX, _rx_gpio_reg.atr_mask); // bring CPLD out of reset - std::this_thread::sleep_for(std::chrono::milliseconds(20)); // hold CPLD reset for minimum of 20 ms + std::this_thread::sleep_for( + std::chrono::milliseconds(20)); // hold CPLD reset for minimum of 20 ms set_gpio_field(CPLD_RST_N, 1); write_gpio(); // Initialize LOs - if (_rev == 0) - { - _txlo1 = max287x_iface::make<max2870>(std::bind(&ubx_xcvr::write_spi_regs, this, TXLO1, std::placeholders::_1)); - _txlo2 = max287x_iface::make<max2870>(std::bind(&ubx_xcvr::write_spi_regs, this, TXLO2, std::placeholders::_1)); - _rxlo1 = max287x_iface::make<max2870>(std::bind(&ubx_xcvr::write_spi_regs, this, RXLO1, std::placeholders::_1)); - _rxlo2 = max287x_iface::make<max2870>(std::bind(&ubx_xcvr::write_spi_regs, this, RXLO2, std::placeholders::_1)); + if (_rev == 0) { + _txlo1 = max287x_iface::make<max2870>( + std::bind(&ubx_xcvr::write_spi_regs, this, TXLO1, std::placeholders::_1)); + _txlo2 = max287x_iface::make<max2870>( + std::bind(&ubx_xcvr::write_spi_regs, this, TXLO2, std::placeholders::_1)); + _rxlo1 = max287x_iface::make<max2870>( + std::bind(&ubx_xcvr::write_spi_regs, this, RXLO1, std::placeholders::_1)); + _rxlo2 = max287x_iface::make<max2870>( + std::bind(&ubx_xcvr::write_spi_regs, this, RXLO2, std::placeholders::_1)); std::vector<max287x_iface::sptr> los{_txlo1, _txlo2, _rxlo1, _rxlo2}; - for(max287x_iface::sptr lo: los) - { + for (max287x_iface::sptr lo : los) { lo->set_auto_retune(false); lo->set_muxout_mode(max287x_iface::MUXOUT_DLD); lo->set_ld_pin_mode(max287x_iface::LD_PIN_MODE_DLD); } - } - else if (_rev == 1 or _rev == 2) - { - _txlo1 = max287x_iface::make<max2871>(std::bind(&ubx_xcvr::write_spi_regs, this, TXLO1, std::placeholders::_1)); - _txlo2 = max287x_iface::make<max2871>(std::bind(&ubx_xcvr::write_spi_regs, this, TXLO2, std::placeholders::_1)); - _rxlo1 = max287x_iface::make<max2871>(std::bind(&ubx_xcvr::write_spi_regs, this, RXLO1, std::placeholders::_1)); - _rxlo2 = max287x_iface::make<max2871>(std::bind(&ubx_xcvr::write_spi_regs, this, RXLO2, std::placeholders::_1)); + } else if (_rev == 1 or _rev == 2) { + _txlo1 = max287x_iface::make<max2871>( + std::bind(&ubx_xcvr::write_spi_regs, this, TXLO1, std::placeholders::_1)); + _txlo2 = max287x_iface::make<max2871>( + std::bind(&ubx_xcvr::write_spi_regs, this, TXLO2, std::placeholders::_1)); + _rxlo1 = max287x_iface::make<max2871>( + std::bind(&ubx_xcvr::write_spi_regs, this, RXLO1, std::placeholders::_1)); + _rxlo2 = max287x_iface::make<max2871>( + std::bind(&ubx_xcvr::write_spi_regs, this, RXLO2, std::placeholders::_1)); std::vector<max287x_iface::sptr> los{_txlo1, _txlo2, _rxlo1, _rxlo2}; - for(max287x_iface::sptr lo: los) - { + for (max287x_iface::sptr lo : los) { lo->set_auto_retune(false); - //lo->set_cycle_slip_mode(true); // tried it - caused longer lock times + // lo->set_cycle_slip_mode(true); // tried it - caused longer lock times lo->set_charge_pump_current(max287x_iface::CHARGE_PUMP_CURRENT_5_12MA); lo->set_muxout_mode(max287x_iface::MUXOUT_SYNC); lo->set_ld_pin_mode(max287x_iface::LD_PIN_MODE_DLD); } - } - else - { + } else { UHD_THROW_INVALID_CODE_PATH(); } // Initialize CPLD register _prev_cpld_value = 0xFFFF; - _cpld_reg.value = 0; + _cpld_reg.value = 0; write_cpld_reg(); //////////////////////////////////////////////////////////////////// // Register power save properties //////////////////////////////////////////////////////////////////// - get_rx_subtree()->create<std::vector<std::string> >("power_mode/options") + get_rx_subtree() + ->create<std::vector<std::string>>("power_mode/options") .set(ubx_power_modes); - get_rx_subtree()->create<std::string>("power_mode/value") - .add_coerced_subscriber(std::bind(&ubx_xcvr::set_power_mode, this, std::placeholders::_1)) + get_rx_subtree() + ->create<std::string>("power_mode/value") + .add_coerced_subscriber( + std::bind(&ubx_xcvr::set_power_mode, this, std::placeholders::_1)) .set("performance"); - get_rx_subtree()->create<std::vector<std::string> >("xcvr_mode/options") + get_rx_subtree() + ->create<std::vector<std::string>>("xcvr_mode/options") .set(ubx_xcvr_modes); - get_rx_subtree()->create<std::string>("xcvr_mode/value") - .add_coerced_subscriber(std::bind(&ubx_xcvr::set_xcvr_mode, this, std::placeholders::_1)) + get_rx_subtree() + ->create<std::string>("xcvr_mode/value") + .add_coerced_subscriber( + std::bind(&ubx_xcvr::set_xcvr_mode, this, std::placeholders::_1)) .set("FDX"); - get_rx_subtree()->create<std::vector<std::string> >("temp_comp_mode/options") + get_rx_subtree() + ->create<std::vector<std::string>>("temp_comp_mode/options") .set(ubx_temp_comp_modes); get_rx_subtree() ->create<std::string>("temp_comp_mode/value") .add_coerced_subscriber( [this](std::string mode) { this->set_temp_comp_mode(mode); }) .set("disabled"); - get_tx_subtree()->create<std::vector<std::string> >("power_mode/options") + get_tx_subtree() + ->create<std::vector<std::string>>("power_mode/options") .set(ubx_power_modes); - get_tx_subtree()->create<std::string>("power_mode/value") - .add_coerced_subscriber(std::bind(&uhd::property<std::string>::set, &get_rx_subtree()->access<std::string>("power_mode/value"), std::placeholders::_1)) - .set_publisher(std::bind(&uhd::property<std::string>::get, &get_rx_subtree()->access<std::string>("power_mode/value"))); - get_tx_subtree()->create<std::vector<std::string> >("xcvr_mode/options") + get_tx_subtree() + ->create<std::string>("power_mode/value") + .add_coerced_subscriber(std::bind(&uhd::property<std::string>::set, + &get_rx_subtree()->access<std::string>("power_mode/value"), + std::placeholders::_1)) + .set_publisher(std::bind(&uhd::property<std::string>::get, + &get_rx_subtree()->access<std::string>("power_mode/value"))); + get_tx_subtree() + ->create<std::vector<std::string>>("xcvr_mode/options") .set(ubx_xcvr_modes); - get_tx_subtree()->create<std::string>("xcvr_mode/value") - .add_coerced_subscriber(std::bind(&uhd::property<std::string>::set, &get_rx_subtree()->access<std::string>("xcvr_mode/value"), std::placeholders::_1)) - .set_publisher(std::bind(&uhd::property<std::string>::get, &get_rx_subtree()->access<std::string>("xcvr_mode/value"))); - get_tx_subtree()->create<std::vector<std::string> >("temp_comp_mode/options") + get_tx_subtree() + ->create<std::string>("xcvr_mode/value") + .add_coerced_subscriber(std::bind(&uhd::property<std::string>::set, + &get_rx_subtree()->access<std::string>("xcvr_mode/value"), + std::placeholders::_1)) + .set_publisher(std::bind(&uhd::property<std::string>::get, + &get_rx_subtree()->access<std::string>("xcvr_mode/value"))); + get_tx_subtree() + ->create<std::vector<std::string>>("temp_comp_mode/options") .set(ubx_temp_comp_modes); get_tx_subtree() ->create<std::string>("temp_comp_mode/value") @@ -483,83 +501,84 @@ public: // Register TX properties //////////////////////////////////////////////////////////////////// get_tx_subtree()->create<std::string>("name").set("UBX TX"); - get_tx_subtree()->create<device_addr_t>("tune_args") - .set(device_addr_t()); - get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked") + get_tx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); + get_tx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&ubx_xcvr::get_locked, this, "TXLO")); - get_tx_subtree()->create<double>("gains/PGA0/value") - .set_coercer(std::bind(&ubx_xcvr::set_tx_gain, this, std::placeholders::_1)).set(0); - get_tx_subtree()->create<meta_range_t>("gains/PGA0/range") - .set(ubx_tx_gain_range); - get_tx_subtree()->create<double>("freq/value") + get_tx_subtree() + ->create<double>("gains/PGA0/value") + .set_coercer(std::bind(&ubx_xcvr::set_tx_gain, this, std::placeholders::_1)) + .set(0); + get_tx_subtree()->create<meta_range_t>("gains/PGA0/range").set(ubx_tx_gain_range); + get_tx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&ubx_xcvr::set_tx_freq, this, std::placeholders::_1)) .set(ubx_freq_range.start()); - get_tx_subtree()->create<meta_range_t>("freq/range") - .set(ubx_freq_range); - get_tx_subtree()->create<std::vector<std::string> >("antenna/options") + get_tx_subtree()->create<meta_range_t>("freq/range").set(ubx_freq_range); + get_tx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(ubx_tx_antennas); - get_tx_subtree()->create<std::string>("antenna/value") + get_tx_subtree() + ->create<std::string>("antenna/value") .set_coercer(std::bind(&ubx_xcvr::set_tx_ant, this, std::placeholders::_1)) .set(ubx_tx_antennas.at(0)); - get_tx_subtree()->create<std::string>("connection") - .set("QI"); - get_tx_subtree()->create<bool>("enabled") - .set(true); //always enabled - get_tx_subtree()->create<bool>("use_lo_offset") - .set(false); - get_tx_subtree()->create<double>("bandwidth/value") - .set(bw); - get_tx_subtree()->create<meta_range_t>("bandwidth/range") + get_tx_subtree()->create<std::string>("connection").set("QI"); + get_tx_subtree()->create<bool>("enabled").set(true); // always enabled + get_tx_subtree()->create<bool>("use_lo_offset").set(false); + get_tx_subtree()->create<double>("bandwidth/value").set(bw); + get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(freq_range_t(bw, bw)); - get_tx_subtree()->create<int64_t>("sync_delay") - .add_coerced_subscriber(std::bind(&ubx_xcvr::set_sync_delay, this, true, std::placeholders::_1)) + get_tx_subtree() + ->create<int64_t>("sync_delay") + .add_coerced_subscriber( + std::bind(&ubx_xcvr::set_sync_delay, this, true, std::placeholders::_1)) .set(0); //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// get_rx_subtree()->create<std::string>("name").set("UBX RX"); - get_rx_subtree()->create<device_addr_t>("tune_args") - .set(device_addr_t()); - get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + get_rx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); + get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&ubx_xcvr::get_locked, this, "RXLO")); - get_rx_subtree()->create<double>("gains/PGA0/value") + get_rx_subtree() + ->create<double>("gains/PGA0/value") .set_coercer(std::bind(&ubx_xcvr::set_rx_gain, this, std::placeholders::_1)) .set(0); - get_rx_subtree()->create<meta_range_t>("gains/PGA0/range") - .set(ubx_rx_gain_range); - get_rx_subtree()->create<double>("freq/value") + get_rx_subtree()->create<meta_range_t>("gains/PGA0/range").set(ubx_rx_gain_range); + get_rx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&ubx_xcvr::set_rx_freq, this, std::placeholders::_1)) .set(ubx_freq_range.start()); - get_rx_subtree()->create<meta_range_t>("freq/range") - .set(ubx_freq_range); - get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + get_rx_subtree()->create<meta_range_t>("freq/range").set(ubx_freq_range); + get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(ubx_rx_antennas); - get_rx_subtree()->create<std::string>("antenna/value") - .set_coercer(std::bind(&ubx_xcvr::set_rx_ant, this, std::placeholders::_1)).set("RX2"); - get_rx_subtree()->create<std::string>("connection") - .set("IQ"); - get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - get_rx_subtree()->create<double>("bandwidth/value") - .set(bw); - get_rx_subtree()->create<meta_range_t>("bandwidth/range") + get_rx_subtree() + ->create<std::string>("antenna/value") + .set_coercer(std::bind(&ubx_xcvr::set_rx_ant, this, std::placeholders::_1)) + .set("RX2"); + get_rx_subtree()->create<std::string>("connection").set("IQ"); + get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + get_rx_subtree()->create<bool>("use_lo_offset").set(false); + get_rx_subtree()->create<double>("bandwidth/value").set(bw); + get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(freq_range_t(bw, bw)); - get_rx_subtree()->create<int64_t>("sync_delay") - .add_coerced_subscriber(std::bind(&ubx_xcvr::set_sync_delay, this, false, std::placeholders::_1)) + get_rx_subtree() + ->create<int64_t>("sync_delay") + .add_coerced_subscriber( + std::bind(&ubx_xcvr::set_sync_delay, this, false, std::placeholders::_1)) .set(0); } virtual ~ubx_xcvr(void) { - UHD_SAFE_CALL - ( + UHD_SAFE_CALL( // Shutdown synthesizers - _txlo1->shutdown(); - _txlo2->shutdown(); - _rxlo1->shutdown(); + _txlo1->shutdown(); _txlo2->shutdown(); _rxlo1->shutdown(); _rxlo2->shutdown(); // Reset CPLD values @@ -578,17 +597,16 @@ public: set_gpio_field(TXLO2_SYNC, 0); set_gpio_field(RXLO1_SYNC, 0); set_gpio_field(RXLO1_SYNC, 0); - write_gpio(); - ) + write_gpio();) } private: - enum power_mode_t {PERFORMANCE,POWERSAVE}; - enum xcvr_mode_t {FDX, TDD, TX, RX, FAST_TDD}; + enum power_mode_t { PERFORMANCE, POWERSAVE }; + enum xcvr_mode_t { FDX, TDD, TX, RX, FAST_TDD }; /*********************************************************************** - * Helper Functions - **********************************************************************/ + * Helper Functions + **********************************************************************/ void write_spi_reg(spi_dest_t dest, uint32_t value) { boost::mutex::scoped_lock lock(_spi_mutex); @@ -600,7 +618,7 @@ private: { boost::mutex::scoped_lock lock(_spi_mutex); ROUTE_SPI(_iface, dest); - for(uint32_t value: values) + for (uint32_t value : values) WRITE_SPI(_iface, value); } @@ -611,8 +629,7 @@ private: void write_cpld_reg() { - if (_cpld_reg.value != _prev_cpld_value) - { + if (_cpld_reg.value != _prev_cpld_value) { write_spi_reg(CPLD, _cpld_reg.value); _prev_cpld_value = _cpld_reg.value; } @@ -621,15 +638,17 @@ private: void set_gpio_field(ubx_gpio_field_id_t id, uint32_t value) { // Look up field info - std::map<ubx_gpio_field_id_t,ubx_gpio_field_info_t>::iterator entry = _gpio_map.find(id); + std::map<ubx_gpio_field_id_t, ubx_gpio_field_info_t>::iterator entry = + _gpio_map.find(id); if (entry == _gpio_map.end()) return; ubx_gpio_field_info_t field_info = entry->second; if (field_info.direction == ubx_gpio_field_info_t::OUTPUT) return; - ubx_gpio_reg_t *reg = (field_info.unit == dboard_iface::UNIT_TX ? &_tx_gpio_reg : &_rx_gpio_reg); + ubx_gpio_reg_t* reg = + (field_info.unit == dboard_iface::UNIT_TX ? &_tx_gpio_reg : &_rx_gpio_reg); uint32_t _value = reg->value; - uint32_t _mask = reg->mask; + uint32_t _mask = reg->mask; // Set field and mask _value &= ~field_info.mask; @@ -637,10 +656,9 @@ private: _mask |= field_info.mask; // Mark whether register is dirty or not - if (_value != reg->value) - { + if (_value != reg->value) { reg->value = _value; - reg->mask = _mask; + reg->mask = _mask; reg->dirty = true; } } @@ -648,13 +666,15 @@ private: uint32_t get_gpio_field(ubx_gpio_field_id_t id) { // Look up field info - std::map<ubx_gpio_field_id_t,ubx_gpio_field_info_t>::iterator entry = _gpio_map.find(id); + std::map<ubx_gpio_field_id_t, ubx_gpio_field_info_t>::iterator entry = + _gpio_map.find(id); if (entry == _gpio_map.end()) return 0; ubx_gpio_field_info_t field_info = entry->second; - if (field_info.direction == ubx_gpio_field_info_t::INPUT) - { - ubx_gpio_reg_t *reg = (field_info.unit == dboard_iface::UNIT_TX ? &_tx_gpio_reg : &_rx_gpio_reg); + if (field_info.direction == ubx_gpio_field_info_t::INPUT) { + ubx_gpio_reg_t* reg = (field_info.unit == dboard_iface::UNIT_TX + ? &_tx_gpio_reg + : &_rx_gpio_reg); return (reg->value >> field_info.offset) & field_info.mask; } @@ -669,25 +689,24 @@ private: void write_gpio() { - if (_tx_gpio_reg.dirty) - { - _iface->set_gpio_out(dboard_iface::UNIT_TX, _tx_gpio_reg.value, _tx_gpio_reg.mask); + if (_tx_gpio_reg.dirty) { + _iface->set_gpio_out( + dboard_iface::UNIT_TX, _tx_gpio_reg.value, _tx_gpio_reg.mask); _tx_gpio_reg.dirty = false; - _tx_gpio_reg.mask = 0; + _tx_gpio_reg.mask = 0; } - if (_rx_gpio_reg.dirty) - { - _iface->set_gpio_out(dboard_iface::UNIT_RX, _rx_gpio_reg.value, _rx_gpio_reg.mask); + if (_rx_gpio_reg.dirty) { + _iface->set_gpio_out( + dboard_iface::UNIT_RX, _rx_gpio_reg.value, _rx_gpio_reg.mask); _rx_gpio_reg.dirty = false; - _rx_gpio_reg.mask = 0; + _rx_gpio_reg.mask = 0; } } void sync_phase(uhd::time_spec_t cmd_time, uhd::direction_t dir) { // Send phase sync signal only if the command time is set - if (cmd_time != uhd::time_spec_t(0.0)) - { + if (cmd_time != uhd::time_spec_t(0.0)) { // Delay 400 microseconds to allow LOs to lock cmd_time += uhd::time_spec_t(0.0004); @@ -703,14 +722,17 @@ private: // multiple of the system reference, and the device time has been // set on a PPS edge sampled by the system reference clock. - const double pfd_freq = _iface->get_clock_rate(dir == TX_DIRECTION ? dboard_iface::UNIT_TX : dboard_iface::UNIT_RX); - const double tick_rate = _iface->get_codec_rate(dir == TX_DIRECTION ? dboard_iface::UNIT_TX : dboard_iface::UNIT_RX); + const double pfd_freq = _iface->get_clock_rate( + dir == TX_DIRECTION ? dboard_iface::UNIT_TX : dboard_iface::UNIT_RX); + const double tick_rate = _iface->get_codec_rate( + dir == TX_DIRECTION ? dboard_iface::UNIT_TX : dboard_iface::UNIT_RX); const int64_t ticks_per_pfd_cycle = (int64_t)(tick_rate / pfd_freq); // Convert time to ticks int64_t ticks = cmd_time.to_ticks(tick_rate); // Align time to next falling edge of dboard clock - ticks += ticks_per_pfd_cycle - (ticks % ticks_per_pfd_cycle) + (ticks_per_pfd_cycle / 2); + ticks += ticks_per_pfd_cycle - (ticks % ticks_per_pfd_cycle) + + (ticks_per_pfd_cycle / 2); // Add any user specified delay ticks += dir == TX_DIRECTION ? _tx_sync_delay : _rx_sync_delay; // Set the command time @@ -718,20 +740,22 @@ private: _iface->set_command_time(cmd_time); // Assert SYNC - ubx_gpio_field_info_t lo1_field_info = _gpio_map.find(dir == TX_DIRECTION ? TXLO1_SYNC : RXLO1_SYNC)->second; - ubx_gpio_field_info_t lo2_field_info = _gpio_map.find(dir == TX_DIRECTION ? TXLO2_SYNC : RXLO2_SYNC)->second; + ubx_gpio_field_info_t lo1_field_info = + _gpio_map.find(dir == TX_DIRECTION ? TXLO1_SYNC : RXLO1_SYNC)->second; + ubx_gpio_field_info_t lo2_field_info = + _gpio_map.find(dir == TX_DIRECTION ? TXLO2_SYNC : RXLO2_SYNC)->second; uint16_t value = (1 << lo1_field_info.offset) | (1 << lo2_field_info.offset); - uint16_t mask = lo1_field_info.mask | lo2_field_info.mask; + uint16_t mask = lo1_field_info.mask | lo2_field_info.mask; dboard_iface::unit_t unit = lo1_field_info.unit; UHD_ASSERT_THROW(lo1_field_info.unit == lo2_field_info.unit); _iface->set_atr_reg(unit, gpio_atr::ATR_REG_IDLE, value, mask); - cmd_time += uhd::time_spec_t(1/pfd_freq); + cmd_time += uhd::time_spec_t(1 / pfd_freq); _iface->set_command_time(cmd_time); _iface->set_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY, value, mask); - cmd_time += uhd::time_spec_t(1/pfd_freq); + cmd_time += uhd::time_spec_t(1 / pfd_freq); _iface->set_command_time(cmd_time); _iface->set_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY, value, mask); - cmd_time += uhd::time_spec_t(1/pfd_freq); + cmd_time += uhd::time_spec_t(1 / pfd_freq); _iface->set_command_time(cmd_time); _iface->set_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX, value, mask); @@ -747,18 +771,15 @@ private: /*********************************************************************** * Board Control Handling **********************************************************************/ - sensor_value_t get_locked(const std::string &pll_name) + sensor_value_t get_locked(const std::string& pll_name) { boost::mutex::scoped_lock lock(_mutex); assert_has(ubx_plls, pll_name, "ubx pll name"); - if(pll_name == "TXLO") - { + if (pll_name == "TXLO") { _txlo_locked = (get_gpio_field(TX_LO_LOCKED) != 0); return sensor_value_t("TXLO", _txlo_locked, "locked", "unlocked"); - } - else if(pll_name == "RXLO") - { + } else if (pll_name == "RXLO") { _rxlo_locked = (get_gpio_field(RX_LO_LOCKED) != 0); return sensor_value_t("RXLO", _rxlo_locked, "locked", "unlocked"); } @@ -766,9 +787,9 @@ private: return sensor_value_t("Unknown", false, "locked", "unlocked"); } - std::string set_tx_ant(const std::string &ant) + std::string set_tx_ant(const std::string& ant) { - //validate input + // validate input assert_has(ubx_tx_antennas, ant, "ubx tx antenna name"); set_cpld_field(CAL_ENABLE, (ant == "CAL")); write_cpld_reg(); @@ -776,10 +797,10 @@ private: } // Set RX antennas - std::string set_rx_ant(const std::string &ant) + std::string set_rx_ant(const std::string& ant) { boost::mutex::scoped_lock lock(_mutex); - //validate input + // validate input assert_has(ubx_rx_antennas, ant, "ubx rx antenna name"); // There can be long transients on TX, so force on the TX PA @@ -788,14 +809,18 @@ private: // is set to TX/RX (to prevent higher noise floor on RX). // Setting the xcvr_mode to TDD will force on the PA when // not in powersave mode regardless of the board revision. - if (ant == "TX/RX") - { + if (ant == "TX/RX") { set_gpio_field(RX_ANT, 0); - // Force on TX PA for boards with high isolation or if the user sets the TDD mode - set_cpld_field(TXDRV_FORCEON, (_power_mode == POWERSAVE ? 0 : _high_isolation or _xcvr_mode == TDD ? 1 : 0)); + // Force on TX PA for boards with high isolation or if the user sets the TDD + // mode + set_cpld_field(TXDRV_FORCEON, + (_power_mode == POWERSAVE + ? 0 + : _high_isolation or _xcvr_mode == TDD ? 1 : 0)); } else { set_gpio_field(RX_ANT, 1); - set_cpld_field(TXDRV_FORCEON, (_power_mode == POWERSAVE ? 0 : 1)); // Keep PA on + set_cpld_field( + TXDRV_FORCEON, (_power_mode == POWERSAVE ? 0 : 1)); // Keep PA on } write_gpio(); write_cpld_reg(); @@ -809,12 +834,14 @@ private: double set_tx_gain(double gain) { boost::mutex::scoped_lock lock(_mutex); - gain = ubx_tx_gain_range.clip(gain); - int attn_code = int(std::floor(gain * 2)); + gain = ubx_tx_gain_range.clip(gain); + int attn_code = int(std::floor(gain * 2)); _ubx_tx_atten_val = ((attn_code & 0x3F) << 10); set_gpio_field(TX_GAIN, attn_code); write_gpio(); - UHD_LOGGER_TRACE("UBX") << boost::format("UBX TX Gain: %f dB, Code: %d, IO Bits 0x%04x") % gain % attn_code % _ubx_tx_atten_val ; + UHD_LOGGER_TRACE("UBX") + << boost::format("UBX TX Gain: %f dB, Code: %d, IO Bits 0x%04x") % gain + % attn_code % _ubx_tx_atten_val; _tx_gain = gain; return gain; } @@ -822,26 +849,28 @@ private: double set_rx_gain(double gain) { boost::mutex::scoped_lock lock(_mutex); - gain = ubx_rx_gain_range.clip(gain); - int attn_code = int(std::floor(gain * 2)); + gain = ubx_rx_gain_range.clip(gain); + int attn_code = int(std::floor(gain * 2)); _ubx_rx_atten_val = ((attn_code & 0x3F) << 10); set_gpio_field(RX_GAIN, attn_code); write_gpio(); - UHD_LOGGER_TRACE("UBX") << boost::format("UBX RX Gain: %f dB, Code: %d, IO Bits 0x%04x") % gain % attn_code % _ubx_rx_atten_val ; + UHD_LOGGER_TRACE("UBX") + << boost::format("UBX RX Gain: %f dB, Code: %d, IO Bits 0x%04x") % gain + % attn_code % _ubx_rx_atten_val; _rx_gain = gain; return gain; } /*********************************************************************** - * Frequency Handling - **********************************************************************/ + * Frequency Handling + **********************************************************************/ double set_tx_freq(double freq) { boost::mutex::scoped_lock lock(_mutex); double freq_lo1 = 0.0; double freq_lo2 = 0.0; double ref_freq = _iface->get_clock_rate(dboard_iface::UNIT_TX); - bool is_int_n = false; + bool is_int_n = false; /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to @@ -849,20 +878,18 @@ private: * performance on some mixers. The default is fractional tuning. */ property_tree::sptr subtree = this->get_tx_subtree(); - device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); - UHD_LOGGER_TRACE("UBX") << boost::format("UBX TX: the requested frequency is %f MHz") % (freq/1e6) ; + device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); + is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); + UHD_LOGGER_TRACE("UBX") + << boost::format("UBX TX: the requested frequency is %f MHz") % (freq / 1e6); double target_pfd_freq = _tx_target_pfd_freq; - if (is_int_n and tune_args.has_key("int_n_step")) - { + if (is_int_n and tune_args.has_key("int_n_step")) { target_pfd_freq = tune_args.cast<double>("int_n_step", _tx_target_pfd_freq); - if (target_pfd_freq > _tx_target_pfd_freq) - { + if (target_pfd_freq > _tx_target_pfd_freq) { UHD_LOGGER_WARNING("UBX") - << boost::format("Requested int_n_step of %f MHz too large, clipping to %f MHz") - % (target_pfd_freq/1e6) - % (_tx_target_pfd_freq/1e6) - ; + << boost::format( + "Requested int_n_step of %f MHz too large, clipping to %f MHz") + % (target_pfd_freq / 1e6) % (_tx_target_pfd_freq / 1e6); target_pfd_freq = _tx_target_pfd_freq; } } @@ -873,43 +900,39 @@ private: // Power up/down LOs if (_txlo1->is_shutdown()) _txlo1->power_up(); - if (_txlo2->is_shutdown() and (_power_mode == PERFORMANCE or freq < (500*fMHz))) + if (_txlo2->is_shutdown() and (_power_mode == PERFORMANCE or freq < (500 * fMHz))) _txlo2->power_up(); - else if (freq >= 500*fMHz and _power_mode == POWERSAVE) + else if (freq >= 500 * fMHz and _power_mode == POWERSAVE) _txlo2->shutdown(); // Set up LOs for phase sync if command time is set uhd::time_spec_t cmd_time = _iface->get_command_time(); - if (cmd_time != uhd::time_spec_t(0.0)) - { + if (cmd_time != uhd::time_spec_t(0.0)) { _txlo1->config_for_sync(true); if (not _txlo2->is_shutdown()) _txlo2->config_for_sync(true); - } - else - { + } else { _txlo1->config_for_sync(false); if (not _txlo2->is_shutdown()) _txlo2->config_for_sync(false); } // Set up registers for the requested frequency - if (freq < (500*fMHz)) - { + if (freq < (500 * fMHz)) { set_cpld_field(TXLO1_FSEL3, 0); set_cpld_field(TXLO1_FSEL2, 1); set_cpld_field(TXLO1_FSEL1, 0); set_cpld_field(TXLB_SEL, 1); set_cpld_field(TXHB_SEL, 0); // Set LO1 to IF of 2100 MHz (offset from RX IF to reduce leakage) - freq_lo1 = _txlo1->set_frequency(2100*fMHz, ref_freq, target_pfd_freq, is_int_n); + freq_lo1 = + _txlo1->set_frequency(2100 * fMHz, ref_freq, target_pfd_freq, is_int_n); _txlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM); // Set LO2 to IF minus desired frequency - freq_lo2 = _txlo2->set_frequency(freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n); + freq_lo2 = _txlo2->set_frequency( + freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n); _txlo2->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= (500*fMHz)) && (freq <= (800*fMHz))) - { + } else if ((freq >= (500 * fMHz)) && (freq <= (800 * fMHz))) { set_cpld_field(TXLO1_FSEL3, 0); set_cpld_field(TXLO1_FSEL2, 0); set_cpld_field(TXLO1_FSEL1, 1); @@ -917,9 +940,7 @@ private: set_cpld_field(TXHB_SEL, 1); freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _txlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq > (800*fMHz)) && (freq <= (1000*fMHz))) - { + } else if ((freq > (800 * fMHz)) && (freq <= (1000 * fMHz))) { set_cpld_field(TXLO1_FSEL3, 0); set_cpld_field(TXLO1_FSEL2, 0); set_cpld_field(TXLO1_FSEL1, 1); @@ -927,9 +948,7 @@ private: set_cpld_field(TXHB_SEL, 1); freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _txlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM); - } - else if ((freq > (1000*fMHz)) && (freq <= (2200*fMHz))) - { + } else if ((freq > (1000 * fMHz)) && (freq <= (2200 * fMHz))) { set_cpld_field(TXLO1_FSEL3, 0); set_cpld_field(TXLO1_FSEL2, 1); set_cpld_field(TXLO1_FSEL1, 0); @@ -937,9 +956,7 @@ private: set_cpld_field(TXHB_SEL, 1); freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _txlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq > (2200*fMHz)) && (freq <= (2500*fMHz))) - { + } else if ((freq > (2200 * fMHz)) && (freq <= (2500 * fMHz))) { set_cpld_field(TXLO1_FSEL3, 0); set_cpld_field(TXLO1_FSEL2, 1); set_cpld_field(TXLO1_FSEL1, 0); @@ -947,9 +964,7 @@ private: set_cpld_field(TXHB_SEL, 1); freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _txlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq > (2500*fMHz)) && (freq <= (6000*fMHz))) - { + } else if ((freq > (2500 * fMHz)) && (freq <= (6000 * fMHz))) { set_cpld_field(TXLO1_FSEL3, 1); set_cpld_field(TXLO1_FSEL2, 0); set_cpld_field(TXLO1_FSEL1, 0); @@ -962,35 +977,37 @@ private: // To reduce the number of commands issued to the device, write to the // SPI destination already addressed first. This avoids the writes to // the GPIO registers to route the SPI to the same destination. - switch (get_gpio_field(SPI_ADDR)) - { - case TXLO1: - _txlo1->commit(); - if (freq < (500*fMHz)) _txlo2->commit(); - write_cpld_reg(); - break; - case TXLO2: - if (freq < (500*fMHz)) _txlo2->commit(); - _txlo1->commit(); - write_cpld_reg(); - break; - default: - write_cpld_reg(); - _txlo1->commit(); - if (freq < (500*fMHz)) _txlo2->commit(); - break; + switch (get_gpio_field(SPI_ADDR)) { + case TXLO1: + _txlo1->commit(); + if (freq < (500 * fMHz)) + _txlo2->commit(); + write_cpld_reg(); + break; + case TXLO2: + if (freq < (500 * fMHz)) + _txlo2->commit(); + _txlo1->commit(); + write_cpld_reg(); + break; + default: + write_cpld_reg(); + _txlo1->commit(); + if (freq < (500 * fMHz)) + _txlo2->commit(); + break; } - if (cmd_time != uhd::time_spec_t(0.0) and _txlo1->can_sync()) - { + if (cmd_time != uhd::time_spec_t(0.0) and _txlo1->can_sync()) { sync_phase(cmd_time, TX_DIRECTION); } - _tx_freq = freq_lo1 - freq_lo2; + _tx_freq = freq_lo1 - freq_lo2; _txlo1_freq = freq_lo1; _txlo2_freq = freq_lo2; - UHD_LOGGER_TRACE("UBX") << boost::format("UBX TX: the actual frequency is %f MHz") % (_tx_freq/1e6) ; + UHD_LOGGER_TRACE("UBX") + << boost::format("UBX TX: the actual frequency is %f MHz") % (_tx_freq / 1e6); return _tx_freq; } @@ -1001,24 +1018,22 @@ private: double freq_lo1 = 0.0; double freq_lo2 = 0.0; double ref_freq = _iface->get_clock_rate(dboard_iface::UNIT_RX); - bool is_int_n = false; + bool is_int_n = false; - UHD_LOGGER_TRACE("UBX") << boost::format("UBX RX: the requested frequency is %f MHz") % (freq/1e6) ; + UHD_LOGGER_TRACE("UBX") + << boost::format("UBX RX: the requested frequency is %f MHz") % (freq / 1e6); property_tree::sptr subtree = this->get_rx_subtree(); - device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); + device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); + is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); double target_pfd_freq = _rx_target_pfd_freq; - if (is_int_n and tune_args.has_key("int_n_step")) - { + if (is_int_n and tune_args.has_key("int_n_step")) { target_pfd_freq = tune_args.cast<double>("int_n_step", _rx_target_pfd_freq); - if (target_pfd_freq > _rx_target_pfd_freq) - { + if (target_pfd_freq > _rx_target_pfd_freq) { UHD_LOGGER_WARNING("UBX") - << boost::format("Requested int_n_step of %f Mhz too large, clipping to %f MHz") - % (target_pfd_freq/1e6) - % (_rx_target_pfd_freq/1e6) - ; + << boost::format( + "Requested int_n_step of %f Mhz too large, clipping to %f MHz") + % (target_pfd_freq / 1e6) % (_rx_target_pfd_freq / 1e6); target_pfd_freq = _rx_target_pfd_freq; } } @@ -1029,29 +1044,25 @@ private: // Power up/down LOs if (_rxlo1->is_shutdown()) _rxlo1->power_up(); - if (_rxlo2->is_shutdown() and (_power_mode == PERFORMANCE or freq < 500*fMHz)) + if (_rxlo2->is_shutdown() and (_power_mode == PERFORMANCE or freq < 500 * fMHz)) _rxlo2->power_up(); - else if (freq >= 500*fMHz and _power_mode == POWERSAVE) + else if (freq >= 500 * fMHz and _power_mode == POWERSAVE) _rxlo2->shutdown(); // Set up LOs for phase sync if command time is set uhd::time_spec_t cmd_time = _iface->get_command_time(); - if (cmd_time != uhd::time_spec_t(0.0)) - { + if (cmd_time != uhd::time_spec_t(0.0)) { _rxlo1->config_for_sync(true); if (not _rxlo2->is_shutdown()) _rxlo2->config_for_sync(true); - } - else - { + } else { _rxlo1->config_for_sync(false); if (not _rxlo2->is_shutdown()) _rxlo2->config_for_sync(false); } // Work with frequencies - if (freq < 100*fMHz) - { + if (freq < 100 * fMHz) { set_cpld_field(SEL_LNA1, 0); set_cpld_field(SEL_LNA2, 1); set_cpld_field(RXLO1_FSEL3, 1); @@ -1059,15 +1070,16 @@ private: set_cpld_field(RXLO1_FSEL1, 0); set_cpld_field(RXLB_SEL, 1); set_cpld_field(RXHB_SEL, 0); - // Set LO1 to IF of 2380 MHz (2440 MHz filter center minus 60 MHz offset to minimize LO leakage) - freq_lo1 = _rxlo1->set_frequency(2380*fMHz, ref_freq, target_pfd_freq, is_int_n); + // Set LO1 to IF of 2380 MHz (2440 MHz filter center minus 60 MHz offset to + // minimize LO leakage) + freq_lo1 = + _rxlo1->set_frequency(2380 * fMHz, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM); // Set LO2 to IF minus desired frequency - freq_lo2 = _rxlo2->set_frequency(freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n); + freq_lo2 = _rxlo2->set_frequency( + freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n); _rxlo2->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= 100*fMHz) && (freq < 500*fMHz)) - { + } else if ((freq >= 100 * fMHz) && (freq < 500 * fMHz)) { set_cpld_field(SEL_LNA1, 0); set_cpld_field(SEL_LNA2, 1); set_cpld_field(RXLO1_FSEL3, 1); @@ -1076,14 +1088,14 @@ private: set_cpld_field(RXLB_SEL, 1); set_cpld_field(RXHB_SEL, 0); // Set LO1 to IF of 2440 (center of filter) - freq_lo1 = _rxlo1->set_frequency(2440*fMHz, ref_freq, target_pfd_freq, is_int_n); + freq_lo1 = + _rxlo1->set_frequency(2440 * fMHz, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM); // Set LO2 to IF minus desired frequency - freq_lo2 = _rxlo2->set_frequency(freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n); + freq_lo2 = _rxlo2->set_frequency( + freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= 500*fMHz) && (freq < 800*fMHz)) - { + } else if ((freq >= 500 * fMHz) && (freq < 800 * fMHz)) { set_cpld_field(SEL_LNA1, 0); set_cpld_field(SEL_LNA2, 1); set_cpld_field(RXLO1_FSEL3, 0); @@ -1093,9 +1105,7 @@ private: set_cpld_field(RXHB_SEL, 1); freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= 800*fMHz) && (freq < 1000*fMHz)) - { + } else if ((freq >= 800 * fMHz) && (freq < 1000 * fMHz)) { set_cpld_field(SEL_LNA1, 0); set_cpld_field(SEL_LNA2, 1); set_cpld_field(RXLO1_FSEL3, 0); @@ -1105,9 +1115,7 @@ private: set_cpld_field(RXHB_SEL, 1); freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM); - } - else if ((freq >= 1000*fMHz) && (freq < 1500*fMHz)) - { + } else if ((freq >= 1000 * fMHz) && (freq < 1500 * fMHz)) { set_cpld_field(SEL_LNA1, 0); set_cpld_field(SEL_LNA2, 1); set_cpld_field(RXLO1_FSEL3, 0); @@ -1117,9 +1125,7 @@ private: set_cpld_field(RXHB_SEL, 1); freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= 1500*fMHz) && (freq < 2200*fMHz)) - { + } else if ((freq >= 1500 * fMHz) && (freq < 2200 * fMHz)) { set_cpld_field(SEL_LNA1, 1); set_cpld_field(SEL_LNA2, 0); set_cpld_field(RXLO1_FSEL3, 0); @@ -1129,9 +1135,7 @@ private: set_cpld_field(RXHB_SEL, 1); freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= 2200*fMHz) && (freq < 2500*fMHz)) - { + } else if ((freq >= 2200 * fMHz) && (freq < 2500 * fMHz)) { set_cpld_field(SEL_LNA1, 1); set_cpld_field(SEL_LNA2, 0); set_cpld_field(RXLO1_FSEL3, 0); @@ -1141,9 +1145,7 @@ private: set_cpld_field(RXHB_SEL, 1); freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= 2500*fMHz) && (freq <= 6000*fMHz)) - { + } else if ((freq >= 2500 * fMHz) && (freq <= 6000 * fMHz)) { set_cpld_field(SEL_LNA1, 1); set_cpld_field(SEL_LNA2, 0); set_cpld_field(RXLO1_FSEL3, 1); @@ -1158,47 +1160,48 @@ private: // To reduce the number of commands issued to the device, write to the // SPI destination already addressed first. This avoids the writes to // the GPIO registers to route the SPI to the same destination. - switch (get_gpio_field(SPI_ADDR)) - { - case RXLO1: - _rxlo1->commit(); - if (freq < (500*fMHz)) _rxlo2->commit(); - write_cpld_reg(); - break; - case RXLO2: - if (freq < (500*fMHz)) _rxlo2->commit(); - _rxlo1->commit(); - write_cpld_reg(); - break; - default: - write_cpld_reg(); - _rxlo1->commit(); - if (freq < (500*fMHz)) _rxlo2->commit(); - break; + switch (get_gpio_field(SPI_ADDR)) { + case RXLO1: + _rxlo1->commit(); + if (freq < (500 * fMHz)) + _rxlo2->commit(); + write_cpld_reg(); + break; + case RXLO2: + if (freq < (500 * fMHz)) + _rxlo2->commit(); + _rxlo1->commit(); + write_cpld_reg(); + break; + default: + write_cpld_reg(); + _rxlo1->commit(); + if (freq < (500 * fMHz)) + _rxlo2->commit(); + break; } - if (cmd_time != uhd::time_spec_t(0.0) and _rxlo1->can_sync()) - { + if (cmd_time != uhd::time_spec_t(0.0) and _rxlo1->can_sync()) { sync_phase(cmd_time, RX_DIRECTION); } - _rx_freq = freq_lo1 - freq_lo2; + _rx_freq = freq_lo1 - freq_lo2; _rxlo1_freq = freq_lo1; _rxlo2_freq = freq_lo2; - UHD_LOGGER_TRACE("UBX") << boost::format("UBX RX: the actual frequency is %f MHz") % (_rx_freq/1e6) ; + UHD_LOGGER_TRACE("UBX") + << boost::format("UBX RX: the actual frequency is %f MHz") % (_rx_freq / 1e6); return _rx_freq; } /*********************************************************************** - * Setting Modes - **********************************************************************/ + * Setting Modes + **********************************************************************/ void set_power_mode(std::string mode) { boost::mutex::scoped_lock lock(_mutex); - if (mode == "performance") - { + if (mode == "performance") { // performance mode attempts to reduce tuning and settling time // as much as possible without adding noise. @@ -1231,9 +1234,7 @@ private: write_cpld_reg(); _power_mode = PERFORMANCE; - } - else if (mode == "powersave") - { + } else if (mode == "powersave") { // powersave mode attempts to use the least amount of power possible // by powering on components only when needed. Longer tuning and // settling times are expected. @@ -1270,26 +1271,17 @@ private: // the board is in TX, RX, or full duplex mode // to reduce power consumption and RF noise. boost::to_upper(mode); - if (mode == "FDX") - { + if (mode == "FDX") { _xcvr_mode = FDX; - } - else if (mode == "TDD") - { + } else if (mode == "TDD") { _xcvr_mode = TDD; set_cpld_field(TXDRV_FORCEON, 1); write_cpld_reg(); - } - else if (mode == "TX") - { + } else if (mode == "TX") { _xcvr_mode = TX; - } - else if (mode == "RX") - { + } else if (mode == "RX") { _xcvr_mode = RX; - } - else - { + } else { throw uhd::value_error("invalid xcvr_mode"); } } @@ -1321,14 +1313,14 @@ private: } /*********************************************************************** - * Variables - **********************************************************************/ + * Variables + **********************************************************************/ dboard_iface::sptr _iface; boost::mutex _spi_mutex; boost::mutex _mutex; ubx_cpld_reg_t _cpld_reg; uint32_t _prev_cpld_value; - std::map<ubx_gpio_field_id_t,ubx_gpio_field_info_t> _gpio_map; + std::map<ubx_gpio_field_id_t, ubx_gpio_field_info_t> _gpio_map; std::shared_ptr<max287x_iface> _txlo1; std::shared_ptr<max287x_iface> _txlo2; std::shared_ptr<max287x_iface> _rxlo1; @@ -1368,12 +1360,20 @@ static dboard_base::sptr make_ubx(dboard_base::ctor_args_t args) UHD_STATIC_BLOCK(reg_ubx_dboards) { - dboard_manager::register_dboard(UBX_PROTO_V3_RX_ID, UBX_PROTO_V3_TX_ID, &make_ubx, "UBX v0.3"); - dboard_manager::register_dboard(UBX_PROTO_V4_RX_ID, UBX_PROTO_V4_TX_ID, &make_ubx, "UBX v0.4"); - dboard_manager::register_dboard(UBX_V1_40MHZ_RX_ID, UBX_V1_40MHZ_TX_ID, &make_ubx, "UBX-40 v1"); - dboard_manager::register_dboard(UBX_V1_160MHZ_RX_ID, UBX_V1_160MHZ_TX_ID, &make_ubx, "UBX-160 v1"); - dboard_manager::register_dboard(UBX_V2_40MHZ_RX_ID, UBX_V2_40MHZ_TX_ID, &make_ubx, "UBX-40 v2"); - dboard_manager::register_dboard(UBX_V2_160MHZ_RX_ID, UBX_V2_160MHZ_TX_ID, &make_ubx, "UBX-160 v2"); - dboard_manager::register_dboard(UBX_LP_160MHZ_RX_ID, UBX_LP_160MHZ_TX_ID, &make_ubx, "UBX-160-LP"); - dboard_manager::register_dboard(UBX_TDD_160MHZ_RX_ID, UBX_TDD_160MHZ_TX_ID, &make_ubx, "UBX-TDD"); + dboard_manager::register_dboard( + UBX_PROTO_V3_RX_ID, UBX_PROTO_V3_TX_ID, &make_ubx, "UBX v0.3"); + dboard_manager::register_dboard( + UBX_PROTO_V4_RX_ID, UBX_PROTO_V4_TX_ID, &make_ubx, "UBX v0.4"); + dboard_manager::register_dboard( + UBX_V1_40MHZ_RX_ID, UBX_V1_40MHZ_TX_ID, &make_ubx, "UBX-40 v1"); + dboard_manager::register_dboard( + UBX_V1_160MHZ_RX_ID, UBX_V1_160MHZ_TX_ID, &make_ubx, "UBX-160 v1"); + dboard_manager::register_dboard( + UBX_V2_40MHZ_RX_ID, UBX_V2_40MHZ_TX_ID, &make_ubx, "UBX-40 v2"); + dboard_manager::register_dboard( + UBX_V2_160MHZ_RX_ID, UBX_V2_160MHZ_TX_ID, &make_ubx, "UBX-160 v2"); + dboard_manager::register_dboard( + UBX_LP_160MHZ_RX_ID, UBX_LP_160MHZ_TX_ID, &make_ubx, "UBX-160-LP"); + dboard_manager::register_dboard( + UBX_TDD_160MHZ_RX_ID, UBX_TDD_160MHZ_TX_ID, &make_ubx, "UBX-TDD"); } diff --git a/host/lib/usrp/dboard/db_unknown.cpp b/host/lib/usrp/dboard/db_unknown.cpp index 2640ad607..f6587b4b3 100644 --- a/host/lib/usrp/dboard/db_unknown.cpp +++ b/host/lib/usrp/dboard/db_unknown.cpp @@ -6,15 +6,15 @@ // #include <uhd/types/ranges.hpp> -#include <uhd/utils/assert_has.hpp> -#include <uhd/utils/static.hpp> -#include <uhd/utils/log.hpp> #include <uhd/usrp/dboard_base.hpp> #include <uhd/usrp/dboard_manager.hpp> +#include <uhd/utils/assert_has.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/static.hpp> #include <boost/assign/list_of.hpp> #include <boost/format.hpp> -#include <vector> #include <tuple> +#include <vector> using namespace uhd; using namespace uhd::usrp; @@ -23,26 +23,26 @@ using namespace boost::assign; /*********************************************************************** * Utility functions **********************************************************************/ -static void warn_if_old_rfx(const dboard_id_t &dboard_id, const std::string &xx){ - typedef std::tuple<std::string, dboard_id_t, dboard_id_t> old_ids_t; //name, rx_id, tx_id - static const std::vector<old_ids_t> old_rfx_ids = list_of - (old_ids_t("Flex 400 Classic", 0x0004, 0x0008)) - (old_ids_t("Flex 900 Classic", 0x0005, 0x0009)) - (old_ids_t("Flex 1200 Classic", 0x0006, 0x000a)) - (old_ids_t("Flex 1800 Classic", 0x0030, 0x0031)) - (old_ids_t("Flex 2400 Classic", 0x0007, 0x000b)) - ; - for(const old_ids_t &old_id: old_rfx_ids){ - std::string name; dboard_id_t rx_id, tx_id; +static void warn_if_old_rfx(const dboard_id_t& dboard_id, const std::string& xx) +{ + typedef std::tuple<std::string, dboard_id_t, dboard_id_t> + old_ids_t; // name, rx_id, tx_id + static const std::vector<old_ids_t> old_rfx_ids = + list_of(old_ids_t("Flex 400 Classic", 0x0004, 0x0008))( + old_ids_t("Flex 900 Classic", 0x0005, 0x0009))( + old_ids_t("Flex 1200 Classic", 0x0006, 0x000a))( + old_ids_t("Flex 1800 Classic", 0x0030, 0x0031))( + old_ids_t("Flex 2400 Classic", 0x0007, 0x000b)); + for (const old_ids_t& old_id : old_rfx_ids) { + std::string name; + dboard_id_t rx_id, tx_id; std::tie(name, rx_id, tx_id) = old_id; - if ( - (xx == "RX" and rx_id == dboard_id) or - (xx == "TX" and tx_id == dboard_id) - ) UHD_LOGGER_WARNING("unknown_db") << boost::format( - "Detected %s daughterboard %s\n" - "This board requires modification to use.\n" - "See the daughterboard application notes.\n" - ) % xx % name; + if ((xx == "RX" and rx_id == dboard_id) or (xx == "TX" and tx_id == dboard_id)) + UHD_LOGGER_WARNING("unknown_db") + << boost::format("Detected %s daughterboard %s\n" + "This board requires modification to use.\n" + "See the daughterboard application notes.\n") + % xx % name; } } @@ -50,12 +50,14 @@ static void warn_if_old_rfx(const dboard_id_t &dboard_id, const std::string &xx) * The unknown boards: * Like a basic board, but with only one subdev. **********************************************************************/ -class unknown_rx : public rx_dboard_base{ +class unknown_rx : public rx_dboard_base +{ public: unknown_rx(ctor_args_t args); }; -class unknown_tx : public tx_dboard_base{ +class unknown_tx : public tx_dboard_base +{ public: unknown_tx(ctor_args_t args); }; @@ -63,15 +65,18 @@ public: /*********************************************************************** * Register the unknown dboards **********************************************************************/ -static dboard_base::sptr make_unknown_rx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_unknown_rx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new unknown_rx(args)); } -static dboard_base::sptr make_unknown_tx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_unknown_tx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new unknown_tx(args)); } -UHD_STATIC_BLOCK(reg_unknown_dboards){ +UHD_STATIC_BLOCK(reg_unknown_dboards) +{ dboard_manager::register_dboard(0xfff0, &make_unknown_tx, "Unknown TX"); dboard_manager::register_dboard(0xfff1, &make_unknown_rx, "Unknown RX"); } @@ -79,71 +84,61 @@ UHD_STATIC_BLOCK(reg_unknown_dboards){ /*********************************************************************** * Unknown RX dboard **********************************************************************/ -unknown_rx::unknown_rx(ctor_args_t args) : rx_dboard_base(args){ +unknown_rx::unknown_rx(ctor_args_t args) : rx_dboard_base(args) +{ warn_if_old_rfx(this->get_rx_id(), "RX"); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - this->get_rx_subtree()->create<std::string>("name").set( - std::string(str(boost::format("%s - %s") - % get_rx_id().to_pp_string() - % get_subdev_name() - ))); - this->get_rx_subtree()->create<int>("gains"); //phony property so this dir exists - this->get_rx_subtree()->create<double>("freq/value") - .set(double(0.0)); - this->get_rx_subtree()->create<meta_range_t>("freq/range") + this->get_rx_subtree()->create<std::string>("name").set(std::string( + str(boost::format("%s - %s") % get_rx_id().to_pp_string() % get_subdev_name()))); + this->get_rx_subtree()->create<int>("gains"); // phony property so this dir exists + this->get_rx_subtree()->create<double>("freq/value").set(double(0.0)); + this->get_rx_subtree() + ->create<meta_range_t>("freq/range") .set(freq_range_t(double(0.0), double(0.0))); - this->get_rx_subtree()->create<std::string>("antenna/value") - .set(""); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree()->create<std::string>("antenna/value").set(""); + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(list_of("")); - this->get_rx_subtree()->create<int>("sensors"); //phony property so this dir exists - this->get_rx_subtree()->create<std::string>("connection") - .set("IQ"); - this->get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_rx_subtree()->create<double>("bandwidth/value") - .set(double(0.0)); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_rx_subtree()->create<int>("sensors"); // phony property so this dir exists + this->get_rx_subtree()->create<std::string>("connection").set("IQ"); + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_rx_subtree()->create<double>("bandwidth/value").set(double(0.0)); + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(freq_range_t(0.0, 0.0)); } /*********************************************************************** * Unknown TX dboard **********************************************************************/ -unknown_tx::unknown_tx(ctor_args_t args) : tx_dboard_base(args){ +unknown_tx::unknown_tx(ctor_args_t args) : tx_dboard_base(args) +{ warn_if_old_rfx(this->get_tx_id(), "TX"); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - this->get_tx_subtree()->create<std::string>("name").set( - std::string(str(boost::format("%s - %s") - % get_tx_id().to_pp_string() - % get_subdev_name() - ))); - this->get_tx_subtree()->create<int>("gains"); //phony property so this dir exists - this->get_tx_subtree()->create<double>("freq/value") - .set(double(0.0)); - this->get_tx_subtree()->create<meta_range_t>("freq/range") + this->get_tx_subtree()->create<std::string>("name").set(std::string( + str(boost::format("%s - %s") % get_tx_id().to_pp_string() % get_subdev_name()))); + this->get_tx_subtree()->create<int>("gains"); // phony property so this dir exists + this->get_tx_subtree()->create<double>("freq/value").set(double(0.0)); + this->get_tx_subtree() + ->create<meta_range_t>("freq/range") .set(freq_range_t(double(0.0), double(0.0))); - this->get_tx_subtree()->create<std::string>("antenna/value") - .set(""); - this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_tx_subtree()->create<std::string>("antenna/value").set(""); + this->get_tx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(list_of("")); - this->get_tx_subtree()->create<int>("sensors"); //phony property so this dir exists - this->get_tx_subtree()->create<std::string>("connection") - .set("IQ"); - this->get_tx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_tx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_tx_subtree()->create<double>("bandwidth/value") - .set(double(0.0)); - this->get_tx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_tx_subtree()->create<int>("sensors"); // phony property so this dir exists + this->get_tx_subtree()->create<std::string>("connection").set("IQ"); + this->get_tx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_tx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_tx_subtree()->create<double>("bandwidth/value").set(double(0.0)); + this->get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(freq_range_t(0.0, 0.0)); } diff --git a/host/lib/usrp/dboard/db_wbx_common.cpp b/host/lib/usrp/dboard/db_wbx_common.cpp index 4651de76a..df89e3779 100644 --- a/host/lib/usrp/dboard/db_wbx_common.cpp +++ b/host/lib/usrp/dboard/db_wbx_common.cpp @@ -22,23 +22,24 @@ using namespace boost::assign; /*********************************************************************** * Gain-related functions **********************************************************************/ -static int rx_pga0_gain_to_iobits(double &gain){ - //clip the input +static int rx_pga0_gain_to_iobits(double& gain) +{ + // clip the input gain = wbx_rx_gain_ranges["PGA0"].clip(gain); - //convert to attenuation + // convert to attenuation double attn = wbx_rx_gain_ranges["PGA0"].stop() - gain; - //calculate the attenuation - int attn_code = boost::math::iround(attn*2); - int iobits = ((~attn_code) << RX_ATTN_SHIFT) & RX_ATTN_MASK; + // calculate the attenuation + int attn_code = boost::math::iround(attn * 2); + int iobits = ((~attn_code) << RX_ATTN_SHIFT) & RX_ATTN_MASK; - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX RX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x" - ) % attn % attn_code % (iobits & RX_ATTN_MASK) % RX_ATTN_MASK ; + UHD_LOGGER_TRACE("WBX") + << boost::format("WBX RX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x") + % attn % attn_code % (iobits & RX_ATTN_MASK) % RX_ATTN_MASK; - //the actual gain setting - gain = wbx_rx_gain_ranges["PGA0"].stop() - double(attn_code)/2; + // the actual gain setting + gain = wbx_rx_gain_ranges["PGA0"].stop() - double(attn_code) / 2; return iobits; } @@ -47,9 +48,9 @@ static int rx_pga0_gain_to_iobits(double &gain){ /*********************************************************************** * WBX Common Implementation **********************************************************************/ -wbx_base::wbx_base(ctor_args_t args) : xcvr_dboard_base(args){ - - //enable the clocks that we need +wbx_base::wbx_base(ctor_args_t args) : xcvr_dboard_base(args) +{ + // enable the clocks that we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); @@ -59,38 +60,47 @@ wbx_base::wbx_base(ctor_args_t args) : xcvr_dboard_base(args){ uint16_t rx_id = this->get_rx_id().to_uint16(); this->get_rx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&wbx_base::get_locked, this, dboard_iface::UNIT_RX)); - for(const std::string &name: wbx_rx_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&wbx_base::set_rx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : wbx_rx_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer( + std::bind(&wbx_base::set_rx_gain, this, std::placeholders::_1, name)) .set(wbx_rx_gain_ranges[name].start()); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(wbx_rx_gain_ranges[name]); } this->get_rx_subtree()->create<std::string>("connection").set("IQ"); - this->get_rx_subtree()->create<bool>("enabled") - .add_coerced_subscriber(std::bind(&wbx_base::set_rx_enabled, this, std::placeholders::_1)) - .set(true); //start enabled + this->get_rx_subtree() + ->create<bool>("enabled") + .add_coerced_subscriber( + std::bind(&wbx_base::set_rx_enabled, this, std::placeholders::_1)) + .set(true); // start enabled this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); - //Value of bw low-pass dependent on board, we want complex double-sided + // Value of bw low-pass dependent on board, we want complex double-sided double bw = (rx_id != 0x0081) ? 20.0e6 : 60.0e6; - this->get_rx_subtree()->create<double>("bandwidth/value").set(2*bw); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(2*bw, 2*bw)); - this->get_tx_subtree()->create<double>("bandwidth/value").set(2*bw); - this->get_tx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(2*bw, 2*bw)); + this->get_rx_subtree()->create<double>("bandwidth/value").set(2 * bw); + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(2 * bw, 2 * bw)); + this->get_tx_subtree()->create<double>("bandwidth/value").set(2 * bw); + this->get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(2 * bw, 2 * bw)); this->get_tx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); - this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_tx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&wbx_base::get_locked, this, dboard_iface::UNIT_TX)); this->get_tx_subtree()->create<std::string>("connection").set("IQ"); this->get_tx_subtree()->create<bool>("use_lo_offset").set(false); // instantiate subclass foo - switch(rx_id) { + switch (rx_id) { case 0x0053: db_actual = wbx_versionx_sptr(new wbx_version2(this)); return; @@ -107,49 +117,54 @@ wbx_base::wbx_base(ctor_args_t args) : xcvr_dboard_base(args){ /* We didn't recognize the version of the board... */ UHD_THROW_INVALID_CODE_PATH(); } - } -wbx_base::~wbx_base(void){ +wbx_base::~wbx_base(void) +{ /* NOP */ } /*********************************************************************** * Enables **********************************************************************/ -void wbx_base::set_rx_enabled(bool enb){ +void wbx_base::set_rx_enabled(bool enb) +{ this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, - (enb)? RX_POWER_UP : RX_POWER_DOWN, RX_POWER_UP | RX_POWER_DOWN - ); + (enb) ? RX_POWER_UP : RX_POWER_DOWN, + RX_POWER_UP | RX_POWER_DOWN); } /*********************************************************************** * Gain Handling **********************************************************************/ -double wbx_base::set_rx_gain(double gain, const std::string &name){ +double wbx_base::set_rx_gain(double gain, const std::string& name) +{ assert_has(wbx_rx_gain_ranges.keys(), name, "wbx rx gain name"); - if(name == "PGA0"){ + if (name == "PGA0") { uint16_t io_bits = rx_pga0_gain_to_iobits(gain); - _rx_gains[name] = gain; + _rx_gains[name] = gain; - //write the new gain to rx gpio outputs + // write the new gain to rx gpio outputs this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, io_bits, RX_ATTN_MASK); - } - else UHD_THROW_INVALID_CODE_PATH(); - return _rx_gains[name]; //returned shadowed + } else + UHD_THROW_INVALID_CODE_PATH(); + return _rx_gains[name]; // returned shadowed } /*********************************************************************** * Tuning **********************************************************************/ -sensor_value_t wbx_base::get_locked(dboard_iface::unit_t unit){ +sensor_value_t wbx_base::get_locked(dboard_iface::unit_t unit) +{ const bool locked = (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0; return sensor_value_t("LO", locked, "locked", "unlocked"); } -void wbx_base::wbx_versionx::write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s) { - for(uint32_t reg: regs) { +void wbx_base::wbx_versionx::write_lo_regs( + dboard_iface::unit_t unit, const std::vector<uint32_t>& regs) +{ + for (uint32_t reg : regs) { self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, reg, 32); } } diff --git a/host/lib/usrp/dboard/db_wbx_common.hpp b/host/lib/usrp/dboard/db_wbx_common.hpp index 9425b041c..e7beabd8b 100644 --- a/host/lib/usrp/dboard/db_wbx_common.hpp +++ b/host/lib/usrp/dboard/db_wbx_common.hpp @@ -12,96 +12,93 @@ #include <uhdlib/usrp/common/adf435x.hpp> // LO Related -#define ADF435X_CE (1 << 3) -#define ADF435X_PDBRF (1 << 2) -#define ADF435X_MUXOUT (1 << 1) // INPUT!!! -#define LOCKDET_MASK (1 << 0) // INPUT!!! +#define ADF435X_CE (1 << 3) +#define ADF435X_PDBRF (1 << 2) +#define ADF435X_MUXOUT (1 << 1) // INPUT!!! +#define LOCKDET_MASK (1 << 0) // INPUT!!! // TX IO Pins -#define TX_PUP_5V (1 << 7) // enables 5.0V power supply -#define TX_PUP_3V (1 << 6) // enables 3.3V supply -#define TXMOD_EN (1 << 4) // on UNIT_TX, 1 enables TX Modulator +#define TX_PUP_5V (1 << 7) // enables 5.0V power supply +#define TX_PUP_3V (1 << 6) // enables 3.3V supply +#define TXMOD_EN (1 << 4) // on UNIT_TX, 1 enables TX Modulator // RX IO Pins -#define RX_PUP_5V (1 << 7) // enables 5.0V power supply -#define RX_PUP_3V (1 << 6) // enables 3.3V supply -#define RXBB_PDB (1 << 4) // on UNIT_RX, 1 powers up RX baseband +#define RX_PUP_5V (1 << 7) // enables 5.0V power supply +#define RX_PUP_3V (1 << 6) // enables 3.3V supply +#define RXBB_PDB (1 << 4) // on UNIT_RX, 1 powers up RX baseband // TX Attenuator Pins (v3 only) -#define TX_ATTN_16 (1 << 14) -#define TX_ATTN_8 (1 << 5) -#define TX_ATTN_4 (1 << 4) -#define TX_ATTN_2 (1 << 3) -#define TX_ATTN_1 (1 << 1) -#define TX_ATTN_MASK (TX_ATTN_16|TX_ATTN_8|TX_ATTN_4|TX_ATTN_2|TX_ATTN_1) // valid bits of TX Attenuator Control - -#define RX_ATTN_SHIFT 8 //lsb of RX Attenuator Control -#define RX_ATTN_MASK (63 << RX_ATTN_SHIFT) //valid bits of RX Attenuator Control +#define TX_ATTN_16 (1 << 14) +#define TX_ATTN_8 (1 << 5) +#define TX_ATTN_4 (1 << 4) +#define TX_ATTN_2 (1 << 3) +#define TX_ATTN_1 (1 << 1) +#define TX_ATTN_MASK \ + (TX_ATTN_16 | TX_ATTN_8 | TX_ATTN_4 | TX_ATTN_2 \ + | TX_ATTN_1) // valid bits of TX Attenuator Control + +#define RX_ATTN_SHIFT 8 // lsb of RX Attenuator Control +#define RX_ATTN_MASK (63 << RX_ATTN_SHIFT) // valid bits of RX Attenuator Control // Mixer functions -#define TX_MIXER_ENB (TXMOD_EN|ADF435X_PDBRF) // for v3, TXMOD_EN tied to ADF435X_PDBRF rather than separate -#define TX_MIXER_DIS 0 +#define TX_MIXER_ENB \ + (TXMOD_EN \ + | ADF435X_PDBRF) // for v3, TXMOD_EN tied to ADF435X_PDBRF rather than separate +#define TX_MIXER_DIS 0 -#define RX_MIXER_ENB (RXBB_PDB|ADF435X_PDBRF) -#define RX_MIXER_DIS 0 +#define RX_MIXER_ENB (RXBB_PDB | ADF435X_PDBRF) +#define RX_MIXER_DIS 0 // Power functions -#define TX_POWER_UP (TX_PUP_5V|TX_PUP_3V) // high enables power supply -#define TX_POWER_DOWN 0 +#define TX_POWER_UP (TX_PUP_5V | TX_PUP_3V) // high enables power supply +#define TX_POWER_DOWN 0 -#define RX_POWER_UP (RX_PUP_5V|RX_PUP_3V|ADF435X_CE) // high enables power supply -#define RX_POWER_DOWN 0 +#define RX_POWER_UP (RX_PUP_5V | RX_PUP_3V | ADF435X_CE) // high enables power supply +#define RX_POWER_DOWN 0 #include <uhd/types/dict.hpp> #include <uhd/types/ranges.hpp> #include <uhd/types/sensors.hpp> +#include <uhd/usrp/dboard_base.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/static.hpp> -#include <uhd/usrp/dboard_base.hpp> #include <boost/assign/list_of.hpp> #include <boost/format.hpp> -#include <memory> #include <boost/math/special_functions/round.hpp> #include <functional> +#include <memory> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { /*********************************************************************** * The WBX Common dboard constants **********************************************************************/ -static const uhd::dict<std::string, gain_range_t> wbx_rx_gain_ranges = boost::assign::map_list_of - ("PGA0", gain_range_t(0, 31.5, 0.5)); +static const uhd::dict<std::string, gain_range_t> wbx_rx_gain_ranges = + boost::assign::map_list_of("PGA0", gain_range_t(0, 31.5, 0.5)); -static const freq_range_t wbx_tx_lo_5dbm = boost::assign::list_of - (range_t(0.05e9, 1.7e9)) - (range_t(1.9e9, 2.2e9)) -; +static const freq_range_t wbx_tx_lo_5dbm = + boost::assign::list_of(range_t(0.05e9, 1.7e9))(range_t(1.9e9, 2.2e9)); -static const freq_range_t wbx_tx_lo_m1dbm = boost::assign::list_of - (range_t(1.7e9, 1.9e9)) -; +static const freq_range_t wbx_tx_lo_m1dbm = boost::assign::list_of(range_t(1.7e9, 1.9e9)); -static const freq_range_t wbx_rx_lo_5dbm = boost::assign::list_of - (range_t(0.05e9, 1.4e9)) -; +static const freq_range_t wbx_rx_lo_5dbm = boost::assign::list_of(range_t(0.05e9, 1.4e9)); -static const freq_range_t wbx_rx_lo_2dbm = boost::assign::list_of - (range_t(1.4e9, 2.2e9)) -; +static const freq_range_t wbx_rx_lo_2dbm = boost::assign::list_of(range_t(1.4e9, 2.2e9)); /*********************************************************************** * The WBX dboard base class **********************************************************************/ -class wbx_base : public xcvr_dboard_base{ +class wbx_base : public xcvr_dboard_base +{ public: wbx_base(ctor_args_t args); virtual ~wbx_base(void); protected: - virtual double set_rx_gain(double gain, const std::string &name); + virtual double set_rx_gain(double gain, const std::string& name); virtual void set_rx_enabled(bool enb); @@ -121,29 +118,32 @@ protected: * This class is an abstract base class, and thus is impossible to * instantiate. */ - class wbx_versionx { + class wbx_versionx + { public: - wbx_versionx():self_base(NULL) {} + wbx_versionx() : self_base(NULL) {} virtual ~wbx_versionx(void) {} - virtual double set_tx_gain(double gain, const std::string &name) = 0; - virtual void set_tx_enabled(bool enb) = 0; + virtual double set_tx_gain(double gain, const std::string& name) = 0; + virtual void set_tx_enabled(bool enb) = 0; virtual double set_lo_freq(dboard_iface::unit_t unit, double target_freq) = 0; /*! This is the registered instance of the wrapper class, wbx_base. */ - wbx_base *self_base; + wbx_base* self_base; - property_tree::sptr get_rx_subtree(void){ + property_tree::sptr get_rx_subtree(void) + { return self_base->get_rx_subtree(); } - property_tree::sptr get_tx_subtree(void){ + property_tree::sptr get_tx_subtree(void) + { return self_base->get_tx_subtree(); } adf435x_iface::sptr _txlo; adf435x_iface::sptr _rxlo; - void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s); + void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t>& regs); }; @@ -152,12 +152,13 @@ protected: * * Basically the original release of the DB. */ - class wbx_version2 : public wbx_versionx { + class wbx_version2 : public wbx_versionx + { public: - wbx_version2(wbx_base *_self_wbx_base); + wbx_version2(wbx_base* _self_wbx_base); virtual ~wbx_version2(void); - double set_tx_gain(double gain, const std::string &name); + double set_tx_gain(double gain, const std::string& name); void set_tx_enabled(bool enb); double set_lo_freq(dboard_iface::unit_t unit, double target_freq); }; @@ -167,12 +168,13 @@ protected: * * Fixed a problem with the AGC from Version 2. */ - class wbx_version3 : public wbx_versionx { + class wbx_version3 : public wbx_versionx + { public: - wbx_version3(wbx_base *_self_wbx_base); + wbx_version3(wbx_base* _self_wbx_base); virtual ~wbx_version3(void); - double set_tx_gain(double gain, const std::string &name); + double set_tx_gain(double gain, const std::string& name); void set_tx_enabled(bool enb); double set_lo_freq(dboard_iface::unit_t unit, double target_freq); }; @@ -182,12 +184,13 @@ protected: * * Upgrades the Frequnecy Synthensizer from ADF4350 to ADF4351. */ - class wbx_version4 : public wbx_versionx { + class wbx_version4 : public wbx_versionx + { public: - wbx_version4(wbx_base *_self_wbx_base); + wbx_version4(wbx_base* _self_wbx_base); virtual ~wbx_version4(void); - double set_tx_gain(double gain, const std::string &name); + double set_tx_gain(double gain, const std::string& name); void set_tx_enabled(bool enb); double set_lo_freq(dboard_iface::unit_t unit, double target_freq); }; @@ -208,6 +211,6 @@ protected: }; -}} //namespace uhd::usrp +}} // namespace uhd::usrp #endif /* INCLUDED_LIBUHD_USRP_DBOARD_DB_WBX_COMMON_HPP */ diff --git a/host/lib/usrp/dboard/db_wbx_simple.cpp b/host/lib/usrp/dboard/db_wbx_simple.cpp index 98eb96c1f..35675a081 100644 --- a/host/lib/usrp/dboard/db_wbx_simple.cpp +++ b/host/lib/usrp/dboard/db_wbx_simple.cpp @@ -6,11 +6,12 @@ // // Antenna constants -#define ANTSW_IO ((1 << 15)) // on UNIT_TX, 0 = TX, 1 = RX, on UNIT_RX 0 = main ant, 1 = RX2 -#define ANT_TX 0 //the tx line is transmitting -#define ANT_RX ANTSW_IO //the tx line is receiving -#define ANT_TXRX 0 //the rx line is on txrx -#define ANT_RX2 ANTSW_IO //the rx line in on rx2 +#define ANTSW_IO \ + ((1 << 15)) // on UNIT_TX, 0 = TX, 1 = RX, on UNIT_RX 0 = main ant, 1 = RX2 +#define ANT_TX 0 // the tx line is transmitting +#define ANT_RX ANTSW_IO // the tx line is receiving +#define ANT_TXRX 0 // the rx line is on txrx +#define ANT_RX2 ANTSW_IO // the rx line in on rx2 #include "db_wbx_common.hpp" #include <uhd/usrp/dboard_manager.hpp> @@ -34,122 +35,154 @@ static const std::vector<std::string> wbx_rx_antennas = list_of("TX/RX")("RX2")( /*********************************************************************** * The WBX simple implementation **********************************************************************/ -class wbx_simple : public wbx_base{ +class wbx_simple : public wbx_base +{ public: wbx_simple(ctor_args_t args); virtual ~wbx_simple(void); private: - void set_rx_ant(const std::string &ant); - void set_tx_ant(const std::string &ant); + void set_rx_ant(const std::string& ant); + void set_tx_ant(const std::string& ant); std::string _rx_ant; }; /*********************************************************************** * Register the WBX simple implementation **********************************************************************/ -static dboard_base::sptr make_wbx_simple(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_wbx_simple(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new wbx_simple(args)); } /*********************************************************************** * ID Numbers for WBX daughterboard combinations. **********************************************************************/ -UHD_STATIC_BLOCK(reg_wbx_simple_dboards){ +UHD_STATIC_BLOCK(reg_wbx_simple_dboards) +{ dboard_manager::register_dboard(0x0053, 0x0052, &make_wbx_simple, "WBX"); dboard_manager::register_dboard(0x0053, 0x004f, &make_wbx_simple, "WBX + Simple GDB"); dboard_manager::register_dboard(0x0057, 0x0056, &make_wbx_simple, "WBX v3"); - dboard_manager::register_dboard(0x0057, 0x004f, &make_wbx_simple, "WBX v3 + Simple GDB"); + dboard_manager::register_dboard( + 0x0057, 0x004f, &make_wbx_simple, "WBX v3 + Simple GDB"); dboard_manager::register_dboard(0x0063, 0x0062, &make_wbx_simple, "WBX v4"); - dboard_manager::register_dboard(0x0063, 0x004f, &make_wbx_simple, "WBX v4 + Simple GDB"); + dboard_manager::register_dboard( + 0x0063, 0x004f, &make_wbx_simple, "WBX v4 + Simple GDB"); dboard_manager::register_dboard(0x0081, 0x0080, &make_wbx_simple, "WBX-120"); - dboard_manager::register_dboard(0x0081, 0x004f, &make_wbx_simple, "WBX-120 + Simple GDB"); + dboard_manager::register_dboard( + 0x0081, 0x004f, &make_wbx_simple, "WBX-120 + Simple GDB"); } /*********************************************************************** * Structors **********************************************************************/ -wbx_simple::wbx_simple(ctor_args_t args) : wbx_base(args){ - +wbx_simple::wbx_simple(ctor_args_t args) : wbx_base(args) +{ //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// this->get_rx_subtree()->access<std::string>("name").set( - std::string(str(boost::format("%s+GDB") % this->get_rx_subtree()->access<std::string>("name").get() - ))); - this->get_rx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&wbx_simple::set_rx_ant, this, std::placeholders::_1)) + std::string(str(boost::format("%s+GDB") + % this->get_rx_subtree()->access<std::string>("name").get()))); + this->get_rx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&wbx_simple::set_rx_ant, this, std::placeholders::_1)) .set("RX2"); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(wbx_rx_antennas); //////////////////////////////////////////////////////////////////// // Register TX properties //////////////////////////////////////////////////////////////////// this->get_tx_subtree()->access<std::string>("name").set( - std::string(str(boost::format("%s+GDB") % this->get_tx_subtree()->access<std::string>("name").get() - ))); - this->get_tx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&wbx_simple::set_tx_ant, this, std::placeholders::_1)) + std::string(str(boost::format("%s+GDB") + % this->get_tx_subtree()->access<std::string>("name").get()))); + this->get_tx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&wbx_simple::set_tx_ant, this, std::placeholders::_1)) .set(wbx_tx_antennas.at(0)); - this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_tx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(wbx_tx_antennas); - //set the gpio directions and atr controls (antenna switches all under ATR) + // set the gpio directions and atr controls (antenna switches all under ATR) this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, ANTSW_IO, ANTSW_IO); this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, ANTSW_IO, ANTSW_IO); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, ANTSW_IO, ANTSW_IO); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, ANTSW_IO, ANTSW_IO); - //setup ATR for the antenna switches (constant) - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, ANT_RX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, ANT_RX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO); - - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, ANT_TXRX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO); + // setup ATR for the antenna switches (constant) + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, ANT_RX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, ANT_RX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO); + + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, ANT_TXRX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO); } -wbx_simple::~wbx_simple(void){ +wbx_simple::~wbx_simple(void) +{ /* NOP */ } /*********************************************************************** * Antennas **********************************************************************/ -void wbx_simple::set_rx_ant(const std::string &ant){ - //validate input +void wbx_simple::set_rx_ant(const std::string& ant) +{ + // validate input assert_has(wbx_rx_antennas, ant, "wbx rx antenna name"); - //shadow the setting + // shadow the setting _rx_ant = ant; - //write the new antenna setting to atr regs + // write the new antenna setting to atr regs if (_rx_ant == "CAL") { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_TXRX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TXRX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, ANT_TXRX, ANTSW_IO); - } - else { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, ((_rx_ant == "TX/RX")? ANT_TXRX : ANT_RX2), ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_TXRX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TXRX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, ANT_TXRX, ANTSW_IO); + } else { + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + ((_rx_ant == "TX/RX") ? ANT_TXRX : ANT_RX2), + ANTSW_IO); } } -void wbx_simple::set_tx_ant(const std::string &ant){ +void wbx_simple::set_tx_ant(const std::string& ant) +{ assert_has(wbx_tx_antennas, ant, "wbx tx antenna name"); - //write the new antenna setting to atr regs + // write the new antenna setting to atr regs if (ant == "CAL") { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX, ANTSW_IO); - } - else { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX, ANTSW_IO); + } else { + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO); } } diff --git a/host/lib/usrp/dboard/db_wbx_version2.cpp b/host/lib/usrp/dboard/db_wbx_version2.cpp index a8605942b..890436cdb 100644 --- a/host/lib/usrp/dboard/db_wbx_version2.cpp +++ b/host/lib/usrp/dboard/db_wbx_version2.cpp @@ -28,32 +28,32 @@ using namespace boost::assign; /*********************************************************************** * WBX Version 2 Constants **********************************************************************/ -static const uhd::dict<std::string, gain_range_t> wbx_v2_tx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 25, 0.05)) -; +static const uhd::dict<std::string, gain_range_t> wbx_v2_tx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 25, 0.05)); static const freq_range_t wbx_v2_freq_range(68.75e6, 2.2e9); /*********************************************************************** * Gain-related functions **********************************************************************/ -static double tx_pga0_gain_to_dac_volts(double &gain){ - //clip the input +static double tx_pga0_gain_to_dac_volts(double& gain) +{ + // clip the input gain = wbx_v2_tx_gain_ranges["PGA0"].clip(gain); - //voltage level constants + // voltage level constants static const double max_volts = 0.5, min_volts = 1.4; - static const double slope = (max_volts-min_volts)/wbx_v2_tx_gain_ranges["PGA0"].stop(); + static const double slope = + (max_volts - min_volts) / wbx_v2_tx_gain_ranges["PGA0"].stop(); - //calculate the voltage for the aux dac - double dac_volts = gain*slope + min_volts; + // calculate the voltage for the aux dac + double dac_volts = gain * slope + min_volts; - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX TX Gain: %f dB, dac_volts: %f V" - ) % gain % dac_volts ; + UHD_LOGGER_TRACE("WBX") << boost::format("WBX TX Gain: %f dB, dac_volts: %f V") % gain + % dac_volts; - //the actual gain setting - gain = (dac_volts - min_volts)/slope; + // the actual gain setting + gain = (dac_volts - min_volts) / slope; return dac_volts; } @@ -62,150 +62,206 @@ static double tx_pga0_gain_to_dac_volts(double &gain){ /*********************************************************************** * WBX Version 2 Implementation **********************************************************************/ -wbx_base::wbx_version2::wbx_version2(wbx_base *_self_wbx_base) { - //register our handle on the primary wbx_base instance +wbx_base::wbx_version2::wbx_version2(wbx_base* _self_wbx_base) +{ + // register our handle on the primary wbx_base instance self_base = _self_wbx_base; - _txlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_TX, std::placeholders::_1)); - _rxlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_RX, std::placeholders::_1)); + _txlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)); + _rxlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// this->get_rx_subtree()->create<std::string>("name").set("WBXv2 RX"); - this->get_rx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&wbx_base::wbx_version2::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) - .set((wbx_v2_freq_range.start() + wbx_v2_freq_range.stop())/2.0); + this->get_rx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind(&wbx_base::wbx_version2::set_lo_freq, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)) + .set((wbx_v2_freq_range.start() + wbx_v2_freq_range.stop()) / 2.0); this->get_rx_subtree()->create<meta_range_t>("freq/range").set(wbx_v2_freq_range); //////////////////////////////////////////////////////////////////// // Register TX properties //////////////////////////////////////////////////////////////////// this->get_tx_subtree()->create<std::string>("name").set("WBXv2 TX"); - for(const std::string &name: wbx_v2_tx_gain_ranges.keys()){ - self_base->get_tx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&wbx_base::wbx_version2::set_tx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : wbx_v2_tx_gain_ranges.keys()) { + self_base->get_tx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer(std::bind( + &wbx_base::wbx_version2::set_tx_gain, this, std::placeholders::_1, name)) .set(wbx_v2_tx_gain_ranges[name].start()); - self_base->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range") + self_base->get_tx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(wbx_v2_tx_gain_ranges[name]); } - this->get_tx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&wbx_base::wbx_version2::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) - .set((wbx_v2_freq_range.start() + wbx_v2_freq_range.stop())/2.0); + this->get_tx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind(&wbx_base::wbx_version2::set_lo_freq, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)) + .set((wbx_v2_freq_range.start() + wbx_v2_freq_range.stop()) / 2.0); this->get_tx_subtree()->create<meta_range_t>("freq/range").set(wbx_v2_freq_range); - this->get_tx_subtree()->create<bool>("enabled") - .add_coerced_subscriber(std::bind(&wbx_base::wbx_version2::set_tx_enabled, this, std::placeholders::_1)) - .set(true); //start enabled + this->get_tx_subtree() + ->create<bool>("enabled") + .add_coerced_subscriber(std::bind( + &wbx_base::wbx_version2::set_tx_enabled, this, std::placeholders::_1)) + .set(true); // start enabled - //set attenuator control bits + // set attenuator control bits int v2_iobits = ADF435X_CE; - int v2_tx_mod = TXMOD_EN|ADF435X_PDBRF; + int v2_tx_mod = TXMOD_EN | ADF435X_PDBRF; - //set the gpio directions and atr controls + // set the gpio directions and atr controls self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, v2_tx_mod); - self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXBB_PDB|ADF435X_PDBRF); - self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, TX_PUP_5V|TX_PUP_3V|v2_tx_mod|v2_iobits); - self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, RX_PUP_5V|RX_PUP_3V|ADF435X_CE|RXBB_PDB|ADF435X_PDBRF|RX_ATTN_MASK); - - //setup ATR for the mixer enables (always enabled to prevent phase slip between bursts) - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod); - - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXBB_PDB | ADF435X_PDBRF); + self_base->get_iface()->set_gpio_ddr( + dboard_iface::UNIT_TX, TX_PUP_5V | TX_PUP_3V | v2_tx_mod | v2_iobits); + self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, + RX_PUP_5V | RX_PUP_3V | ADF435X_CE | RXBB_PDB | ADF435X_PDBRF | RX_ATTN_MASK); + + // setup ATR for the mixer enables (always enabled to prevent phase slip between + // bursts) + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_IDLE, + v2_tx_mod, + TX_MIXER_DIS | v2_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_RX_ONLY, + v2_tx_mod, + TX_MIXER_DIS | v2_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + v2_tx_mod, + TX_MIXER_DIS | v2_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + v2_tx_mod, + TX_MIXER_DIS | v2_tx_mod); + + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_IDLE, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_TX_ONLY, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); } -wbx_base::wbx_version2::~wbx_version2(void){ +wbx_base::wbx_version2::~wbx_version2(void) +{ /* NOP */ } /*********************************************************************** * Enables **********************************************************************/ -void wbx_base::wbx_version2::set_tx_enabled(bool enb){ +void wbx_base::wbx_version2::set_tx_enabled(bool enb) +{ self_base->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, - (enb)? TX_POWER_UP | ADF435X_CE : TX_POWER_DOWN, TX_POWER_UP | TX_POWER_DOWN | ADF435X_CE); + (enb) ? TX_POWER_UP | ADF435X_CE : TX_POWER_DOWN, + TX_POWER_UP | TX_POWER_DOWN | ADF435X_CE); } /*********************************************************************** * Gain Handling **********************************************************************/ -double wbx_base::wbx_version2::set_tx_gain(double gain, const std::string &name){ +double wbx_base::wbx_version2::set_tx_gain(double gain, const std::string& name) +{ assert_has(wbx_v2_tx_gain_ranges.keys(), name, "wbx tx gain name"); - if(name == "PGA0"){ - double dac_volts = tx_pga0_gain_to_dac_volts(gain); + if (name == "PGA0") { + double dac_volts = tx_pga0_gain_to_dac_volts(gain); self_base->_tx_gains[name] = gain; - //write the new voltage to the aux dac - self_base->get_iface()->write_aux_dac(dboard_iface::UNIT_TX, dboard_iface::AUX_DAC_A, dac_volts); - } - else UHD_THROW_INVALID_CODE_PATH(); - return self_base->_tx_gains[name]; //shadowed + // write the new voltage to the aux dac + self_base->get_iface()->write_aux_dac( + dboard_iface::UNIT_TX, dboard_iface::AUX_DAC_A, dac_volts); + } else + UHD_THROW_INVALID_CODE_PATH(); + return self_base->_tx_gains[name]; // shadowed } /*********************************************************************** * Tuning **********************************************************************/ -double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { - //clip to tuning range +double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + // clip to tuning range target_freq = wbx_v2_freq_range.clip(target_freq); - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; + UHD_LOGGER_TRACE("WBX") << boost::format("WBX tune: target frequency %f MHz") + % (target_freq / 1e6); /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to * tune in Integer-N mode, which can result in better spur * performance on some mixers. The default is fractional tuning. */ - property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree() - : self_base->get_tx_subtree(); + property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) + ? self_base->get_rx_subtree() + : self_base->get_tx_subtree(); device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); - double reference_freq = self_base->get_iface()->get_clock_rate(unit); + bool is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); + double reference_freq = self_base->get_iface()->get_clock_rate(unit); - //Select the LO + // Select the LO adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo; lo_iface->set_reference_freq(reference_freq); - //The mixer has a divide-by-2 stage on the LO port so the synthesizer - //frequency must 2x the target frequency + // The mixer has a divide-by-2 stage on the LO port so the synthesizer + // frequency must 2x the target frequency double synth_target_freq = target_freq * 2; - //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) - lo_iface->set_prescaler(synth_target_freq > 3e9 ? - adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5); + // Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) + lo_iface->set_prescaler(synth_target_freq > 3e9 ? adf435x_iface::PRESCALER_8_9 + : adf435x_iface::PRESCALER_4_5); - //The feedback of the divided frequency must be disabled whenever the target frequency - //divided by the minimum PFD frequency cannot meet the minimum integer divider (N) value. - //If it is disabled, additional phase ambiguity will be introduced. With a minimum PFD - //frequency of 10 MHz, synthesizer frequencies below 230 MHz (LO frequencies below 115 MHz) - //will have too much ambiguity to synchronize. + // The feedback of the divided frequency must be disabled whenever the target + // frequency divided by the minimum PFD frequency cannot meet the minimum integer + // divider (N) value. If it is disabled, additional phase ambiguity will be + // introduced. With a minimum PFD frequency of 10 MHz, synthesizer frequencies below + // 230 MHz (LO frequencies below 115 MHz) will have too much ambiguity to synchronize. lo_iface->set_feedback_select( - (int(synth_target_freq / 10e6) >= lo_iface->get_int_range().start() ? - adf435x_iface::FB_SEL_DIVIDED : adf435x_iface::FB_SEL_FUNDAMENTAL)); + (int(synth_target_freq / 10e6) >= lo_iface->get_int_range().start() + ? adf435x_iface::FB_SEL_DIVIDED + : adf435x_iface::FB_SEL_FUNDAMENTAL)); double synth_actual_freq = lo_iface->set_frequency(synth_target_freq, is_int_n); - //The mixer has a divide-by-2 stage on the LO port so the synthesizer - //actual_freq must /2 the synth_actual_freq + // The mixer has a divide-by-2 stage on the LO port so the synthesizer + // actual_freq must /2 the synth_actual_freq double actual_freq = synth_actual_freq / 2; if (unit == dboard_iface::UNIT_RX) { - lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) ? - adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_2DBM); + lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) + ? adf435x_iface::OUTPUT_POWER_5DBM + : adf435x_iface::OUTPUT_POWER_2DBM); } else { - lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) ? - adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_M1DBM); + lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) + ? adf435x_iface::OUTPUT_POWER_5DBM + : adf435x_iface::OUTPUT_POWER_M1DBM); } - //Write to hardware + // Write to hardware lo_iface->commit(); return actual_freq; diff --git a/host/lib/usrp/dboard/db_wbx_version3.cpp b/host/lib/usrp/dboard/db_wbx_version3.cpp index 43c1d9652..51902b3aa 100644 --- a/host/lib/usrp/dboard/db_wbx_version3.cpp +++ b/host/lib/usrp/dboard/db_wbx_version3.cpp @@ -27,37 +27,34 @@ using namespace boost::assign; /*********************************************************************** * WBX Version 3 Constants **********************************************************************/ -static const uhd::dict<std::string, gain_range_t> wbx_v3_tx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 31, 1.0)) -; +static const uhd::dict<std::string, gain_range_t> wbx_v3_tx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 31, 1.0)); static const freq_range_t wbx_v3_freq_range(68.75e6, 2.2e9); /*********************************************************************** * Gain-related functions **********************************************************************/ -static int tx_pga0_gain_to_iobits(double &gain){ - //clip the input +static int tx_pga0_gain_to_iobits(double& gain) +{ + // clip the input gain = wbx_v3_tx_gain_ranges["PGA0"].clip(gain); - //convert to attenuation + // convert to attenuation double attn = wbx_v3_tx_gain_ranges["PGA0"].stop() - gain; - //calculate the attenuation + // calculate the attenuation int attn_code = boost::math::iround(attn); - int iobits = ( - (attn_code & 16 ? 0 : TX_ATTN_16) | - (attn_code & 8 ? 0 : TX_ATTN_8) | - (attn_code & 4 ? 0 : TX_ATTN_4) | - (attn_code & 2 ? 0 : TX_ATTN_2) | - (attn_code & 1 ? 0 : TX_ATTN_1) - ) & TX_ATTN_MASK; - - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x" - ) % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK ; - - //the actual gain setting + int iobits = ((attn_code & 16 ? 0 : TX_ATTN_16) | (attn_code & 8 ? 0 : TX_ATTN_8) + | (attn_code & 4 ? 0 : TX_ATTN_4) | (attn_code & 2 ? 0 : TX_ATTN_2) + | (attn_code & 1 ? 0 : TX_ATTN_1)) + & TX_ATTN_MASK; + + UHD_LOGGER_TRACE("WBX") + << boost::format("WBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x") + % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK; + + // the actual gain setting gain = wbx_v3_tx_gain_ranges["PGA0"].stop() - double(attn_code); return iobits; @@ -67,85 +64,112 @@ static int tx_pga0_gain_to_iobits(double &gain){ /*********************************************************************** * WBX Common Implementation **********************************************************************/ -wbx_base::wbx_version3::wbx_version3(wbx_base *_self_wbx_base) { - //register our handle on the primary wbx_base instance +wbx_base::wbx_version3::wbx_version3(wbx_base* _self_wbx_base) +{ + // register our handle on the primary wbx_base instance self_base = _self_wbx_base; - _txlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_TX, std::placeholders::_1)); - _rxlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_RX, std::placeholders::_1)); + _txlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)); + _rxlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// this->get_rx_subtree()->create<std::string>("name").set("WBXv3 RX"); - this->get_rx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&wbx_base::wbx_version3::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) - .set((wbx_v3_freq_range.start() + wbx_v3_freq_range.stop())/2.0); + this->get_rx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind(&wbx_base::wbx_version3::set_lo_freq, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)) + .set((wbx_v3_freq_range.start() + wbx_v3_freq_range.stop()) / 2.0); this->get_rx_subtree()->create<meta_range_t>("freq/range").set(wbx_v3_freq_range); //////////////////////////////////////////////////////////////////// // Register TX properties //////////////////////////////////////////////////////////////////// this->get_tx_subtree()->create<std::string>("name").set("WBXv3 TX"); - for(const std::string &name: wbx_v3_tx_gain_ranges.keys()){ - self_base->get_tx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&wbx_base::wbx_version3::set_tx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : wbx_v3_tx_gain_ranges.keys()) { + self_base->get_tx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer(std::bind( + &wbx_base::wbx_version3::set_tx_gain, this, std::placeholders::_1, name)) .set(wbx_v3_tx_gain_ranges[name].start()); - self_base->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range") + self_base->get_tx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(wbx_v3_tx_gain_ranges[name]); } - this->get_tx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&wbx_base::wbx_version3::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) - .set((wbx_v3_freq_range.start() + wbx_v3_freq_range.stop())/2.0); + this->get_tx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind(&wbx_base::wbx_version3::set_lo_freq, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)) + .set((wbx_v3_freq_range.start() + wbx_v3_freq_range.stop()) / 2.0); this->get_tx_subtree()->create<meta_range_t>("freq/range").set(wbx_v3_freq_range); - this->get_tx_subtree()->create<bool>("enabled") - .add_coerced_subscriber(std::bind(&wbx_base::wbx_version3::set_tx_enabled, this, std::placeholders::_1)) - .set(true); //start enabled + this->get_tx_subtree() + ->create<bool>("enabled") + .add_coerced_subscriber(std::bind( + &wbx_base::wbx_version3::set_tx_enabled, this, std::placeholders::_1)) + .set(true); // start enabled - //set attenuator control bits + // set attenuator control bits int v3_iobits = TX_ATTN_MASK; int v3_tx_mod = ADF435X_PDBRF; - //set the gpio directions and atr controls - self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, \ - v3_tx_mod|v3_iobits); - self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, \ - RXBB_PDB|ADF435X_PDBRF); - self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, \ - TX_PUP_5V|TX_PUP_3V|v3_tx_mod|v3_iobits); - self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, \ - RX_PUP_5V|RX_PUP_3V|ADF435X_CE|RXBB_PDB|ADF435X_PDBRF|RX_ATTN_MASK); - - //setup ATR for the mixer enables (always enabled to prevent phase - //slip between bursts). set TX gain iobits to min gain (max attenuation) - //when RX_ONLY or IDLE to suppress LO leakage - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_IDLE, v3_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_RX_ONLY, v3_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_TX_ONLY, v3_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_FULL_DUPLEX, v3_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); - - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_IDLE, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_TX_ONLY, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_RX_ONLY, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_FULL_DUPLEX, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); + // set the gpio directions and atr controls + self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, v3_tx_mod | v3_iobits); + self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXBB_PDB | ADF435X_PDBRF); + self_base->get_iface()->set_gpio_ddr( + dboard_iface::UNIT_TX, TX_PUP_5V | TX_PUP_3V | v3_tx_mod | v3_iobits); + self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, + RX_PUP_5V | RX_PUP_3V | ADF435X_CE | RXBB_PDB | ADF435X_PDBRF | RX_ATTN_MASK); + + // setup ATR for the mixer enables (always enabled to prevent phase + // slip between bursts). set TX gain iobits to min gain (max attenuation) + // when RX_ONLY or IDLE to suppress LO leakage + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_IDLE, + v3_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_RX_ONLY, + v3_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + v3_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + v3_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); + + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_IDLE, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_TX_ONLY, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); } -wbx_base::wbx_version3::~wbx_version3(void){ +wbx_base::wbx_version3::~wbx_version3(void) +{ /* NOP */ } @@ -153,90 +177,100 @@ wbx_base::wbx_version3::~wbx_version3(void){ /*********************************************************************** * Enables **********************************************************************/ -void wbx_base::wbx_version3::set_tx_enabled(bool enb){ +void wbx_base::wbx_version3::set_tx_enabled(bool enb) +{ self_base->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, - (enb)? TX_POWER_UP | ADF435X_CE : TX_POWER_DOWN, TX_POWER_UP | TX_POWER_DOWN | 0); + (enb) ? TX_POWER_UP | ADF435X_CE : TX_POWER_DOWN, + TX_POWER_UP | TX_POWER_DOWN | 0); } /*********************************************************************** * Gain Handling **********************************************************************/ -double wbx_base::wbx_version3::set_tx_gain(double gain, const std::string &name){ +double wbx_base::wbx_version3::set_tx_gain(double gain, const std::string& name) +{ assert_has(wbx_v3_tx_gain_ranges.keys(), name, "wbx tx gain name"); - if(name == "PGA0"){ + if (name == "PGA0") { uint16_t io_bits = tx_pga0_gain_to_iobits(gain); self_base->_tx_gains[name] = gain; - //write the new gain to tx gpio outputs - //Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR states - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK); - } - else UHD_THROW_INVALID_CODE_PATH(); - return self_base->_tx_gains[name]; //shadow + // write the new gain to tx gpio outputs + // Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR + // states + self_base->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK); + self_base->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK); + } else + UHD_THROW_INVALID_CODE_PATH(); + return self_base->_tx_gains[name]; // shadow } /*********************************************************************** * Tuning **********************************************************************/ -double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { - //clip to tuning range +double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + // clip to tuning range target_freq = wbx_v3_freq_range.clip(target_freq); - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; + UHD_LOGGER_TRACE("WBX") << boost::format("WBX tune: target frequency %f MHz") + % (target_freq / 1e6); /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to * tune in Integer-N mode, which can result in better spur * performance on some mixers. The default is fractional tuning. */ - property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree() - : self_base->get_tx_subtree(); + property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) + ? self_base->get_rx_subtree() + : self_base->get_tx_subtree(); device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); - double reference_freq = self_base->get_iface()->get_clock_rate(unit); + bool is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); + double reference_freq = self_base->get_iface()->get_clock_rate(unit); - //Select the LO + // Select the LO adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo; lo_iface->set_reference_freq(reference_freq); - //The mixer has a divide-by-2 stage on the LO port so the synthesizer - //frequency must 2x the target frequency + // The mixer has a divide-by-2 stage on the LO port so the synthesizer + // frequency must 2x the target frequency double synth_target_freq = target_freq * 2; - //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) - lo_iface->set_prescaler(synth_target_freq > 3e9 ? - adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5); + // Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) + lo_iface->set_prescaler(synth_target_freq > 3e9 ? adf435x_iface::PRESCALER_8_9 + : adf435x_iface::PRESCALER_4_5); - //The feedback of the divided frequency must be disabled whenever the target frequency - //divided by the minimum PFD frequency cannot meet the minimum integer divider (N) value. - //If it is disabled, additional phase ambiguity will be introduced. With a minimum PFD - //frequency of 10 MHz, synthesizer frequencies below 230 MHz (LO frequencies below 115 MHz) - //will have too much ambiguity to synchronize. + // The feedback of the divided frequency must be disabled whenever the target + // frequency divided by the minimum PFD frequency cannot meet the minimum integer + // divider (N) value. If it is disabled, additional phase ambiguity will be + // introduced. With a minimum PFD frequency of 10 MHz, synthesizer frequencies below + // 230 MHz (LO frequencies below 115 MHz) will have too much ambiguity to synchronize. lo_iface->set_feedback_select( - (int(synth_target_freq / 10e6) >= lo_iface->get_int_range().start() ? - adf435x_iface::FB_SEL_DIVIDED : adf435x_iface::FB_SEL_FUNDAMENTAL)); + (int(synth_target_freq / 10e6) >= lo_iface->get_int_range().start() + ? adf435x_iface::FB_SEL_DIVIDED + : adf435x_iface::FB_SEL_FUNDAMENTAL)); double synth_actual_freq = lo_iface->set_frequency(synth_target_freq, is_int_n); - //The mixer has a divide-by-2 stage on the LO port so the synthesizer - //actual_freq must /2 the synth_actual_freq + // The mixer has a divide-by-2 stage on the LO port so the synthesizer + // actual_freq must /2 the synth_actual_freq double actual_freq = synth_actual_freq / 2; if (unit == dboard_iface::UNIT_RX) { - lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) ? - adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_2DBM); + lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) + ? adf435x_iface::OUTPUT_POWER_5DBM + : adf435x_iface::OUTPUT_POWER_2DBM); } else { - lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) ? - adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_M1DBM); + lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) + ? adf435x_iface::OUTPUT_POWER_5DBM + : adf435x_iface::OUTPUT_POWER_M1DBM); } - //Write to hardware + // Write to hardware lo_iface->commit(); return actual_freq; diff --git a/host/lib/usrp/dboard/db_wbx_version4.cpp b/host/lib/usrp/dboard/db_wbx_version4.cpp index 6755fb6eb..54c0a9c21 100644 --- a/host/lib/usrp/dboard/db_wbx_version4.cpp +++ b/host/lib/usrp/dboard/db_wbx_version4.cpp @@ -27,9 +27,8 @@ using namespace boost::assign; /*********************************************************************** * WBX Version 4 Constants **********************************************************************/ -static const uhd::dict<std::string, gain_range_t> wbx_v4_tx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 31, 1.0)) -; +static const uhd::dict<std::string, gain_range_t> wbx_v4_tx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 31, 1.0)); static const freq_range_t wbx_v4_freq_range(25.0e6, 2.2e9); @@ -37,28 +36,26 @@ static const freq_range_t wbx_v4_freq_range(25.0e6, 2.2e9); /*********************************************************************** * Gain-related functions **********************************************************************/ -static int tx_pga0_gain_to_iobits(double &gain){ - //clip the input +static int tx_pga0_gain_to_iobits(double& gain) +{ + // clip the input gain = wbx_v4_tx_gain_ranges["PGA0"].clip(gain); - //convert to attenuation + // convert to attenuation double attn = wbx_v4_tx_gain_ranges["PGA0"].stop() - gain; - //calculate the attenuation + // calculate the attenuation int attn_code = boost::math::iround(attn); - int iobits = ( - (attn_code & 16 ? 0 : TX_ATTN_16) | - (attn_code & 8 ? 0 : TX_ATTN_8) | - (attn_code & 4 ? 0 : TX_ATTN_4) | - (attn_code & 2 ? 0 : TX_ATTN_2) | - (attn_code & 1 ? 0 : TX_ATTN_1) - ) & TX_ATTN_MASK; - - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x" - ) % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK ; - - //the actual gain setting + int iobits = ((attn_code & 16 ? 0 : TX_ATTN_16) | (attn_code & 8 ? 0 : TX_ATTN_8) + | (attn_code & 4 ? 0 : TX_ATTN_4) | (attn_code & 2 ? 0 : TX_ATTN_2) + | (attn_code & 1 ? 0 : TX_ATTN_1)) + & TX_ATTN_MASK; + + UHD_LOGGER_TRACE("WBX") + << boost::format("WBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x") + % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK; + + // the actual gain setting gain = wbx_v4_tx_gain_ranges["PGA0"].stop() - double(attn_code); return iobits; @@ -68,91 +65,122 @@ static int tx_pga0_gain_to_iobits(double &gain){ /*********************************************************************** * WBX Common Implementation **********************************************************************/ -wbx_base::wbx_version4::wbx_version4(wbx_base *_self_wbx_base) { - //register our handle on the primary wbx_base instance +wbx_base::wbx_version4::wbx_version4(wbx_base* _self_wbx_base) +{ + // register our handle on the primary wbx_base instance self_base = _self_wbx_base; - _txlo = adf435x_iface::make_adf4351(std::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_TX, std::placeholders::_1)); - _rxlo = adf435x_iface::make_adf4351(std::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_RX, std::placeholders::_1)); + _txlo = adf435x_iface::make_adf4351(std::bind(&wbx_base::wbx_versionx::write_lo_regs, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)); + _rxlo = adf435x_iface::make_adf4351(std::bind(&wbx_base::wbx_versionx::write_lo_regs, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// uint16_t rx_id = _self_wbx_base->get_rx_id().to_uint16(); - if(rx_id == 0x0063) this->get_rx_subtree()->create<std::string>("name").set("WBXv4 RX"); - else if(rx_id == 0x0081) this->get_rx_subtree()->create<std::string>("name").set("WBX-120 RX"); - this->get_rx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&wbx_base::wbx_version4::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) - .set((wbx_v4_freq_range.start() + wbx_v4_freq_range.stop())/2.0); + if (rx_id == 0x0063) + this->get_rx_subtree()->create<std::string>("name").set("WBXv4 RX"); + else if (rx_id == 0x0081) + this->get_rx_subtree()->create<std::string>("name").set("WBX-120 RX"); + this->get_rx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind(&wbx_base::wbx_version4::set_lo_freq, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)) + .set((wbx_v4_freq_range.start() + wbx_v4_freq_range.stop()) / 2.0); this->get_rx_subtree()->create<meta_range_t>("freq/range").set(wbx_v4_freq_range); //////////////////////////////////////////////////////////////////// // Register TX properties //////////////////////////////////////////////////////////////////// - //get_tx_id() will always return GDB ID, so use RX ID to determine WBXv4 vs. WBX-120 - if(rx_id == 0x0063) this->get_tx_subtree()->create<std::string>("name").set("WBXv4 TX"); - else if(rx_id == 0x0081) this->get_tx_subtree()->create<std::string>("name").set("WBX-120 TX"); - for(const std::string &name: wbx_v4_tx_gain_ranges.keys()){ - self_base->get_tx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&wbx_base::wbx_version4::set_tx_gain, this, std::placeholders::_1, name)) + // get_tx_id() will always return GDB ID, so use RX ID to determine WBXv4 vs. WBX-120 + if (rx_id == 0x0063) + this->get_tx_subtree()->create<std::string>("name").set("WBXv4 TX"); + else if (rx_id == 0x0081) + this->get_tx_subtree()->create<std::string>("name").set("WBX-120 TX"); + for (const std::string& name : wbx_v4_tx_gain_ranges.keys()) { + self_base->get_tx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer(std::bind( + &wbx_base::wbx_version4::set_tx_gain, this, std::placeholders::_1, name)) .set(wbx_v4_tx_gain_ranges[name].start()); - self_base->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range") + self_base->get_tx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(wbx_v4_tx_gain_ranges[name]); } - this->get_tx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&wbx_base::wbx_version4::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) - .set((wbx_v4_freq_range.start() + wbx_v4_freq_range.stop())/2.0); + this->get_tx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind(&wbx_base::wbx_version4::set_lo_freq, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)) + .set((wbx_v4_freq_range.start() + wbx_v4_freq_range.stop()) / 2.0); this->get_tx_subtree()->create<meta_range_t>("freq/range").set(wbx_v4_freq_range); - this->get_tx_subtree()->create<bool>("enabled") - .add_coerced_subscriber(std::bind(&wbx_base::wbx_version4::set_tx_enabled, this, std::placeholders::_1)) - .set(true); //start enabled + this->get_tx_subtree() + ->create<bool>("enabled") + .add_coerced_subscriber(std::bind( + &wbx_base::wbx_version4::set_tx_enabled, this, std::placeholders::_1)) + .set(true); // start enabled - //set attenuator control bits + // set attenuator control bits int v4_iobits = TX_ATTN_MASK; int v4_tx_mod = ADF435X_PDBRF; - //set the gpio directions and atr controls - self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, \ - v4_tx_mod|v4_iobits); - self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, \ - RXBB_PDB|ADF435X_PDBRF); - self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, \ - TX_PUP_5V|TX_PUP_3V|v4_tx_mod|v4_iobits); - self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, \ - RX_PUP_5V|RX_PUP_3V|ADF435X_CE|RXBB_PDB|ADF435X_PDBRF|RX_ATTN_MASK); - - //setup ATR for the mixer enables (always enabled to prevent phase slip - //between bursts) set TX gain iobits to min gain (max attenuation) when - //RX_ONLY or IDLE to suppress LO leakage - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_IDLE, v4_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_RX_ONLY, v4_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_TX_ONLY, v4_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_FULL_DUPLEX, v4_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); - - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_IDLE, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_TX_ONLY, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_RX_ONLY, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_FULL_DUPLEX, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); + // set the gpio directions and atr controls + self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, v4_tx_mod | v4_iobits); + self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXBB_PDB | ADF435X_PDBRF); + self_base->get_iface()->set_gpio_ddr( + dboard_iface::UNIT_TX, TX_PUP_5V | TX_PUP_3V | v4_tx_mod | v4_iobits); + self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, + RX_PUP_5V | RX_PUP_3V | ADF435X_CE | RXBB_PDB | ADF435X_PDBRF | RX_ATTN_MASK); + + // setup ATR for the mixer enables (always enabled to prevent phase slip + // between bursts) set TX gain iobits to min gain (max attenuation) when + // RX_ONLY or IDLE to suppress LO leakage + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_IDLE, + v4_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_RX_ONLY, + v4_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + v4_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + v4_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); + + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_IDLE, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_TX_ONLY, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); } -wbx_base::wbx_version4::~wbx_version4(void){ +wbx_base::wbx_version4::~wbx_version4(void) +{ /* NOP */ } @@ -160,29 +188,35 @@ wbx_base::wbx_version4::~wbx_version4(void){ /*********************************************************************** * Enables **********************************************************************/ -void wbx_base::wbx_version4::set_tx_enabled(bool enb) { +void wbx_base::wbx_version4::set_tx_enabled(bool enb) +{ self_base->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, - (enb)? TX_POWER_UP | ADF435X_CE : TX_POWER_DOWN, TX_POWER_UP | TX_POWER_DOWN | 0); + (enb) ? TX_POWER_UP | ADF435X_CE : TX_POWER_DOWN, + TX_POWER_UP | TX_POWER_DOWN | 0); } /*********************************************************************** * Gain Handling **********************************************************************/ -double wbx_base::wbx_version4::set_tx_gain(double gain, const std::string &name) { +double wbx_base::wbx_version4::set_tx_gain(double gain, const std::string& name) +{ assert_has(wbx_v4_tx_gain_ranges.keys(), name, "wbx tx gain name"); - if(name == "PGA0"){ + if (name == "PGA0") { uint16_t io_bits = tx_pga0_gain_to_iobits(gain); self_base->_tx_gains[name] = gain; - //write the new gain to tx gpio outputs - //Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR states - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK); + // write the new gain to tx gpio outputs + // Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR + // states + self_base->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK); + self_base->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else + UHD_THROW_INVALID_CODE_PATH(); return self_base->_tx_gains[name]; } @@ -190,62 +224,66 @@ double wbx_base::wbx_version4::set_tx_gain(double gain, const std::string &name) /*********************************************************************** * Tuning **********************************************************************/ -double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { - //clip to tuning range +double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + // clip to tuning range target_freq = wbx_v4_freq_range.clip(target_freq); - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; + UHD_LOGGER_TRACE("WBX") << boost::format("WBX tune: target frequency %f MHz") + % (target_freq / 1e6); /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to * tune in Integer-N mode, which can result in better spur * performance on some mixers. The default is fractional tuning. */ - property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree() - : self_base->get_tx_subtree(); + property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) + ? self_base->get_rx_subtree() + : self_base->get_tx_subtree(); device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); - double reference_freq = self_base->get_iface()->get_clock_rate(unit); + bool is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); + double reference_freq = self_base->get_iface()->get_clock_rate(unit); - //Select the LO + // Select the LO adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo; lo_iface->set_reference_freq(reference_freq); - //The mixer has a divide-by-2 stage on the LO port so the synthesizer - //frequency must 2x the target frequency. This introduces a 180 degree phase - //ambiguity when trying to synchronize the phase of multiple boards. + // The mixer has a divide-by-2 stage on the LO port so the synthesizer + // frequency must 2x the target frequency. This introduces a 180 degree phase + // ambiguity when trying to synchronize the phase of multiple boards. double synth_target_freq = target_freq * 2; - //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) - lo_iface->set_prescaler(synth_target_freq > 3.6e9 ? - adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5); + // Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) + lo_iface->set_prescaler(synth_target_freq > 3.6e9 ? adf435x_iface::PRESCALER_8_9 + : adf435x_iface::PRESCALER_4_5); - //The feedback of the divided frequency must be disabled whenever the target frequency - //divided by the minimum PFD frequency cannot meet the minimum integer divider (N) value. - //If it is disabled, additional phase ambiguity will be introduced. With a minimum PFD - //frequency of 10 MHz, synthesizer frequencies below 230 MHz (LO frequencies below 115 MHz) - //will have too much ambiguity to synchronize. + // The feedback of the divided frequency must be disabled whenever the target + // frequency divided by the minimum PFD frequency cannot meet the minimum integer + // divider (N) value. If it is disabled, additional phase ambiguity will be + // introduced. With a minimum PFD frequency of 10 MHz, synthesizer frequencies below + // 230 MHz (LO frequencies below 115 MHz) will have too much ambiguity to synchronize. lo_iface->set_feedback_select( - (int(synth_target_freq / 10e6) >= lo_iface->get_int_range().start() ? - adf435x_iface::FB_SEL_DIVIDED : adf435x_iface::FB_SEL_FUNDAMENTAL)); + (int(synth_target_freq / 10e6) >= lo_iface->get_int_range().start() + ? adf435x_iface::FB_SEL_DIVIDED + : adf435x_iface::FB_SEL_FUNDAMENTAL)); double synth_actual_freq = lo_iface->set_frequency(synth_target_freq, is_int_n); - //The mixer has a divide-by-2 stage on the LO port so the synthesizer - //actual_freq must /2 the synth_actual_freq + // The mixer has a divide-by-2 stage on the LO port so the synthesizer + // actual_freq must /2 the synth_actual_freq double actual_freq = synth_actual_freq / 2; if (unit == dboard_iface::UNIT_RX) { - lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) ? - adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_2DBM); + lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) + ? adf435x_iface::OUTPUT_POWER_5DBM + : adf435x_iface::OUTPUT_POWER_2DBM); } else { - lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) ? - adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_M1DBM); + lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) + ? adf435x_iface::OUTPUT_POWER_5DBM + : adf435x_iface::OUTPUT_POWER_M1DBM); } - //Write to hardware + // Write to hardware lo_iface->commit(); return actual_freq; diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index 40fdca0a5..d42a56562 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -6,36 +6,38 @@ // // TX IO Pins -#define HB_PA_OFF_TXIO (1 << 15) // 5GHz PA, 1 = off, 0 = on -#define LB_PA_OFF_TXIO (1 << 14) // 2.4GHz PA, 1 = off, 0 = on -#define ANTSEL_TX1_RX2_TXIO (1 << 13) // 1 = Ant 1 to TX, Ant 2 to RX -#define ANTSEL_TX2_RX1_TXIO (1 << 12) // 1 = Ant 2 to TX, Ant 1 to RX -#define TX_EN_TXIO (1 << 11) // 1 = TX on, 0 = TX off -#define AD9515DIV_TXIO (1 << 4) // 1 = Div by 3, 0 = Div by 2 +#define HB_PA_OFF_TXIO (1 << 15) // 5GHz PA, 1 = off, 0 = on +#define LB_PA_OFF_TXIO (1 << 14) // 2.4GHz PA, 1 = off, 0 = on +#define ANTSEL_TX1_RX2_TXIO (1 << 13) // 1 = Ant 1 to TX, Ant 2 to RX +#define ANTSEL_TX2_RX1_TXIO (1 << 12) // 1 = Ant 2 to TX, Ant 1 to RX +#define TX_EN_TXIO (1 << 11) // 1 = TX on, 0 = TX off +#define AD9515DIV_TXIO (1 << 4) // 1 = Div by 3, 0 = Div by 2 -#define TXIO_MASK (HB_PA_OFF_TXIO | LB_PA_OFF_TXIO | ANTSEL_TX1_RX2_TXIO | ANTSEL_TX2_RX1_TXIO | TX_EN_TXIO | AD9515DIV_TXIO) +#define TXIO_MASK \ + (HB_PA_OFF_TXIO | LB_PA_OFF_TXIO | ANTSEL_TX1_RX2_TXIO | ANTSEL_TX2_RX1_TXIO \ + | TX_EN_TXIO | AD9515DIV_TXIO) // TX IO Functions -#define HB_PA_TXIO LB_PA_OFF_TXIO -#define LB_PA_TXIO HB_PA_OFF_TXIO -#define TX_ENB_TXIO TX_EN_TXIO -#define TX_DIS_TXIO (HB_PA_OFF_TXIO | LB_PA_OFF_TXIO) -#define AD9515DIV_3_TXIO AD9515DIV_TXIO -#define AD9515DIV_2_TXIO 0 +#define HB_PA_TXIO LB_PA_OFF_TXIO +#define LB_PA_TXIO HB_PA_OFF_TXIO +#define TX_ENB_TXIO TX_EN_TXIO +#define TX_DIS_TXIO (HB_PA_OFF_TXIO | LB_PA_OFF_TXIO) +#define AD9515DIV_3_TXIO AD9515DIV_TXIO +#define AD9515DIV_2_TXIO 0 // RX IO Pins -#define LOCKDET_RXIO (1 << 15) // This is an INPUT!!! -#define POWER_RXIO (1 << 14) // 1 = power on, 0 = shutdown -#define RX_EN_RXIO (1 << 13) // 1 = RX on, 0 = RX off -#define RX_HP_RXIO (1 << 12) // 0 = Fc set by rx_hpf, 1 = 600 KHz +#define LOCKDET_RXIO (1 << 15) // This is an INPUT!!! +#define POWER_RXIO (1 << 14) // 1 = power on, 0 = shutdown +#define RX_EN_RXIO (1 << 13) // 1 = RX on, 0 = RX off +#define RX_HP_RXIO (1 << 12) // 0 = Fc set by rx_hpf, 1 = 600 KHz #define RXIO_MASK (POWER_RXIO | RX_EN_RXIO | RX_HP_RXIO) // RX IO Functions -#define POWER_UP_RXIO POWER_RXIO -#define POWER_DOWN_RXIO 0 -#define RX_ENB_RXIO RX_EN_RXIO -#define RX_DIS_RXIO 0 +#define POWER_UP_RXIO POWER_RXIO +#define POWER_DOWN_RXIO 0 +#define RX_ENB_RXIO RX_EN_RXIO +#define RX_DIS_RXIO 0 #include "max2829_regs.hpp" #include <uhd/types/dict.hpp> @@ -63,45 +65,32 @@ using namespace boost::assign; /*********************************************************************** * The XCVR 2450 constants **********************************************************************/ -static const freq_range_t xcvr_freq_range = list_of - (range_t(2.4e9, 2.5e9)) - (range_t(4.9e9, 6.0e9)) -; - -//Multiplied by 2.0 for conversion to complex bandpass from lowpass -static const freq_range_t xcvr_tx_bandwidth_range = list_of - (range_t(2.0*12e6)) - (range_t(2.0*18e6)) - (range_t(2.0*24e6)) -; - -//Multiplied by 2.0 for conversion to complex bandpass from lowpass -static const freq_range_t xcvr_rx_bandwidth_range = list_of - (range_t(2.0*0.9*7.5e6, 2.0*1.1*7.5e6)) - (range_t(2.0*0.9*9.5e6, 2.0*1.1*9.5e6)) - (range_t(2.0*0.9*14e6, 2.0*1.1*14e6)) - (range_t(2.0*0.9*18e6, 2.0*1.1*18e6)) -; +static const freq_range_t xcvr_freq_range = + list_of(range_t(2.4e9, 2.5e9))(range_t(4.9e9, 6.0e9)); + +// Multiplied by 2.0 for conversion to complex bandpass from lowpass +static const freq_range_t xcvr_tx_bandwidth_range = + list_of(range_t(2.0 * 12e6))(range_t(2.0 * 18e6))(range_t(2.0 * 24e6)); + +// Multiplied by 2.0 for conversion to complex bandpass from lowpass +static const freq_range_t xcvr_rx_bandwidth_range = + list_of(range_t(2.0 * 0.9 * 7.5e6, 2.0 * 1.1 * 7.5e6))( + range_t(2.0 * 0.9 * 9.5e6, 2.0 * 1.1 * 9.5e6))(range_t( + 2.0 * 0.9 * 14e6, 2.0 * 1.1 * 14e6))(range_t(2.0 * 0.9 * 18e6, 2.0 * 1.1 * 18e6)); static const std::vector<std::string> xcvr_antennas = list_of("J1")("J2"); -static const uhd::dict<std::string, gain_range_t> xcvr_tx_gain_ranges = map_list_of - ("VGA", gain_range_t(0, 30, 0.5)) - ("BB", gain_range_t(0, 5, 1.5)) -; -static const uhd::dict<std::string, gain_range_t> xcvr_rx_gain_ranges = map_list_of - ("LNA", gain_range_t(list_of - (range_t(0)) - (range_t(15)) - (range_t(30.5)) - )) - ("VGA", gain_range_t(0, 62, 2.0)) -; +static const uhd::dict<std::string, gain_range_t> xcvr_tx_gain_ranges = + map_list_of("VGA", gain_range_t(0, 30, 0.5))("BB", gain_range_t(0, 5, 1.5)); +static const uhd::dict<std::string, gain_range_t> xcvr_rx_gain_ranges = + map_list_of("LNA", gain_range_t(list_of(range_t(0))(range_t(15))(range_t(30.5))))( + "VGA", gain_range_t(0, 62, 2.0)); /*********************************************************************** * The XCVR 2450 dboard class **********************************************************************/ -class xcvr2450 : public xcvr_dboard_base{ +class xcvr2450 : public xcvr_dboard_base +{ public: xcvr2450(ctor_args_t args); virtual ~xcvr2450(void); @@ -116,35 +105,38 @@ private: double set_lo_freq(double target_freq); double set_lo_freq_core(double target_freq); - void set_tx_ant(const std::string &ant); - void set_rx_ant(const std::string &ant); - double set_tx_gain(double gain, const std::string &name); - double set_rx_gain(double gain, const std::string &name); + void set_tx_ant(const std::string& ant); + void set_rx_ant(const std::string& ant); + double set_tx_gain(double gain, const std::string& name); + double set_rx_gain(double gain, const std::string& name); double set_rx_bandwidth(double bandwidth); double set_tx_bandwidth(double bandwidth); void update_atr(void); void spi_reset(void); - void send_reg(uint8_t addr){ + void send_reg(uint8_t addr) + { uint32_t value = _max2829_regs.get_reg(addr); - UHD_LOGGER_TRACE("XCVR2450") << boost::format( - "XCVR2450: send reg 0x%02x, value 0x%05x" - ) % int(addr) % value ; + UHD_LOGGER_TRACE("XCVR2450") + << boost::format("XCVR2450: send reg 0x%02x, value 0x%05x") % int(addr) + % value; this->get_iface()->write_spi( - dboard_iface::UNIT_RX, - spi_config_t::EDGE_RISE, - value, 24 - ); + dboard_iface::UNIT_RX, spi_config_t::EDGE_RISE, value, 24); } - static bool is_highband(double freq){return freq > 3e9;} + static bool is_highband(double freq) + { + return freq > 3e9; + } /*! * Get the lock detect status of the LO. * \return sensor for locked */ - sensor_value_t get_locked(void){ - const bool locked = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & LOCKDET_RXIO) != 0; + sensor_value_t get_locked(void) + { + const bool locked = + (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & LOCKDET_RXIO) != 0; return sensor_value_t("LO", locked, "locked", "unlocked"); } @@ -152,22 +144,30 @@ private: * Read the RSSI from the aux adc * \return the rssi sensor in dBm */ - sensor_value_t get_rssi(void){ + sensor_value_t get_rssi(void) + { //*FIXME* RSSI depends on LNA Gain Setting (datasheet pg 16 top middle chart) double max_power = 0.0; - switch(_max2829_regs.rx_lna_gain){ - case 0: - case 1: max_power = 0; break; - case 2: max_power = -15; break; - case 3: max_power = -30.5; break; + switch (_max2829_regs.rx_lna_gain) { + case 0: + case 1: + max_power = 0; + break; + case 2: + max_power = -15; + break; + case 3: + max_power = -30.5; + break; } - //constants for the rssi calculation + // constants for the rssi calculation static const double min_v = 2.5, max_v = 0.5; static const double rssi_dyn_range = 60.0; - //calculate the rssi from the voltage - double voltage = this->get_iface()->read_aux_adc(dboard_iface::UNIT_RX, dboard_iface::AUX_ADC_B); - double rssi = max_power - rssi_dyn_range*(voltage - min_v)/(max_v - min_v); + // calculate the rssi from the voltage + double voltage = this->get_iface()->read_aux_adc( + dboard_iface::UNIT_RX, dboard_iface::AUX_ADC_B); + double rssi = max_power - rssi_dyn_range * (voltage - min_v) / (max_v - min_v); return sensor_value_t("RSSI", rssi, "dBm"); } }; @@ -175,12 +175,14 @@ private: /*********************************************************************** * Register the XCVR 2450 dboard **********************************************************************/ -static dboard_base::sptr make_xcvr2450(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_xcvr2450(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new xcvr2450(args)); } -UHD_STATIC_BLOCK(reg_xcvr2450_dboard){ - //register the factory function for the rx and tx dbids +UHD_STATIC_BLOCK(reg_xcvr2450_dboard) +{ + // register the factory function for the rx and tx dbids dboard_manager::register_dboard(0x0061, 0x0060, &make_xcvr2450, "XCVR2450"); dboard_manager::register_dboard(0x0061, 0x0059, &make_xcvr2450, "XCVR2450 - r2.1"); } @@ -188,13 +190,14 @@ UHD_STATIC_BLOCK(reg_xcvr2450_dboard){ /*********************************************************************** * Structors **********************************************************************/ -xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args){ - spi_reset(); //prepare the spi +xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args) +{ + spi_reset(); // prepare the spi _rx_bandwidth = 9.5e6; _tx_bandwidth = 12.0e6; - //setup the misc max2829 registers + // setup the misc max2829 registers _max2829_regs.mimo_select = max2829_regs_t::MIMO_SELECT_MIMO; _max2829_regs.band_sel_mimo = max2829_regs_t::BAND_SEL_MIMO_MIMO; _max2829_regs.pll_cp_select = max2829_regs_t::PLL_CP_SELECT_4MA; @@ -212,223 +215,261 @@ xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args){ _max2829_regs.tx_vga_linearity = max2829_regs_t::TX_VGA_LINEARITY_78; _max2829_regs.tx_upconv_linearity = max2829_regs_t::TX_UPCONV_LINEARITY_78; - //send initial register settings - for(uint8_t reg = 0x2; reg <= 0xC; reg++){ + // send initial register settings + for (uint8_t reg = 0x2; reg <= 0xC; reg++) { this->send_reg(reg); } //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// - this->get_rx_subtree()->create<std::string>("name") - .set("XCVR2450 RX"); - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_rx_subtree()->create<std::string>("name").set("XCVR2450 RX"); + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&xcvr2450::get_locked, this)); - this->get_rx_subtree()->create<sensor_value_t>("sensors/rssi") + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/rssi") .set_publisher(std::bind(&xcvr2450::get_rssi, this)); - for(const std::string &name: xcvr_rx_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&xcvr2450::set_rx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : xcvr_rx_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer( + std::bind(&xcvr2450::set_rx_gain, this, std::placeholders::_1, name)) .set(xcvr_rx_gain_ranges[name].start()); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(xcvr_rx_gain_ranges[name]); } - this->get_rx_subtree()->create<double>("freq/value") + this->get_rx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&xcvr2450::set_lo_freq, this, std::placeholders::_1)) .set(double(2.45e9)); - this->get_rx_subtree()->create<meta_range_t>("freq/range") - .set(xcvr_freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&xcvr2450::set_rx_ant, this, std::placeholders::_1)) + this->get_rx_subtree()->create<meta_range_t>("freq/range").set(xcvr_freq_range); + this->get_rx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&xcvr2450::set_rx_ant, this, std::placeholders::_1)) .set(xcvr_antennas.at(0)); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(xcvr_antennas); - this->get_rx_subtree()->create<std::string>("connection") - .set("IQ"); - this->get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_rx_subtree()->create<double>("bandwidth/value") - .set_coercer(std::bind(&xcvr2450::set_rx_bandwidth, this, std::placeholders::_1)) //complex bandpass bandwidth - .set(2.0*_rx_bandwidth); //_rx_bandwidth in lowpass, convert to complex bandpass - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_rx_subtree()->create<std::string>("connection").set("IQ"); + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_rx_subtree() + ->create<double>("bandwidth/value") + .set_coercer(std::bind(&xcvr2450::set_rx_bandwidth, + this, + std::placeholders::_1)) // complex bandpass bandwidth + .set(2.0 * _rx_bandwidth); //_rx_bandwidth in lowpass, convert to complex bandpass + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(xcvr_rx_bandwidth_range); //////////////////////////////////////////////////////////////////// // Register TX properties //////////////////////////////////////////////////////////////////// - this->get_tx_subtree()->create<std::string>("name") - .set("XCVR2450 TX"); - this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_tx_subtree()->create<std::string>("name").set("XCVR2450 TX"); + this->get_tx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&xcvr2450::get_locked, this)); - for(const std::string &name: xcvr_tx_gain_ranges.keys()){ - this->get_tx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&xcvr2450::set_tx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : xcvr_tx_gain_ranges.keys()) { + this->get_tx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer( + std::bind(&xcvr2450::set_tx_gain, this, std::placeholders::_1, name)) .set(xcvr_tx_gain_ranges[name].start()); - this->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_tx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(xcvr_tx_gain_ranges[name]); } - this->get_tx_subtree()->create<double>("freq/value") + this->get_tx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&xcvr2450::set_lo_freq, this, std::placeholders::_1)) .set(double(2.45e9)); - this->get_tx_subtree()->create<meta_range_t>("freq/range") - .set(xcvr_freq_range); - this->get_tx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&xcvr2450::set_tx_ant, this, std::placeholders::_1)) + this->get_tx_subtree()->create<meta_range_t>("freq/range").set(xcvr_freq_range); + this->get_tx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&xcvr2450::set_tx_ant, this, std::placeholders::_1)) .set(xcvr_antennas.at(1)); - this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_tx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(xcvr_antennas); - this->get_tx_subtree()->create<std::string>("connection") - .set("QI"); - this->get_tx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_tx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_tx_subtree()->create<double>("bandwidth/value") - .set_coercer(std::bind(&xcvr2450::set_tx_bandwidth, this, std::placeholders::_1)) //complex bandpass bandwidth - .set(2.0*_tx_bandwidth); //_tx_bandwidth in lowpass, convert to complex bandpass - this->get_tx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_tx_subtree()->create<std::string>("connection").set("QI"); + this->get_tx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_tx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_tx_subtree() + ->create<double>("bandwidth/value") + .set_coercer(std::bind(&xcvr2450::set_tx_bandwidth, + this, + std::placeholders::_1)) // complex bandpass bandwidth + .set(2.0 * _tx_bandwidth); //_tx_bandwidth in lowpass, convert to complex bandpass + this->get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(xcvr_tx_bandwidth_range); - //enable only the clocks we need + // enable only the clocks we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); - //set the gpio directions and atr controls (identically) + // set the gpio directions and atr controls (identically) this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, TXIO_MASK); this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXIO_MASK); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, TXIO_MASK); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, RXIO_MASK); } -xcvr2450::~xcvr2450(void){ +xcvr2450::~xcvr2450(void) +{ UHD_SAFE_CALL(spi_reset();) } -void xcvr2450::spi_reset(void){ - //spi reset mode: global enable = off, tx and rx enable = on - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, TX_ENB_TXIO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_ENB_RXIO | POWER_DOWN_RXIO); +void xcvr2450::spi_reset(void) +{ + // spi reset mode: global enable = off, tx and rx enable = on + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, TX_ENB_TXIO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_ENB_RXIO | POWER_DOWN_RXIO); std::this_thread::sleep_for(std::chrono::milliseconds(10)); - //take it back out of spi reset mode and wait a bit - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_DIS_RXIO | POWER_UP_RXIO); + // take it back out of spi reset mode and wait a bit + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_DIS_RXIO | POWER_UP_RXIO); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } /*********************************************************************** * Update ATR regs which change with Antenna or Freq **********************************************************************/ -void xcvr2450::update_atr(void){ - //calculate tx atr pins - int band_sel = (xcvr2450::is_highband(_lo_freq))? HB_PA_TXIO : LB_PA_TXIO; - int tx_ant_sel = (_tx_ant == "J1")? ANTSEL_TX1_RX2_TXIO : ANTSEL_TX2_RX1_TXIO; - int rx_ant_sel = (_rx_ant == "J2")? ANTSEL_TX1_RX2_TXIO : ANTSEL_TX2_RX1_TXIO; - int xx_ant_sel = tx_ant_sel; //Prefer the tx antenna selection for full duplex, - //due to the issue that USRP1 will take the value of full duplex for its TXATR. - int ad9515div = (_ad9515div == 3)? AD9515DIV_3_TXIO : AD9515DIV_2_TXIO; - - //set the tx registers - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, band_sel | ad9515div | TX_DIS_TXIO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, band_sel | ad9515div | TX_DIS_TXIO | rx_ant_sel); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, band_sel | ad9515div | TX_ENB_TXIO | tx_ant_sel); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, band_sel | ad9515div | TX_ENB_TXIO | xx_ant_sel); - - //set the rx registers - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, POWER_UP_RXIO | RX_DIS_RXIO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, POWER_UP_RXIO | RX_ENB_RXIO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, POWER_UP_RXIO | RX_DIS_RXIO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, POWER_UP_RXIO | RX_DIS_RXIO); +void xcvr2450::update_atr(void) +{ + // calculate tx atr pins + int band_sel = (xcvr2450::is_highband(_lo_freq)) ? HB_PA_TXIO : LB_PA_TXIO; + int tx_ant_sel = (_tx_ant == "J1") ? ANTSEL_TX1_RX2_TXIO : ANTSEL_TX2_RX1_TXIO; + int rx_ant_sel = (_rx_ant == "J2") ? ANTSEL_TX1_RX2_TXIO : ANTSEL_TX2_RX1_TXIO; + int xx_ant_sel = tx_ant_sel; // Prefer the tx antenna selection for full duplex, + // due to the issue that USRP1 will take the value of full duplex for its TXATR. + int ad9515div = (_ad9515div == 3) ? AD9515DIV_3_TXIO : AD9515DIV_2_TXIO; + + // set the tx registers + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_IDLE, + band_sel | ad9515div | TX_DIS_TXIO); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_RX_ONLY, + band_sel | ad9515div | TX_DIS_TXIO | rx_ant_sel); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + band_sel | ad9515div | TX_ENB_TXIO | tx_ant_sel); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + band_sel | ad9515div | TX_ENB_TXIO | xx_ant_sel); + + // set the rx registers + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, POWER_UP_RXIO | RX_DIS_RXIO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, POWER_UP_RXIO | RX_ENB_RXIO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, POWER_UP_RXIO | RX_DIS_RXIO); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + POWER_UP_RXIO | RX_DIS_RXIO); } /*********************************************************************** * Tuning **********************************************************************/ -double xcvr2450::set_lo_freq(double target_freq){ - //tune the LO and sleep a bit for lock - //if not locked, try some carrier offsets +double xcvr2450::set_lo_freq(double target_freq) +{ + // tune the LO and sleep a bit for lock + // if not locked, try some carrier offsets double actual = 0.0; - for (double offset = 0.0; offset <= 3e6; offset+=1e6){ + for (double offset = 0.0; offset <= 3e6; offset += 1e6) { actual = this->set_lo_freq_core(target_freq + offset); std::this_thread::sleep_for(std::chrono::milliseconds(50)); - if (this->get_locked().to_bool()) break; + if (this->get_locked().to_bool()) + break; } return actual; } -double xcvr2450::set_lo_freq_core(double target_freq){ - - //clip the input to the range +double xcvr2450::set_lo_freq_core(double target_freq) +{ + // clip the input to the range target_freq = xcvr_freq_range.clip(target_freq); - //variables used in the calculation below - double scaler = xcvr2450::is_highband(target_freq)? (4.0/5.0) : (4.0/3.0); + // variables used in the calculation below + double scaler = xcvr2450::is_highband(target_freq) ? (4.0 / 5.0) : (4.0 / 3.0); double ref_freq = this->get_iface()->get_codec_rate(dboard_iface::UNIT_TX); int R, intdiv = 131, fracdiv = 0; - //loop through values until we get a match - for(_ad9515div = 2; _ad9515div <= 3; _ad9515div++){ - for(R = 1; R <= 7; R++){ - double N = (target_freq*scaler*R*_ad9515div)/ref_freq; - intdiv = int(std::floor(N)); - fracdiv = boost::math::iround((N - intdiv)*double(1 << 16)); - //actual minimum is 128, but most chips seems to require higher to lock - if (intdiv < 131 or intdiv > 255) continue; - //constraints met: exit loop + // loop through values until we get a match + for (_ad9515div = 2; _ad9515div <= 3; _ad9515div++) { + for (R = 1; R <= 7; R++) { + double N = (target_freq * scaler * R * _ad9515div) / ref_freq; + intdiv = int(std::floor(N)); + fracdiv = boost::math::iround((N - intdiv) * double(1 << 16)); + // actual minimum is 128, but most chips seems to require higher to lock + if (intdiv < 131 or intdiv > 255) + continue; + // constraints met: exit loop goto done_loop; } - } done_loop: + } +done_loop: - //calculate the actual freq from the values above - double N = double(intdiv) + double(fracdiv)/double(1 << 16); - _lo_freq = (N*ref_freq)/(scaler*R*_ad9515div); + // calculate the actual freq from the values above + double N = double(intdiv) + double(fracdiv) / double(1 << 16); + _lo_freq = (N * ref_freq) / (scaler * R * _ad9515div); UHD_LOGGER_TRACE("XCVR2450") << boost::format("XCVR2450 tune:\n") - << boost::format(" R=%d, N=%f, ad9515=%d, scaler=%f\n") % R % N % _ad9515div % scaler - << boost::format(" Ref Freq=%fMHz\n") % (ref_freq/1e6) - << boost::format(" Target Freq=%fMHz\n") % (target_freq/1e6) - << boost::format(" Actual Freq=%fMHz\n") % (_lo_freq/1e6) - ; - - //high-high band or low-high band? - if(_lo_freq > (5.35e9 + 5.47e9)/2.0){ - UHD_LOGGER_TRACE("XCVR2450") << "XCVR2450 tune: Using high-high band" ; - _max2829_regs.band_select_802_11a = max2829_regs_t::BAND_SELECT_802_11A_5_47GHZ_TO_5_875GHZ; - }else{ - UHD_LOGGER_TRACE("XCVR2450") << "XCVR2450 tune: Using low-high band" ; - _max2829_regs.band_select_802_11a = max2829_regs_t::BAND_SELECT_802_11A_4_9GHZ_TO_5_35GHZ; + << boost::format(" R=%d, N=%f, ad9515=%d, scaler=%f\n") % R % N % _ad9515div + % scaler + << boost::format(" Ref Freq=%fMHz\n") % (ref_freq / 1e6) + << boost::format(" Target Freq=%fMHz\n") % (target_freq / 1e6) + << boost::format(" Actual Freq=%fMHz\n") % (_lo_freq / 1e6); + + // high-high band or low-high band? + if (_lo_freq > (5.35e9 + 5.47e9) / 2.0) { + UHD_LOGGER_TRACE("XCVR2450") << "XCVR2450 tune: Using high-high band"; + _max2829_regs.band_select_802_11a = + max2829_regs_t::BAND_SELECT_802_11A_5_47GHZ_TO_5_875GHZ; + } else { + UHD_LOGGER_TRACE("XCVR2450") << "XCVR2450 tune: Using low-high band"; + _max2829_regs.band_select_802_11a = + max2829_regs_t::BAND_SELECT_802_11A_4_9GHZ_TO_5_35GHZ; } - //new band select settings and ad9515 divider + // new band select settings and ad9515 divider this->update_atr(); const bool div_ext(this->get_tx_id() == 0x0059); - if (div_ext) - { - this->get_iface()->set_clock_rate(dboard_iface::UNIT_TX, ref_freq/_ad9515div); - } - else - { + if (div_ext) { + this->get_iface()->set_clock_rate(dboard_iface::UNIT_TX, ref_freq / _ad9515div); + } else { this->get_iface()->set_clock_rate(dboard_iface::UNIT_TX, ref_freq); } - //load new counters into registers + // load new counters into registers _max2829_regs.int_div_ratio_word = intdiv; _max2829_regs.frac_div_ratio_lsb = fracdiv & 0x3; _max2829_regs.frac_div_ratio_msb = fracdiv >> 2; - this->send_reg(0x3); //integer - this->send_reg(0x4); //fractional + this->send_reg(0x3); // integer + this->send_reg(0x4); // fractional - //load the reference divider and band select into registers - //toggle the bandswitch from off to automatic (which really means start) + // load the reference divider and band select into registers + // toggle the bandswitch from off to automatic (which really means start) _max2829_regs.ref_divider = R; - _max2829_regs.band_select = (xcvr2450::is_highband(_lo_freq))? - max2829_regs_t::BAND_SELECT_5GHZ : - max2829_regs_t::BAND_SELECT_2_4GHZ ; + _max2829_regs.band_select = (xcvr2450::is_highband(_lo_freq)) + ? max2829_regs_t::BAND_SELECT_5GHZ + : max2829_regs_t::BAND_SELECT_2_4GHZ; _max2829_regs.vco_bandswitch = max2829_regs_t::VCO_BANDSWITCH_DISABLE; this->send_reg(0x5); - _max2829_regs.vco_bandswitch = max2829_regs_t::VCO_BANDSWITCH_AUTOMATIC;; + _max2829_regs.vco_bandswitch = max2829_regs_t::VCO_BANDSWITCH_AUTOMATIC; + ; this->send_reg(0x5); return _lo_freq; @@ -437,16 +478,18 @@ double xcvr2450::set_lo_freq_core(double target_freq){ /*********************************************************************** * Antenna Handling **********************************************************************/ -void xcvr2450::set_tx_ant(const std::string &ant){ +void xcvr2450::set_tx_ant(const std::string& ant) +{ assert_has(xcvr_antennas, ant, "xcvr antenna name"); - _tx_ant = ant; - this->update_atr(); //sets the atr to the new antenna setting + _tx_ant = ant; + this->update_atr(); // sets the atr to the new antenna setting } -void xcvr2450::set_rx_ant(const std::string &ant){ +void xcvr2450::set_rx_ant(const std::string& ant) +{ assert_has(xcvr_antennas, ant, "xcvr antenna name"); _rx_ant = ant; - this->update_atr(); //sets the atr to the new antenna setting + this->update_atr(); // sets the atr to the new antenna setting } /*********************************************************************** @@ -458,16 +501,20 @@ void xcvr2450::set_rx_ant(const std::string &ant){ * \param gain the requested gain in dB * \return 6 bit the register value */ -static int gain_to_tx_vga_reg(double &gain){ - //calculate the register value - int reg = uhd::clip(boost::math::iround(gain*60/30.0) + 3, 0, 63); +static int gain_to_tx_vga_reg(double& gain) +{ + // calculate the register value + int reg = uhd::clip(boost::math::iround(gain * 60 / 30.0) + 3, 0, 63); - //calculate the actual gain value - if (reg < 4) gain = 0; - else if (reg < 48) gain = double(reg/2 - 1); - else gain = double(reg/2.0 - 1.5); + // calculate the actual gain value + if (reg < 4) + gain = 0; + else if (reg < 48) + gain = double(reg / 2 - 1); + else + gain = double(reg / 2.0 - 1.5); - //return register value + // return register value return reg; } @@ -477,21 +524,22 @@ static int gain_to_tx_vga_reg(double &gain){ * \param gain the requested gain in dB * \return gain enum value */ -static max2829_regs_t::tx_baseband_gain_t gain_to_tx_bb_reg(double &gain){ - int reg = uhd::clip(boost::math::iround(gain*3/5.0), 0, 3); - switch(reg){ - case 0: - gain = 0; - return max2829_regs_t::TX_BASEBAND_GAIN_0DB; - case 1: - gain = 2; - return max2829_regs_t::TX_BASEBAND_GAIN_2DB; - case 2: - gain = 3.5; - return max2829_regs_t::TX_BASEBAND_GAIN_3_5DB; - case 3: - gain = 5; - return max2829_regs_t::TX_BASEBAND_GAIN_5DB; +static max2829_regs_t::tx_baseband_gain_t gain_to_tx_bb_reg(double& gain) +{ + int reg = uhd::clip(boost::math::iround(gain * 3 / 5.0), 0, 3); + switch (reg) { + case 0: + gain = 0; + return max2829_regs_t::TX_BASEBAND_GAIN_0DB; + case 1: + gain = 2; + return max2829_regs_t::TX_BASEBAND_GAIN_2DB; + case 2: + gain = 3.5; + return max2829_regs_t::TX_BASEBAND_GAIN_3_5DB; + case 3: + gain = 5; + return max2829_regs_t::TX_BASEBAND_GAIN_5DB; } UHD_THROW_INVALID_CODE_PATH(); } @@ -502,9 +550,10 @@ static max2829_regs_t::tx_baseband_gain_t gain_to_tx_bb_reg(double &gain){ * \param gain the requested gain in dB * \return 5 bit the register value */ -static int gain_to_rx_vga_reg(double &gain){ - int reg = uhd::clip(boost::math::iround(gain/2.0), 0, 31); - gain = double(reg*2); +static int gain_to_rx_vga_reg(double& gain) +{ + int reg = uhd::clip(boost::math::iround(gain / 2.0), 0, 31); + gain = double(reg * 2); return reg; } @@ -514,44 +563,51 @@ static int gain_to_rx_vga_reg(double &gain){ * \param gain the requested gain in dB * \return 2 bit the register value */ -static int gain_to_rx_lna_reg(double &gain){ - int reg = uhd::clip(boost::math::iround(gain*2/30.5) + 1, 0, 3); - switch(reg){ - case 0: - case 1: gain = 0; break; - case 2: gain = 15; break; - case 3: gain = 30.5; break; +static int gain_to_rx_lna_reg(double& gain) +{ + int reg = uhd::clip(boost::math::iround(gain * 2 / 30.5) + 1, 0, 3); + switch (reg) { + case 0: + case 1: + gain = 0; + break; + case 2: + gain = 15; + break; + case 3: + gain = 30.5; + break; } return reg; } -double xcvr2450::set_tx_gain(double gain, const std::string &name){ +double xcvr2450::set_tx_gain(double gain, const std::string& name) +{ assert_has(xcvr_tx_gain_ranges.keys(), name, "xcvr tx gain name"); - if (name == "VGA"){ + if (name == "VGA") { _max2829_regs.tx_vga_gain = gain_to_tx_vga_reg(gain); send_reg(0xC); - } - else if(name == "BB"){ + } else if (name == "BB") { _max2829_regs.tx_baseband_gain = gain_to_tx_bb_reg(gain); send_reg(0x9); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else + UHD_THROW_INVALID_CODE_PATH(); _tx_gains[name] = gain; return gain; } -double xcvr2450::set_rx_gain(double gain, const std::string &name){ +double xcvr2450::set_rx_gain(double gain, const std::string& name) +{ assert_has(xcvr_rx_gain_ranges.keys(), name, "xcvr rx gain name"); - if (name == "VGA"){ + if (name == "VGA") { _max2829_regs.rx_vga_gain = gain_to_rx_vga_reg(gain); send_reg(0xB); - } - else if(name == "LNA"){ + } else if (name == "LNA") { _max2829_regs.rx_lna_gain = gain_to_rx_lna_reg(gain); send_reg(0xB); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else + UHD_THROW_INVALID_CODE_PATH(); _rx_gains[name] = gain; return gain; @@ -561,116 +617,128 @@ double xcvr2450::set_rx_gain(double gain, const std::string &name){ /*********************************************************************** * Bandwidth Handling **********************************************************************/ -static max2829_regs_t::tx_lpf_coarse_adj_t bandwidth_to_tx_lpf_coarse_reg(double &bandwidth){ - int reg = uhd::clip(boost::math::iround((bandwidth-6.0e6)/6.0e6), 1, 3); - - switch(reg){ - case 1: // bandwidth < 15MHz - bandwidth = 12e6; - return max2829_regs_t::TX_LPF_COARSE_ADJ_12MHZ; - case 2: // 15MHz < bandwidth < 21MHz - bandwidth = 18e6; - return max2829_regs_t::TX_LPF_COARSE_ADJ_18MHZ; - case 3: // bandwidth > 21MHz - bandwidth = 24e6; - return max2829_regs_t::TX_LPF_COARSE_ADJ_24MHZ; +static max2829_regs_t::tx_lpf_coarse_adj_t bandwidth_to_tx_lpf_coarse_reg( + double& bandwidth) +{ + int reg = uhd::clip(boost::math::iround((bandwidth - 6.0e6) / 6.0e6), 1, 3); + + switch (reg) { + case 1: // bandwidth < 15MHz + bandwidth = 12e6; + return max2829_regs_t::TX_LPF_COARSE_ADJ_12MHZ; + case 2: // 15MHz < bandwidth < 21MHz + bandwidth = 18e6; + return max2829_regs_t::TX_LPF_COARSE_ADJ_18MHZ; + case 3: // bandwidth > 21MHz + bandwidth = 24e6; + return max2829_regs_t::TX_LPF_COARSE_ADJ_24MHZ; } UHD_THROW_INVALID_CODE_PATH(); } -static max2829_regs_t::rx_lpf_fine_adj_t bandwidth_to_rx_lpf_fine_reg(double &bandwidth, double requested_bandwidth){ - int reg = uhd::clip(boost::math::iround((requested_bandwidth/bandwidth)/0.05), 18, 22); - - switch(reg){ - case 18: // requested_bandwidth < 92.5% - bandwidth = 0.9 * bandwidth; - return max2829_regs_t::RX_LPF_FINE_ADJ_90; - case 19: // 92.5% < requested_bandwidth < 97.5% - bandwidth = 0.95 * bandwidth; - return max2829_regs_t::RX_LPF_FINE_ADJ_95; - case 20: // 97.5% < requested_bandwidth < 102.5% - bandwidth = 1.0 * bandwidth; - return max2829_regs_t::RX_LPF_FINE_ADJ_100; - case 21: // 102.5% < requested_bandwidth < 107.5% - bandwidth = 1.05 * bandwidth; - return max2829_regs_t::RX_LPF_FINE_ADJ_105; - case 22: // 107.5% < requested_bandwidth - bandwidth = 1.1 * bandwidth; - return max2829_regs_t::RX_LPF_FINE_ADJ_110; +static max2829_regs_t::rx_lpf_fine_adj_t bandwidth_to_rx_lpf_fine_reg( + double& bandwidth, double requested_bandwidth) +{ + int reg = + uhd::clip(boost::math::iround((requested_bandwidth / bandwidth) / 0.05), 18, 22); + + switch (reg) { + case 18: // requested_bandwidth < 92.5% + bandwidth = 0.9 * bandwidth; + return max2829_regs_t::RX_LPF_FINE_ADJ_90; + case 19: // 92.5% < requested_bandwidth < 97.5% + bandwidth = 0.95 * bandwidth; + return max2829_regs_t::RX_LPF_FINE_ADJ_95; + case 20: // 97.5% < requested_bandwidth < 102.5% + bandwidth = 1.0 * bandwidth; + return max2829_regs_t::RX_LPF_FINE_ADJ_100; + case 21: // 102.5% < requested_bandwidth < 107.5% + bandwidth = 1.05 * bandwidth; + return max2829_regs_t::RX_LPF_FINE_ADJ_105; + case 22: // 107.5% < requested_bandwidth + bandwidth = 1.1 * bandwidth; + return max2829_regs_t::RX_LPF_FINE_ADJ_110; } UHD_THROW_INVALID_CODE_PATH(); } -static max2829_regs_t::rx_lpf_coarse_adj_t bandwidth_to_rx_lpf_coarse_reg(double &bandwidth){ - int reg = uhd::clip(boost::math::iround((bandwidth-7.0e6)/1.0e6), 0, 11); - - switch(reg){ - case 0: // bandwidth < 7.5MHz - case 1: // 7.5MHz < bandwidth < 8.5MHz - bandwidth = 7.5e6; - return max2829_regs_t::RX_LPF_COARSE_ADJ_7_5MHZ; - case 2: // 8.5MHz < bandwidth < 9.5MHz - case 3: // 9.5MHz < bandwidth < 10.5MHz - case 4: // 10.5MHz < bandwidth < 11.5MHz - bandwidth = 9.5e6; - return max2829_regs_t::RX_LPF_COARSE_ADJ_9_5MHZ; - case 5: // 11.5MHz < bandwidth < 12.5MHz - case 6: // 12.5MHz < bandwidth < 13.5MHz - case 7: // 13.5MHz < bandwidth < 14.5MHz - case 8: // 14.5MHz < bandwidth < 15.5MHz - bandwidth = 14e6; - return max2829_regs_t::RX_LPF_COARSE_ADJ_14MHZ; - case 9: // 15.5MHz < bandwidth < 16.5MHz - case 10: // 16.5MHz < bandwidth < 17.5MHz - case 11: // 17.5MHz < bandwidth - bandwidth = 18e6; - return max2829_regs_t::RX_LPF_COARSE_ADJ_18MHZ; +static max2829_regs_t::rx_lpf_coarse_adj_t bandwidth_to_rx_lpf_coarse_reg( + double& bandwidth) +{ + int reg = uhd::clip(boost::math::iround((bandwidth - 7.0e6) / 1.0e6), 0, 11); + + switch (reg) { + case 0: // bandwidth < 7.5MHz + case 1: // 7.5MHz < bandwidth < 8.5MHz + bandwidth = 7.5e6; + return max2829_regs_t::RX_LPF_COARSE_ADJ_7_5MHZ; + case 2: // 8.5MHz < bandwidth < 9.5MHz + case 3: // 9.5MHz < bandwidth < 10.5MHz + case 4: // 10.5MHz < bandwidth < 11.5MHz + bandwidth = 9.5e6; + return max2829_regs_t::RX_LPF_COARSE_ADJ_9_5MHZ; + case 5: // 11.5MHz < bandwidth < 12.5MHz + case 6: // 12.5MHz < bandwidth < 13.5MHz + case 7: // 13.5MHz < bandwidth < 14.5MHz + case 8: // 14.5MHz < bandwidth < 15.5MHz + bandwidth = 14e6; + return max2829_regs_t::RX_LPF_COARSE_ADJ_14MHZ; + case 9: // 15.5MHz < bandwidth < 16.5MHz + case 10: // 16.5MHz < bandwidth < 17.5MHz + case 11: // 17.5MHz < bandwidth + bandwidth = 18e6; + return max2829_regs_t::RX_LPF_COARSE_ADJ_18MHZ; } UHD_THROW_INVALID_CODE_PATH(); } -double xcvr2450::set_rx_bandwidth(double bandwidth){ +double xcvr2450::set_rx_bandwidth(double bandwidth) +{ double requested_bandwidth = bandwidth; - //convert complex bandpass to lowpass bandwidth - bandwidth = bandwidth/2.0; + // convert complex bandpass to lowpass bandwidth + bandwidth = bandwidth / 2.0; - //compute coarse low pass cutoff frequency setting + // compute coarse low pass cutoff frequency setting _max2829_regs.rx_lpf_coarse_adj = bandwidth_to_rx_lpf_coarse_reg(bandwidth); - //compute fine low pass cutoff frequency setting - _max2829_regs.rx_lpf_fine_adj = bandwidth_to_rx_lpf_fine_reg(bandwidth, requested_bandwidth); + // compute fine low pass cutoff frequency setting + _max2829_regs.rx_lpf_fine_adj = + bandwidth_to_rx_lpf_fine_reg(bandwidth, requested_bandwidth); - //shadow bandwidth setting + // shadow bandwidth setting _rx_bandwidth = bandwidth; - //update register + // update register send_reg(0x7); - UHD_LOGGER_TRACE("XCVR2450") << boost::format( - "XCVR2450 RX Bandwidth (lp_fc): %f Hz, coarse reg: %d, fine reg: %d" - ) % _rx_bandwidth % (int(_max2829_regs.rx_lpf_coarse_adj)) % (int(_max2829_regs.rx_lpf_fine_adj)) ; + UHD_LOGGER_TRACE("XCVR2450") + << boost::format( + "XCVR2450 RX Bandwidth (lp_fc): %f Hz, coarse reg: %d, fine reg: %d") + % _rx_bandwidth % (int(_max2829_regs.rx_lpf_coarse_adj)) + % (int(_max2829_regs.rx_lpf_fine_adj)); - return 2.0*_rx_bandwidth; + return 2.0 * _rx_bandwidth; } -double xcvr2450::set_tx_bandwidth(double bandwidth){ - //convert complex bandpass to lowpass bandwidth - bandwidth = bandwidth/2.0; +double xcvr2450::set_tx_bandwidth(double bandwidth) +{ + // convert complex bandpass to lowpass bandwidth + bandwidth = bandwidth / 2.0; - //compute coarse low pass cutoff frequency setting + // compute coarse low pass cutoff frequency setting _max2829_regs.tx_lpf_coarse_adj = bandwidth_to_tx_lpf_coarse_reg(bandwidth); - //shadow bandwidth setting + // shadow bandwidth setting _tx_bandwidth = bandwidth; - //update register + // update register send_reg(0x7); - UHD_LOGGER_TRACE("XCVR2450") << boost::format( - "XCVR2450 TX Bandwidth (lp_fc): %f Hz, coarse reg: %d" - ) % _tx_bandwidth % (int(_max2829_regs.tx_lpf_coarse_adj)) ; + UHD_LOGGER_TRACE("XCVR2450") + << boost::format("XCVR2450 TX Bandwidth (lp_fc): %f Hz, coarse reg: %d") + % _tx_bandwidth % (int(_max2829_regs.tx_lpf_coarse_adj)); - //convert lowpass back to complex bandpass bandwidth - return 2.0*_tx_bandwidth; + // convert lowpass back to complex bandpass bandwidth + return 2.0 * _tx_bandwidth; } diff --git a/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.cpp b/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.cpp index 8b8daa681..a0d0eeb22 100644 --- a/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.cpp +++ b/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.cpp @@ -28,162 +28,147 @@ e31x_radio_control_impl::~e31x_radio_control_impl() /****************************************************************************** * API Calls *****************************************************************************/ -uint32_t e31x_radio_control_impl::get_tx_switches( - const size_t chan, - const double freq -) { - RFNOC_LOG_TRACE( - "Update all TX freq related switches. f=" << freq << " Hz, " - ); +uint32_t e31x_radio_control_impl::get_tx_switches(const size_t chan, const double freq) +{ + RFNOC_LOG_TRACE("Update all TX freq related switches. f=" << freq << " Hz, "); - size_t fe_chan = _fe_swap ? (chan ? 0 : 1): chan; + size_t fe_chan = _fe_swap ? (chan ? 0 : 1) : chan; - auto tx_sw1 = TX_SW1_LB_2750; // SW1 = 0 + auto tx_sw1 = TX_SW1_LB_2750; // SW1 = 0 auto vctxrx_sw = VCTXRX_SW_OFF; - auto tx_bias = (fe_chan == 0) ? TX1_BIAS_LB_ON: TX2_BIAS_LB_ON; + auto tx_bias = (fe_chan == 0) ? TX1_BIAS_LB_ON : TX2_BIAS_LB_ON; const auto band = e3xx_radio_control_impl::map_freq_to_tx_band(freq); - switch(band) { - case tx_band::LB_80: - tx_sw1 = TX_SW1_LB_80; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_160: - tx_sw1 = TX_SW1_LB_160; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_225: - tx_sw1 = TX_SW1_LB_225; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_400: - tx_sw1 = TX_SW1_LB_400; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_575: - tx_sw1 = TX_SW1_LB_575; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_1000: - tx_sw1 = TX_SW1_LB_1000; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_1700: - tx_sw1 = TX_SW1_LB_1700; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_2750: - tx_sw1 = TX_SW1_LB_2750; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::HB: - tx_sw1 = TX_SW1_LB_80; - vctxrx_sw = VCTXRX_SW_TX_HB; - tx_bias = (fe_chan == 0) ? TX1_BIAS_HB_ON: TX2_BIAS_HB_ON; - break; - case tx_band::INVALID_BAND: - RFNOC_LOG_ERROR( - "Cannot map TX frequency to band: " << freq); - UHD_THROW_INVALID_CODE_PATH(); - break; + switch (band) { + case tx_band::LB_80: + tx_sw1 = TX_SW1_LB_80; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_160: + tx_sw1 = TX_SW1_LB_160; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_225: + tx_sw1 = TX_SW1_LB_225; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_400: + tx_sw1 = TX_SW1_LB_400; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_575: + tx_sw1 = TX_SW1_LB_575; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_1000: + tx_sw1 = TX_SW1_LB_1000; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_1700: + tx_sw1 = TX_SW1_LB_1700; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_2750: + tx_sw1 = TX_SW1_LB_2750; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::HB: + tx_sw1 = TX_SW1_LB_80; + vctxrx_sw = VCTXRX_SW_TX_HB; + tx_bias = (fe_chan == 0) ? TX1_BIAS_HB_ON : TX2_BIAS_HB_ON; + break; + case tx_band::INVALID_BAND: + RFNOC_LOG_ERROR("Cannot map TX frequency to band: " << freq); + UHD_THROW_INVALID_CODE_PATH(); + break; } RFNOC_LOG_TRACE("TX band = " << int(band) << "TX SW1 = " << tx_sw1 << "TX VCTXRX_SW = " << vctxrx_sw << "TX_BIAS = " << tx_bias); - auto tx_regs = 0 | - vctxrx_sw << VCTXRX_SW_SHIFT | - tx_bias << TX_BIAS_SHIFT | - tx_sw1 << TX_SW1_SHIFT; + auto tx_regs = 0 | vctxrx_sw << VCTXRX_SW_SHIFT | tx_bias << TX_BIAS_SHIFT + | tx_sw1 << TX_SW1_SHIFT; return tx_regs; } uint32_t e31x_radio_control_impl::get_rx_switches( - const size_t chan, - const double freq, - const std::string &ant -){ + const size_t chan, const double freq, const std::string& ant) +{ RFNOC_LOG_TRACE("Update all E310 RX freq related switches. f=" << freq << " Hz, "); - size_t fe_chan = _fe_swap ? (chan ? 0 : 1): chan; + size_t fe_chan = _fe_swap ? (chan ? 0 : 1) : chan; // Default to OFF - auto rx_sw1 = RX_SW1_OFF; - auto rx_swc = RX_SWC_OFF; - auto rx_swb = RX_SWB_OFF; + auto rx_sw1 = RX_SW1_OFF; + auto rx_swc = RX_SWC_OFF; + auto rx_swb = RX_SWB_OFF; auto vctxrx_sw = VCTXRX_SW_OFF; - auto vcrx_sw = (ant == "TX/RX") ? VCRX_TXRX_SW_LB: VCRX_RX_SW_LB; + auto vcrx_sw = (ant == "TX/RX") ? VCRX_TXRX_SW_LB : VCRX_RX_SW_LB; if (ant == "TX/RX") { - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_RX: VCTXRX2_SW_RX; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_RX : VCTXRX2_SW_RX; } const auto band = e3xx_radio_control_impl::map_freq_to_rx_band(freq); - switch(band) { - case rx_band::LB_B2: - rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B2: RX2_SW1_LB_B2; - rx_swc = (fe_chan == 0) ? RX1_SWC_LB_B2: RX2_SWC_LB_B2; - rx_swb = RX_SWB_OFF; - break; - case rx_band::LB_B3: - rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B3: RX2_SW1_LB_B3; - rx_swc = (fe_chan == 0) ? RX1_SWC_LB_B3: RX2_SWC_LB_B3; - rx_swb = RX_SWB_OFF; - break; - case rx_band::LB_B4: - rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B4: RX2_SW1_LB_B4; - rx_swc = (fe_chan == 0) ? RX1_SWC_LB_B4: RX2_SWC_LB_B4; - rx_swb = RX_SWB_OFF; - break; - case rx_band::LB_B5: - rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B5: RX2_SW1_LB_B5; - rx_swc = RX_SWC_OFF; - rx_swb = (fe_chan == 0) ? RX1_SWB_LB_B5: RX2_SWB_LB_B5; - break; - case rx_band::LB_B6: - rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B6: RX2_SW1_LB_B6; - rx_swc = RX_SWC_OFF; - rx_swb = (fe_chan == 0) ? RX1_SWB_LB_B6: RX2_SWB_LB_B6; - break; - case rx_band::LB_B7: - rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B7: RX2_SW1_LB_B7; - rx_swc = RX_SWC_OFF; - rx_swb = (fe_chan == 0) ? RX1_SWB_LB_B7: RX2_SWB_LB_B7; - break; - case rx_band::HB: - rx_sw1 = RX_SW1_OFF; - rx_swc = RX_SWC_OFF; - rx_swb = RX_SWB_OFF; - vcrx_sw = (ant == "TX/RX") ? VCRX_TXRX_SW_HB: VCRX_RX_SW_HB; - break; - case rx_band::INVALID_BAND: - RFNOC_LOG_ERROR("Cannot map RX frequency to band: " << freq); - UHD_THROW_INVALID_CODE_PATH(); - break; + switch (band) { + case rx_band::LB_B2: + rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B2 : RX2_SW1_LB_B2; + rx_swc = (fe_chan == 0) ? RX1_SWC_LB_B2 : RX2_SWC_LB_B2; + rx_swb = RX_SWB_OFF; + break; + case rx_band::LB_B3: + rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B3 : RX2_SW1_LB_B3; + rx_swc = (fe_chan == 0) ? RX1_SWC_LB_B3 : RX2_SWC_LB_B3; + rx_swb = RX_SWB_OFF; + break; + case rx_band::LB_B4: + rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B4 : RX2_SW1_LB_B4; + rx_swc = (fe_chan == 0) ? RX1_SWC_LB_B4 : RX2_SWC_LB_B4; + rx_swb = RX_SWB_OFF; + break; + case rx_band::LB_B5: + rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B5 : RX2_SW1_LB_B5; + rx_swc = RX_SWC_OFF; + rx_swb = (fe_chan == 0) ? RX1_SWB_LB_B5 : RX2_SWB_LB_B5; + break; + case rx_band::LB_B6: + rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B6 : RX2_SW1_LB_B6; + rx_swc = RX_SWC_OFF; + rx_swb = (fe_chan == 0) ? RX1_SWB_LB_B6 : RX2_SWB_LB_B6; + break; + case rx_band::LB_B7: + rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B7 : RX2_SW1_LB_B7; + rx_swc = RX_SWC_OFF; + rx_swb = (fe_chan == 0) ? RX1_SWB_LB_B7 : RX2_SWB_LB_B7; + break; + case rx_band::HB: + rx_sw1 = RX_SW1_OFF; + rx_swc = RX_SWC_OFF; + rx_swb = RX_SWB_OFF; + vcrx_sw = (ant == "TX/RX") ? VCRX_TXRX_SW_HB : VCRX_RX_SW_HB; + break; + case rx_band::INVALID_BAND: + RFNOC_LOG_ERROR("Cannot map RX frequency to band: " << freq); + UHD_THROW_INVALID_CODE_PATH(); + break; } RFNOC_LOG_TRACE("RX SW1=" << rx_sw1 << " RX SWC=" << rx_swc << " RX SWB=" << rx_swb << " RX VCRX_SW=" << vcrx_sw << " RX VCTXRX_SW=" << vctxrx_sw); - auto rx_regs = 0 | - vcrx_sw << VCRX_SW_SHIFT | - vctxrx_sw << VCTXRX_SW_SHIFT | - rx_swc << RX_SWC_SHIFT | - rx_swb << RX_SWB_SHIFT | - rx_sw1 << RX_SW1_SHIFT; + auto rx_regs = 0 | vcrx_sw << VCRX_SW_SHIFT | vctxrx_sw << VCTXRX_SW_SHIFT + | rx_swc << RX_SWC_SHIFT | rx_swb << RX_SWB_SHIFT + | rx_sw1 << RX_SW1_SHIFT; return rx_regs; } uint32_t e31x_radio_control_impl::get_idle_switches() { - uint32_t idle_regs = VCRX_SW_OFF << VCRX_SW_SHIFT | - VCTXRX_SW_OFF << VCTXRX_SW_SHIFT | - TX_BIAS_OFF << TX_BIAS_SHIFT | - RX_SWC_OFF << RX_SWC_SHIFT | - RX_SWB_OFF << RX_SWB_SHIFT | - RX_SW1_OFF << RX_SW1_SHIFT | - TX_SW1_LB_2750 << TX_SW1_SHIFT; + uint32_t idle_regs = VCRX_SW_OFF << VCRX_SW_SHIFT | VCTXRX_SW_OFF << VCTXRX_SW_SHIFT + | TX_BIAS_OFF << TX_BIAS_SHIFT | RX_SWC_OFF << RX_SWC_SHIFT + | RX_SWB_OFF << RX_SWB_SHIFT | RX_SW1_OFF << RX_SW1_SHIFT + | TX_SW1_LB_2750 << TX_SW1_SHIFT; return idle_regs; } diff --git a/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.hpp b/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.hpp index 1c37f4077..04fa800e2 100644 --- a/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.hpp +++ b/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.hpp @@ -6,10 +6,10 @@ // #ifndef INCLUDED_LIBUHD_RFNOC_E31X_RADIO_CTRL_IMPL_HPP -#define INCLUDED_LIBUHD_RFNOC_E31X_RADIO_CTRL_IMPL_HPP +# define INCLUDED_LIBUHD_RFNOC_E31X_RADIO_CTRL_IMPL_HPP -#include "e3xx_constants.hpp" -#include "e3xx_radio_control_impl.hpp" +# include "e3xx_constants.hpp" +# include "e3xx_radio_control_impl.hpp" namespace { static constexpr char E31x_GPIO_BANK[] = "INT0"; @@ -41,11 +41,11 @@ private: * ATR/ Switches Types *************************************************************************/ enum tx_sw1_t { - TX_SW1_LB_80 = 7, - TX_SW1_LB_160 = 6, - TX_SW1_LB_225 = 5, - TX_SW1_LB_400 = 4, - TX_SW1_LB_575 = 3, + TX_SW1_LB_80 = 7, + TX_SW1_LB_160 = 6, + TX_SW1_LB_225 = 5, + TX_SW1_LB_400 = 4, + TX_SW1_LB_575 = 3, TX_SW1_LB_1000 = 2, TX_SW1_LB_1700 = 1, TX_SW1_LB_2750 = 0, @@ -53,12 +53,12 @@ private: }; enum vctxrx_sw_t { - VCTXRX_SW_TX_HB = 3, + VCTXRX_SW_TX_HB = 3, VCTXRX1_SW_TX_LB = 1, - VCTXRX1_SW_RX = 2, + VCTXRX1_SW_RX = 2, VCTXRX2_SW_TX_LB = 2, - VCTXRX2_SW_RX = 1, - VCTXRX_SW_OFF = 0, + VCTXRX2_SW_RX = 1, + VCTXRX_SW_OFF = 0, }; enum rx_sw1_t { @@ -74,7 +74,7 @@ private: RX1_SW1_LB_B5 = 1, RX1_SW1_LB_B6 = 3, RX1_SW1_LB_B7 = 5, - RX_SW1_OFF = 7 + RX_SW1_OFF = 7 }; enum rx_swc_t { @@ -84,7 +84,7 @@ private: RX1_SWC_LB_B2 = 2, RX1_SWC_LB_B3 = 3, RX1_SWC_LB_B4 = 1, - RX_SWC_OFF = 0 + RX_SWC_OFF = 0 }; enum rx_swb_t { @@ -94,15 +94,15 @@ private: RX1_SWB_LB_B5 = 2, RX1_SWB_LB_B6 = 3, RX1_SWB_LB_B7 = 1, - RX_SWB_OFF = 0 + RX_SWB_OFF = 0 }; enum vcrx_sw_t { - VCRX_RX_SW_LB = 1, - VCRX_RX_SW_HB = 2, + VCRX_RX_SW_LB = 1, + VCRX_RX_SW_HB = 2, VCRX_TXRX_SW_LB = 2, VCRX_TXRX_SW_HB = 1, - VCRX_SW_OFF = 0 //or 3 + VCRX_SW_OFF = 0 // or 3 }; // (TX_ENABLEB, TX_ENABLEA) @@ -111,7 +111,7 @@ private: TX1_BIAS_LB_ON = 2, TX2_BIAS_HB_ON = 1, TX2_BIAS_LB_ON = 2, - TX_BIAS_OFF = 0 + TX_BIAS_OFF = 0 }; /************************************************************************ @@ -123,15 +123,9 @@ private: }; uint32_t get_rx_switches( - const size_t chan, - const double freq, - const std::string &ant - ); - - uint32_t get_tx_switches( - const size_t chan, - const double freq - ); + const size_t chan, const double freq, const std::string& ant); + + uint32_t get_tx_switches(const size_t chan, const double freq); uint32_t get_idle_switches(); diff --git a/host/lib/usrp/dboard/e3xx/e31x_regs.hpp b/host/lib/usrp/dboard/e3xx/e31x_regs.hpp index 15ce90743..11d92b953 100644 --- a/host/lib/usrp/dboard/e3xx/e31x_regs.hpp +++ b/host/lib/usrp/dboard/e3xx/e31x_regs.hpp @@ -10,17 +10,16 @@ #include <uhd/config.hpp> #include <cstdint> -static const uint32_t VCRX_SW_SHIFT = 14; -static const uint32_t VCTXRX_SW_SHIFT = 12; -static const uint32_t TX_BIAS_SHIFT = 10; -static const uint32_t RX_SWC_SHIFT = 8; -static const uint32_t RX_SWB_SHIFT = 6; -static const uint32_t RX_SW1_SHIFT = 3; -static const uint32_t TX_SW1_SHIFT = 0; +static const uint32_t VCRX_SW_SHIFT = 14; +static const uint32_t VCTXRX_SW_SHIFT = 12; +static const uint32_t TX_BIAS_SHIFT = 10; +static const uint32_t RX_SWC_SHIFT = 8; +static const uint32_t RX_SWB_SHIFT = 6; +static const uint32_t RX_SW1_SHIFT = 3; +static const uint32_t TX_SW1_SHIFT = 0; -static const uint32_t LED_RX_RX_SHIFT = 2; -static const uint32_t LED_TXRX_TX_SHIFT = 1; -static const uint32_t LED_TXRX_RX_SHIFT = 0; +static const uint32_t LED_RX_RX_SHIFT = 2; +static const uint32_t LED_TXRX_TX_SHIFT = 1; +static const uint32_t LED_TXRX_RX_SHIFT = 0; #endif /* INCLUDED_E31X_REGS_HPP */ - diff --git a/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.cpp b/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.cpp index d9cadc86f..acd0be211 100644 --- a/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.cpp +++ b/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.cpp @@ -147,10 +147,12 @@ ad9361_ctrl::sptr make_rpc(rpc_client::sptr rpcc) /*! Helper function to convert direction and channel to the 'which' required by most Catalina driver functions */ -std::string get_which_ad9361_chain(const direction_t dir, const size_t chan, const bool fe_swap) +std::string get_which_ad9361_chain( + const direction_t dir, const size_t chan, const bool fe_swap) { UHD_ASSERT_THROW(dir == RX_DIRECTION or dir == TX_DIRECTION); UHD_ASSERT_THROW(chan == 0 or chan == 1); size_t ad9361_chan = fe_swap ? (chan ? 0 : 1) : chan; - return str(boost::format("%s%d") % (dir == RX_DIRECTION ? "RX" : "TX") % (ad9361_chan + 1)); + return str( + boost::format("%s%d") % (dir == RX_DIRECTION ? "RX" : "TX") % (ad9361_chan + 1)); } diff --git a/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.hpp b/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.hpp index 129015420..fe694b05c 100644 --- a/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.hpp +++ b/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.hpp @@ -5,7 +5,7 @@ // #ifndef INCLUDED_LIBUHD_RFNOC_E3XX_AD9361_IFACE_HPP -#define INCLUDED_LIBUHD_RFNOC_E3XX_AD9361_IFACE_HPP +# define INCLUDED_LIBUHD_RFNOC_E3XX_AD9361_IFACE_HPP # include <uhd/types/direction.hpp> # include <uhd/types/filters.hpp> @@ -22,7 +22,8 @@ using namespace uhd::usrp; static constexpr size_t E3XX_TUNE_TIMEOUT = 60000; static constexpr size_t E3XX_RATE_TIMEOUT = 60000; ad9361_ctrl::sptr make_rpc(rpc_client::sptr rpcc); -std::string get_which_ad9361_chain(const direction_t dir, const size_t chan, const bool fe_swap=false); +std::string get_which_ad9361_chain( + const direction_t dir, const size_t chan, const bool fe_swap = false); #endif /* INCLUDED_LIBUHD_RFNOC_E3XX_AD9361_IFACE_HPP */ // vim: sw=4 et: diff --git a/host/lib/usrp/dboard/e3xx/e3xx_bands.cpp b/host/lib/usrp/dboard/e3xx/e3xx_bands.cpp index d3dc99fec..e28acf3b9 100644 --- a/host/lib/usrp/dboard/e3xx/e3xx_bands.cpp +++ b/host/lib/usrp/dboard/e3xx/e3xx_bands.cpp @@ -49,17 +49,27 @@ * E31x frequency bands: * * For RX: (chan here is fe_chan - swapped) - * Band Freq RX_BSEL-210 RXC_BSEL-10 RXB_BSEL-10 RX2 TX/RX - * VCRX_V1_V2 VCTXRX_V1_V2 - * chan1 | chan2 chan1 | chan2 chan1 | chan2 RX ant | TXRX ant chan2 | chan1 - * ---------------------------------------------------------------------------------------------------- - * LB_B2: < 450 RF5 100 RF6 101 J2 10 J1 01 -- 00 -- 00 01 10 J2 10 J1 01 - * LB_B3: 450-700 RF3 010 RF4 011 J3 11 J3 11 -- 00 -- 00 01 10 J2 10 J1 01 - * LB_B4: 700-1200 RF1 000 RF2 001 J1 01 J2 10 -- 00 -- 00 01 10 J2 10 J1 01 - * LB_B5: 1200-1800 RF2 001 RF1 000 -- 00 -- 00 J2 10 J1 01 01 10 J2 10 J1 01 - * LB_B6: 1800-2350 RF4 011 RF3 010 -- 00 -- 00 J3 11 J3 11 01 10 J2 10 J1 01 - * LB_B7: 2350-2600 RF6 101 RF5 100 -- 00 -- 00 J1 01 J2 10 01 10 J2 10 J1 01 - * HB: 2600+ --- 111 --- 111 -- 00 -- 00 -- 00 -- 00 10 01 J2 10 J1 01 + * Band Freq RX_BSEL-210 RXC_BSEL-10 RXB_BSEL-10 RX2 TX/RX + * VCRX_V1_V2 + VCTXRX_V1_V2 + * chan1 | chan2 chan1 | chan2 chan1 | chan2 RX ant | TXRX ant + chan2 | chan1 + * + ---------------------------------------------------------------------------------------------------- + * LB_B2: < 450 RF5 100 RF6 101 J2 10 J1 01 -- 00 -- 00 01 10 J2 10 + J1 01 + * LB_B3: 450-700 RF3 010 RF4 011 J3 11 J3 11 -- 00 -- 00 01 10 J2 10 + J1 01 + * LB_B4: 700-1200 RF1 000 RF2 001 J1 01 J2 10 -- 00 -- 00 01 10 J2 10 + J1 01 + * LB_B5: 1200-1800 RF2 001 RF1 000 -- 00 -- 00 J2 10 J1 01 01 10 J2 10 + J1 01 + * LB_B6: 1800-2350 RF4 011 RF3 010 -- 00 -- 00 J3 11 J3 11 01 10 J2 10 + J1 01 + * LB_B7: 2350-2600 RF6 101 RF5 100 -- 00 -- 00 J1 01 J2 10 01 10 J2 10 + J1 01 + * HB: 2600+ --- 111 --- 111 -- 00 -- 00 -- 00 -- 00 10 01 J2 10 + J1 01 * * * For TX: @@ -131,7 +141,8 @@ constexpr double E3XX_TX_LB_2750_MIN_FREQ = 1842.6e6; constexpr double E3XX_TX_HB_MIN_FREQ = 2940.0e6; } // namespace -e3xx_radio_control_impl::rx_band e3xx_radio_control_impl::map_freq_to_rx_band(const double freq) +e3xx_radio_control_impl::rx_band e3xx_radio_control_impl::map_freq_to_rx_band( + const double freq) { e3xx_radio_control_impl::rx_band band; @@ -158,7 +169,8 @@ e3xx_radio_control_impl::rx_band e3xx_radio_control_impl::map_freq_to_rx_band(co return band; } -e3xx_radio_control_impl::tx_band e3xx_radio_control_impl::map_freq_to_tx_band(const double freq) +e3xx_radio_control_impl::tx_band e3xx_radio_control_impl::map_freq_to_tx_band( + const double freq) { e3xx_radio_control_impl::tx_band band; diff --git a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp index bc9ed9169..49a9a9bda 100644 --- a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp +++ b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp @@ -75,7 +75,7 @@ void e3xx_radio_control_impl::deinit() * API Calls *****************************************************************************/ bool e3xx_radio_control_impl::check_topology(const std::vector<size_t>& connected_inputs, - const std::vector<size_t>& connected_outputs) + const std::vector<size_t>& connected_outputs) { if (!node_t::check_topology(connected_inputs, connected_outputs)) { return false; @@ -112,7 +112,7 @@ bool e3xx_radio_control_impl::check_topology(const std::vector<size_t>& connecte RFNOC_LOG_TRACE("RX FE0 Active: " << rx_fe0_active); RFNOC_LOG_TRACE("RX FE1 Active: " << rx_fe1_active); - //setup the active chains in the codec + // setup the active chains in the codec if (connected_inputs.size() + connected_outputs.size() == 0) { // Ensure at least one RX chain is enabled so AD9361 outputs a sample clock this->set_streaming_mode(true, false, true, false); @@ -252,19 +252,21 @@ void e3xx_radio_control_impl::set_rx_agc(const bool enb, const size_t chan) _ad9361->set_agc(rx_fe, enb); } -double e3xx_radio_control_impl::set_rx_bandwidth(const double bandwidth, const size_t chan) +double e3xx_radio_control_impl::set_rx_bandwidth( + const double bandwidth, const size_t chan) { std::lock_guard<std::mutex> l(_set_lock); - double clipped_bw = - _ad9361->set_bw_filter(get_which_ad9361_chain(RX_DIRECTION, chan, _fe_swap), bandwidth); + double clipped_bw = _ad9361->set_bw_filter( + get_which_ad9361_chain(RX_DIRECTION, chan, _fe_swap), bandwidth); return radio_control_impl::set_rx_bandwidth(clipped_bw, chan); } -double e3xx_radio_control_impl::set_tx_bandwidth(const double bandwidth, const size_t chan) +double e3xx_radio_control_impl::set_tx_bandwidth( + const double bandwidth, const size_t chan) { std::lock_guard<std::mutex> l(_set_lock); - double clipped_bw = - _ad9361->set_bw_filter(get_which_ad9361_chain(TX_DIRECTION, chan, _fe_swap), bandwidth); + double clipped_bw = _ad9361->set_bw_filter( + get_which_ad9361_chain(TX_DIRECTION, chan, _fe_swap), bandwidth); return radio_control_impl::set_tx_bandwidth(clipped_bw, chan); } @@ -429,7 +431,7 @@ void e3xx_radio_control_impl::loopback_self_test(const size_t chan) // Set 2R2T mode, stream on all channels this->set_streaming_mode(true, true, true, true); // This was in there in the E320 code, but the comments didn't make sense: - //this->set_streaming_mode(true, true, true, true); + // this->set_streaming_mode(true, true, true, true); // Set maximum rate for 2R2T mode /* FIXME * We're directly setting the master clock rate here because we want to @@ -457,29 +459,34 @@ void e3xx_radio_control_impl::loopback_self_test(const size_t chan) boost::hash_combine(hash, i); const uint32_t word32 = uint32_t(hash) & 0xfff0fff0; // Write test word to codec_idle idle register (on TX side) - regs().poke32( - regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + regmap::REG_TX_IDLE_VALUE, word32); + regs().poke32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + + regmap::REG_TX_IDLE_VALUE, + word32); // Read back values - TX is lower 32-bits and RX is upper 32-bits const uint32_t rb_tx = - regs().peek32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + regmap::REG_TX_IDLE_VALUE); + regs().peek32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + + regmap::REG_TX_IDLE_VALUE); const uint32_t rb_rx = - regs().peek32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + regmap::REG_RX_DATA); + regs().peek32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + + regmap::REG_RX_DATA); // Compare TX and RX values to test word bool test_fail = word32 != rb_tx or word32 != rb_rx; if (test_fail) { RFNOC_LOG_WARNING( "CODEC loopback test failed! " - << boost::format("Expected: 0x%08X Received (TX/RX): 0x%08X/0x%08X") - % word32 % rb_tx % rb_rx); + << boost::format("Expected: 0x%08X Received (TX/RX): 0x%08X/0x%08X") + % word32 % rb_tx % rb_rx); throw uhd::runtime_error("CODEC loopback test failed."); } } RFNOC_LOG_INFO("CODEC loopback test passed"); // Zero out the idle data. - regs().poke32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + regmap::REG_TX_IDLE_VALUE, 0); + regs().poke32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + + regmap::REG_TX_IDLE_VALUE, + 0); // Take AD936x out of loopback mode _ad9361->data_port_loopback(false); diff --git a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.hpp b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.hpp index f49cde64a..d5714634c 100644 --- a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.hpp +++ b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.hpp @@ -9,11 +9,11 @@ #define INCLUDED_LIBUHD_RFNOC_E3XX_RADIO_CTRL_IMPL_HPP #include "e3xx_ad9361_iface.hpp" +#include <uhd/rfnoc/filter_node.hpp> #include <uhd/types/eeprom.hpp> #include <uhd/types/serial.hpp> #include <uhd/usrp/dboard_manager.hpp> #include <uhd/usrp/gpio_defs.hpp> -#include <uhd/rfnoc/filter_node.hpp> #include <uhdlib/rfnoc/radio_control_impl.hpp> #include <uhdlib/usrp/common/mpmd_mb_controller.hpp> #include <uhdlib/usrp/cores/gpio_atr_3000.hpp> @@ -22,22 +22,23 @@ namespace uhd { namespace rfnoc { namespace e3xx_regs { - constexpr uint32_t PERIPH_BASE = 0x80000; - constexpr uint32_t PERIPH_REG_OFFSET = 8; - constexpr uint32_t PERIPH_REG_CHAN_OFFSET = 0x800; - constexpr uint32_t SR_LEDS = PERIPH_BASE + 176 * PERIPH_REG_OFFSET; - constexpr uint32_t SR_FP_GPIO = PERIPH_BASE + 184 * PERIPH_REG_OFFSET; - constexpr uint32_t SR_DB_GPIO = PERIPH_BASE + 192 * PERIPH_REG_OFFSET; +constexpr uint32_t PERIPH_BASE = 0x80000; +constexpr uint32_t PERIPH_REG_OFFSET = 8; +constexpr uint32_t PERIPH_REG_CHAN_OFFSET = 0x800; +constexpr uint32_t SR_LEDS = PERIPH_BASE + 176 * PERIPH_REG_OFFSET; +constexpr uint32_t SR_FP_GPIO = PERIPH_BASE + 184 * PERIPH_REG_OFFSET; +constexpr uint32_t SR_DB_GPIO = PERIPH_BASE + 192 * PERIPH_REG_OFFSET; - constexpr uint32_t RB_DB_GPIO = PERIPH_BASE + 19 * PERIPH_REG_OFFSET; - constexpr uint32_t RB_FP_GPIO = PERIPH_BASE + 20 * PERIPH_REG_OFFSET; +constexpr uint32_t RB_DB_GPIO = PERIPH_BASE + 19 * PERIPH_REG_OFFSET; +constexpr uint32_t RB_FP_GPIO = PERIPH_BASE + 20 * PERIPH_REG_OFFSET; -} +} // namespace e3xx_regs /*! \brief Provide access to an E3xx radio. */ -class e3xx_radio_control_impl : public radio_control_impl, public uhd::rfnoc::detail::filter_node +class e3xx_radio_control_impl : public radio_control_impl, + public uhd::rfnoc::detail::filter_node { public: //! Frequency bands for RX. Bands are a function of the analog filter banks @@ -78,7 +79,7 @@ public: void deinit(); bool check_topology(const std::vector<size_t>& connected_inputs, - const std::vector<size_t>& connected_outputs); + const std::vector<size_t>& connected_outputs); /************************************************************************ * radio_control API calls @@ -87,8 +88,8 @@ public: uhd::meta_range_t get_rate_range() const; // Setters - void set_tx_antenna(const std::string &ant, const size_t chan); - void set_rx_antenna(const std::string &ant, const size_t chan); + void set_tx_antenna(const std::string& ant, const size_t chan); + void set_rx_antenna(const std::string& ant, const size_t chan); double set_tx_frequency(const double freq, const size_t chan); double set_rx_frequency(const double freq, const size_t chan); double set_tx_gain(const double gain, const size_t chan); @@ -144,7 +145,10 @@ public: /************************************************************************** * Radio Identification API Calls *************************************************************************/ - std::string get_slot_name() const { return "A"; } + std::string get_slot_name() const + { + return "A"; + } virtual size_t get_chan_from_dboard_fe( const std::string& fe, const uhd::direction_t direction) const; virtual std::string get_dboard_fe_from_chan( diff --git a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_init.cpp b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_init.cpp index 6ecf4ff2a..f44bdaeb7 100644 --- a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_init.cpp +++ b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_init.cpp @@ -103,8 +103,10 @@ void e3xx_radio_control_impl::_init_peripherals() usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL); } RFNOC_LOG_TRACE("Initializing front-panel GPIO control...") - _fp_gpio = usrp::gpio_atr::gpio_atr_3000::make( - _wb_ifaces.at(0), e3xx_regs::SR_FP_GPIO, e3xx_regs::RB_FP_GPIO, e3xx_regs::PERIPH_REG_OFFSET); + _fp_gpio = usrp::gpio_atr::gpio_atr_3000::make(_wb_ifaces.at(0), + e3xx_regs::SR_FP_GPIO, + e3xx_regs::RB_FP_GPIO, + e3xx_regs::PERIPH_REG_OFFSET); auto block_args = get_block_args(); @@ -123,9 +125,9 @@ void e3xx_radio_control_impl::_init_frontend_subtree( { const fs_path tx_fe_path = fs_path("tx_frontends") / chan_idx; const fs_path rx_fe_path = fs_path("rx_frontends") / chan_idx; - RFNOC_LOG_TRACE( - "Adding non-RFNoC block properties for channel " - << chan_idx << " to prop tree path " << tx_fe_path << " and " << rx_fe_path); + RFNOC_LOG_TRACE("Adding non-RFNoC block properties for channel " + << chan_idx << " to prop tree path " << tx_fe_path << " and " + << rx_fe_path); // TX Standard attributes subtree->create<std::string>(tx_fe_path / "name").set("E3xx"); subtree->create<std::string>(tx_fe_path / "connection").set("IQ"); @@ -242,7 +244,8 @@ void e3xx_radio_control_impl::_init_frontend_subtree( auto rx_sensor_names = get_rx_sensor_names(chan_idx); for (const auto& rx_sensor_name : rx_sensor_names) { RFNOC_LOG_TRACE("Adding RX sensor " << rx_sensor_name); - get_tree()->create<sensor_value_t>(rx_fe_path / "sensors" / rx_sensor_name) + get_tree() + ->create<sensor_value_t>(rx_fe_path / "sensors" / rx_sensor_name) .add_coerced_subscriber([](const sensor_value_t&) { throw uhd::runtime_error("Attempting to write to sensor!"); }) @@ -253,7 +256,8 @@ void e3xx_radio_control_impl::_init_frontend_subtree( auto tx_sensor_names = get_tx_sensor_names(chan_idx); for (const auto& tx_sensor_name : tx_sensor_names) { RFNOC_LOG_TRACE("Adding TX sensor " << tx_sensor_name); - get_tree()->create<sensor_value_t>(tx_fe_path / "sensors" / tx_sensor_name) + get_tree() + ->create<sensor_value_t>(tx_fe_path / "sensors" / tx_sensor_name) .add_coerced_subscriber([](const sensor_value_t&) { throw uhd::runtime_error("Attempting to write to sensor!"); }) @@ -301,4 +305,3 @@ void e3xx_radio_control_impl::_init_codec() this->set_tx_bandwidth(E3XX_DEFAULT_BANDWIDTH, chan); } } - diff --git a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp index f71b1aa4e..adb93ced7 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp @@ -42,7 +42,7 @@ double magnesium_ad9371_iface::set_frequency( const double freq, const size_t chan, const direction_t dir) { // Note: This sets the frequency for both channels (1 and 2). - auto which = _get_which(dir, chan); + auto which = _get_which(dir, chan); auto actual_freq = request<double>(MAGNESIUM_TUNE_TIMEOUT, "set_freq", which, freq, false); UHD_LOG_TRACE(_log_prefix, _rpc_prefix << "set_freq returned " << actual_freq); diff --git a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp index 2374a4503..2cb691025 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp @@ -55,10 +55,7 @@ private: { UHD_LOG_TRACE(_log_prefix, "[RPC] Calling " << func_name); return _rpcc->request_with_token<return_type>( - timeout_ms, - _rpc_prefix + func_name, - std::forward<Args>(args)... - ); + timeout_ms, _rpc_prefix + func_name, std::forward<Args>(args)...); }; //! Reference to the RPC client diff --git a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp index 3d670e4a3..dedb9e924 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp @@ -110,6 +110,6 @@ static constexpr uint32_t RB_MISC_IO = PERIPH_BASE + 16 * PERIPH_REG_OFFSET; static constexpr uint32_t RB_SPI = PERIPH_BASE + 17 * PERIPH_REG_OFFSET; static constexpr uint32_t RB_DB_GPIO = PERIPH_BASE + 19 * PERIPH_REG_OFFSET; static constexpr uint32_t RB_FP_GPIO = PERIPH_BASE + 20 * PERIPH_REG_OFFSET; -} +} // namespace n310_regs #endif /* INCLUDED_LIBUHD_MAGNESIUM_CONSTANTS_HPP */ diff --git a/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.hpp b/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.hpp index 8f4ee0caa..27341673c 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.hpp @@ -11,9 +11,9 @@ #include "adf4351_regs.hpp" #include "magnesium_cpld_regs.hpp" #include <uhd/types/serial.hpp> +#include <functional> #include <memory> #include <mutex> -#include <functional> //! Controls the CPLD on a Magnesium daughterboard // diff --git a/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp b/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp index 6ba91a248..feff1d6f9 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp @@ -30,13 +30,13 @@ struct gain_tuple_t /*! Given a gain index, return a tuple of gain-related settings (Rx) */ -gain_tuple_t get_rx_gain_tuple( - const double gain_index, const uhd::rfnoc::magnesium_radio_control_impl::rx_band band_); +gain_tuple_t get_rx_gain_tuple(const double gain_index, + const uhd::rfnoc::magnesium_radio_control_impl::rx_band band_); /*! Given a gain index, return a tuple of gain-related settings (Tx) */ -gain_tuple_t get_tx_gain_tuple( - const double gain_index, const uhd::rfnoc::magnesium_radio_control_impl::tx_band band_); +gain_tuple_t get_tx_gain_tuple(const double gain_index, + const uhd::rfnoc::magnesium_radio_control_impl::tx_band band_); } /* namespace magnesium */ diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp index 28a7b0c41..e4d446f95 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp @@ -15,12 +15,11 @@ #include <uhd/utils/algorithm.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/math.hpp> -#include <uhd/rfnoc/registry.hpp> #include <boost/algorithm/string.hpp> #include <boost/format.hpp> -#include <memory> #include <cmath> #include <cstdlib> +#include <memory> #include <sstream> using namespace uhd; @@ -206,7 +205,8 @@ double magnesium_radio_control_impl::set_rate(double requested_rate) return _master_clock_rate; } -void magnesium_radio_control_impl::set_tx_antenna(const std::string& ant, const size_t chan) +void magnesium_radio_control_impl::set_tx_antenna( + const std::string& ant, const size_t chan) { if (ant != get_tx_antenna(chan)) { throw uhd::value_error( @@ -216,7 +216,8 @@ void magnesium_radio_control_impl::set_tx_antenna(const std::string& ant, const // We can't actually set the TX antenna, so let's stop here. } -void magnesium_radio_control_impl::set_rx_antenna(const std::string& ant, const size_t chan) +void magnesium_radio_control_impl::set_rx_antenna( + const std::string& ant, const size_t chan) { UHD_ASSERT_THROW(chan <= MAGNESIUM_NUM_CHANS); if (std::find(MAGNESIUM_RX_ANTENNAS.begin(), MAGNESIUM_RX_ANTENNAS.end(), ant) @@ -233,7 +234,8 @@ void magnesium_radio_control_impl::set_rx_antenna(const std::string& ant, const radio_control_impl::set_rx_antenna(ant, chan); } -double magnesium_radio_control_impl::set_tx_frequency(const double req_freq, const size_t chan) +double magnesium_radio_control_impl::set_tx_frequency( + const double req_freq, const size_t chan) { const double freq = MAGNESIUM_FREQ_RANGE.clip(req_freq); RFNOC_LOG_TRACE("set_tx_frequency(f=" << freq << ", chan=" << chan << ")"); @@ -269,7 +271,8 @@ double magnesium_radio_control_impl::set_tx_frequency(const double req_freq, con return radio_control_impl::get_tx_frequency(chan); } -void magnesium_radio_control_impl::_update_gain(const size_t chan, const uhd::direction_t dir) +void magnesium_radio_control_impl::_update_gain( + const size_t chan, const uhd::direction_t dir) { const std::string fe = (dir == TX_DIRECTION) ? "tx_frontends" : "rx_frontends"; const double freq = (dir == TX_DIRECTION) ? this->get_tx_frequency(chan) @@ -277,7 +280,8 @@ void magnesium_radio_control_impl::_update_gain(const size_t chan, const uhd::di this->_set_all_gain(this->_get_all_gain(chan, dir), freq, chan, dir); } -void magnesium_radio_control_impl::_update_freq(const size_t chan, const uhd::direction_t dir) +void magnesium_radio_control_impl::_update_freq( + const size_t chan, const uhd::direction_t dir) { const std::string ad9371_source = dir == TX_DIRECTION ? this->get_tx_lo_source(MAGNESIUM_LO1, chan) @@ -301,7 +305,8 @@ void magnesium_radio_control_impl::_update_freq(const size_t chan, const uhd::di } } -double magnesium_radio_control_impl::set_rx_frequency(const double req_freq, const size_t chan) +double magnesium_radio_control_impl::set_rx_frequency( + const double req_freq, const size_t chan) { const double freq = MAGNESIUM_FREQ_RANGE.clip(req_freq); RFNOC_LOG_TRACE("set_rx_frequency(f=" << freq << ", chan=" << chan << ")"); @@ -366,8 +371,7 @@ double magnesium_radio_control_impl::set_tx_bandwidth( void magnesium_radio_control_impl::set_tx_gain_profile( const std::string& profile, const size_t) { - if (std::find( - MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) + if (std::find(MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) == MAGNESIUM_GP_OPTIONS.end()) { RFNOC_LOG_ERROR("Invalid TX gain profile: " << profile); throw uhd::key_error("Invalid TX gain profile!"); @@ -378,8 +382,7 @@ void magnesium_radio_control_impl::set_tx_gain_profile( void magnesium_radio_control_impl::set_rx_gain_profile( const std::string& profile, const size_t) { - if (std::find( - MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) + if (std::find(MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) == MAGNESIUM_GP_OPTIONS.end()) { RFNOC_LOG_ERROR("Invalid RX gain profile: " << profile); throw uhd::key_error("Invalid RX gain profile!"); @@ -592,12 +595,14 @@ uhd::freq_range_t magnesium_radio_control_impl::get_rx_frequency_range(const siz return meta_range_t(MAGNESIUM_MIN_FREQ, MAGNESIUM_MAX_FREQ, 1.0); } -std::vector<std::string> magnesium_radio_control_impl::get_tx_gain_names(const size_t) const +std::vector<std::string> magnesium_radio_control_impl::get_tx_gain_names( + const size_t) const { return {MAGNESIUM_GAIN1, MAGNESIUM_GAIN2, MAGNESIUM_AMP}; } -std::vector<std::string> magnesium_radio_control_impl::get_rx_gain_names(const size_t) const +std::vector<std::string> magnesium_radio_control_impl::get_rx_gain_names( + const size_t) const { return {MAGNESIUM_GAIN1, MAGNESIUM_GAIN2, MAGNESIUM_AMP}; } @@ -710,7 +715,8 @@ std::vector<std::string> magnesium_radio_control_impl::get_tx_gain_profile_names return MAGNESIUM_GP_OPTIONS; } -std::vector<std::string> magnesium_radio_control_impl::get_rx_gain_profile_names(const size_t ) const +std::vector<std::string> magnesium_radio_control_impl::get_rx_gain_profile_names( + const size_t) const { return MAGNESIUM_GP_OPTIONS; } @@ -761,7 +767,7 @@ std::vector<std::string> magnesium_radio_control_impl::get_rx_lo_sources( freq_range_t magnesium_radio_control_impl::get_rx_lo_freq_range( const std::string& name, const size_t /*chan*/ -) const + ) const { if (name == MAGNESIUM_LO1) { return freq_range_t{ADF4351_MIN_FREQ, ADF4351_MAX_FREQ}; @@ -790,7 +796,7 @@ void magnesium_radio_control_impl::set_rx_lo_source( const std::string magnesium_radio_control_impl::get_rx_lo_source( const std::string& name, const size_t /*chan*/ -) const + ) const { if (name == MAGNESIUM_LO1) { // TODO: should we use this from cache? @@ -860,14 +866,14 @@ double magnesium_radio_control_impl::get_rx_lo_freq( // TX LO std::vector<std::string> magnesium_radio_control_impl::get_tx_lo_names( const size_t /*chan*/ -) const + ) const { return std::vector<std::string>{MAGNESIUM_LO1, MAGNESIUM_LO2}; } std::vector<std::string> magnesium_radio_control_impl::get_tx_lo_sources( const std::string& name, const size_t /*chan*/ -) const + ) const { if (name == MAGNESIUM_LO2) { return std::vector<std::string>{"internal"}; @@ -960,7 +966,8 @@ double magnesium_radio_control_impl::set_tx_lo_freq( return return_freq; } -double magnesium_radio_control_impl::get_tx_lo_freq(const std::string& name, const size_t chan) +double magnesium_radio_control_impl::get_tx_lo_freq( + const std::string& name, const size_t chan) { RFNOC_LOG_TRACE("get_tx_lo_freq(name=" << name << ")"); std::string source = this->get_tx_lo_source(name, chan); @@ -1106,7 +1113,8 @@ std::vector<std::string> magnesium_radio_control_impl::get_rx_sensor_names(size_ return sensor_names; } -sensor_value_t magnesium_radio_control_impl::get_rx_sensor(const std::string& name, size_t chan) +sensor_value_t magnesium_radio_control_impl::get_rx_sensor( + const std::string& name, size_t chan) { if (name == "lo_locked") { return sensor_value_t( @@ -1124,7 +1132,8 @@ std::vector<std::string> magnesium_radio_control_impl::get_tx_sensor_names(size_ return sensor_names; } -sensor_value_t magnesium_radio_control_impl::get_tx_sensor(const std::string& name, size_t chan) +sensor_value_t magnesium_radio_control_impl::get_tx_sensor( + const std::string& name, size_t chan) { if (name == "lo_locked") { return sensor_value_t( @@ -1137,7 +1146,8 @@ sensor_value_t magnesium_radio_control_impl::get_tx_sensor(const std::string& na /************************************************************************** * node_t API Calls *************************************************************************/ -void magnesium_radio_control_impl::set_command_time(uhd::time_spec_t time, const size_t chan) +void magnesium_radio_control_impl::set_command_time( + uhd::time_spec_t time, const size_t chan) { node_t::set_command_time(time, chan); _wb_ifaces.at(chan)->set_time(time); diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp index c6d8e0338..3c965866e 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp @@ -14,15 +14,15 @@ #include "magnesium_ad9371_iface.hpp" #include "magnesium_cpld_ctrl.hpp" #include "magnesium_cpld_regs.hpp" -#include <iostream> +#include <uhd/types/eeprom.hpp> #include <uhd/types/serial.hpp> #include <uhd/usrp/dboard_manager.hpp> #include <uhd/usrp/gpio_defs.hpp> -#include <uhd/types/eeprom.hpp> #include <uhdlib/rfnoc/radio_control_impl.hpp> #include <uhdlib/usrp/common/adf435x.hpp> #include <uhdlib/usrp/common/mpmd_mb_controller.hpp> #include <uhdlib/usrp/cores/gpio_atr_3000.hpp> +#include <iostream> #include <mutex> namespace uhd { namespace rfnoc { @@ -77,8 +77,8 @@ public: double set_rate(double rate); // Setters - void set_tx_antenna(const std::string &ant, const size_t chan); - void set_rx_antenna(const std::string &ant, const size_t chan); + void set_tx_antenna(const std::string& ant, const size_t chan); + void set_rx_antenna(const std::string& ant, const size_t chan); double set_tx_frequency(const double freq, const size_t chan); double set_rx_frequency(const double freq, const size_t chan); double set_tx_gain(const double gain, const size_t chan); @@ -157,13 +157,15 @@ public: /************************************************************************** * Radio Identification API Calls *************************************************************************/ - std::string get_slot_name() const { return _radio_slot; } + std::string get_slot_name() const + { + return _radio_slot; + } size_t get_chan_from_dboard_fe( const std::string& fe, const uhd::direction_t direction) const; std::string get_dboard_fe_from_chan( const size_t chan, const uhd::direction_t direction) const; - std::string get_fe_name( - const size_t chan, const uhd::direction_t direction) const; + std::string get_fe_name(const size_t chan, const uhd::direction_t direction) const; /************************************************************************** * node_t API Calls diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_cpld.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_cpld.cpp index 41f99cd68..a4decdaaa 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_cpld.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_cpld.cpp @@ -120,12 +120,11 @@ void magnesium_radio_control_impl::_update_rx_freq_switches(const double freq, const bool bypass_lnas, const magnesium_cpld_ctrl::chan_sel_t chan_sel) { - RFNOC_LOG_TRACE( - "Update all RX freq related switches. f=" << freq - << " Hz, " - "bypass LNAS: " - << (bypass_lnas ? "Yes" : "No") - << ", chan=" << chan_sel); + RFNOC_LOG_TRACE("Update all RX freq related switches. f=" + << freq + << " Hz, " + "bypass LNAS: " + << (bypass_lnas ? "Yes" : "No") << ", chan=" << chan_sel); auto rx_sw2 = magnesium_cpld_ctrl::RX_SW2_BYPASSPATHTOSWITCH6; auto rx_sw3 = magnesium_cpld_ctrl::RX_SW3_SHUTDOWNSW3; auto rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2100X2850MHZFROM; diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp index f515b2e33..b06222205 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp @@ -7,8 +7,8 @@ #include "magnesium_constants.hpp" #include "magnesium_gain_table.hpp" #include "magnesium_radio_control.hpp" -#include <uhd/utils/log.hpp> #include <uhd/exception.hpp> +#include <uhd/utils/log.hpp> using namespace uhd; using namespace uhd::usrp; @@ -61,14 +61,13 @@ double magnesium_radio_control_impl::_set_all_gain( const double ad9371_gain = ((dir == RX_DIRECTION) ? AD9371_MAX_RX_GAIN : AD9371_MAX_TX_GAIN) - gain_tuple.ad9371_att; - RFNOC_LOG_TRACE( - "AD9371 attenuation==" << gain_tuple.ad9371_att - << " dB, " - "AD9371 gain==" - << ad9371_gain - << " dB, " - "DSA attenuation == " - << gain_tuple.dsa_att << " dB."); + RFNOC_LOG_TRACE("AD9371 attenuation==" << gain_tuple.ad9371_att + << " dB, " + "AD9371 gain==" + << ad9371_gain + << " dB, " + "DSA attenuation == " + << gain_tuple.dsa_att << " dB."); _ad9371->set_gain(ad9371_gain, ad9371_chan, dir); _dsa_set_att(gain_tuple.dsa_att, chan, dir); if (dir == RX_DIRECTION or dir == DX_DIRECTION) { @@ -101,9 +100,8 @@ double magnesium_radio_control_impl::_get_all_gain( double magnesium_radio_control_impl::_dsa_set_att( const double att, const size_t chan, const direction_t dir) { - RFNOC_LOG_TRACE( - __func__ << "(att=" - << "att dB, chan=" << chan << ", dir=" << dir << ")") + RFNOC_LOG_TRACE(__func__ << "(att=" + << "att dB, chan=" << chan << ", dir=" << dir << ")") const uint32_t dsa_val = 2 * att; _set_dsa_val(chan, dir, dsa_val); diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp index 6595cb113..d9bf5c3d2 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp @@ -9,8 +9,8 @@ #include <uhd/types/eeprom.hpp> #include <uhd/types/sensors.hpp> #include <uhd/utils/log.hpp> -#include <uhdlib/usrp/cores/spi_core_3000.hpp> #include <uhdlib/rfnoc/reg_iface_adapter.hpp> +#include <uhdlib/usrp/cores/spi_core_3000.hpp> #include <boost/algorithm/string.hpp> #include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/split.hpp> @@ -25,8 +25,8 @@ namespace { enum slave_select_t { SEN_CPLD = 1, SEN_TX_LO = 2, SEN_RX_LO = 4, SEN_PHASE_DAC = 8 }; -constexpr double MAGNESIUM_DEFAULT_FREQ = 2.5e9; // Hz -constexpr double MAGNESIUM_DEFAULT_BANDWIDTH = 100e6; // Hz +constexpr double MAGNESIUM_DEFAULT_FREQ = 2.5e9; // Hz +constexpr double MAGNESIUM_DEFAULT_BANDWIDTH = 100e6; // Hz } // namespace @@ -148,10 +148,12 @@ void magnesium_radio_control_impl::_init_frontend_subtree( << chan_idx << " to prop tree path " << tx_fe_path << " and " << rx_fe_path); // TX Standard attributes - subtree->create<std::string>(tx_fe_path / "name").set(get_fe_name(chan_idx, TX_DIRECTION)); + subtree->create<std::string>(tx_fe_path / "name") + .set(get_fe_name(chan_idx, TX_DIRECTION)); subtree->create<std::string>(tx_fe_path / "connection").set("IQ"); // RX Standard attributes - subtree->create<std::string>(rx_fe_path / "name").set(get_fe_name(chan_idx, RX_DIRECTION)); + subtree->create<std::string>(rx_fe_path / "name") + .set(get_fe_name(chan_idx, RX_DIRECTION)); subtree->create<std::string>(rx_fe_path / "connection").set("IQ"); // TX Antenna subtree->create<std::string>(tx_fe_path / "antenna" / "value") @@ -160,7 +162,7 @@ void magnesium_radio_control_impl::_init_frontend_subtree( }) .set_publisher([this, chan_idx]() { return this->get_tx_antenna(chan_idx); }); subtree->create<std::vector<std::string>>(tx_fe_path / "antenna" / "options") - .set_publisher([this](){ return get_tx_antennas(0); }) + .set_publisher([this]() { return get_tx_antennas(0); }) .add_coerced_subscriber([](const std::vector<std::string>&) { throw uhd::runtime_error("Attempting to update antenna options!"); }); @@ -171,7 +173,7 @@ void magnesium_radio_control_impl::_init_frontend_subtree( }) .set_publisher([this, chan_idx]() { return this->get_rx_antenna(chan_idx); }); subtree->create<std::vector<std::string>>(rx_fe_path / "antenna" / "options") - .set_publisher([this](){ return get_rx_antennas(0); }) + .set_publisher([this]() { return get_rx_antennas(0); }) .add_coerced_subscriber([](const std::vector<std::string>&) { throw uhd::runtime_error("Attempting to update antenna options!"); }); @@ -182,7 +184,7 @@ void magnesium_radio_control_impl::_init_frontend_subtree( }) .set_publisher([this, chan_idx]() { return this->get_tx_frequency(chan_idx); }); subtree->create<meta_range_t>(tx_fe_path / "freq" / "range") - .set_publisher([this, chan_idx](){ return get_tx_frequency_range(chan_idx); }) + .set_publisher([this, chan_idx]() { return get_tx_frequency_range(chan_idx); }) .add_coerced_subscriber([](const meta_range_t&) { throw uhd::runtime_error("Attempting to update freq range!"); }); @@ -193,7 +195,7 @@ void magnesium_radio_control_impl::_init_frontend_subtree( }) .set_publisher([this, chan_idx]() { return this->get_rx_frequency(chan_idx); }); subtree->create<meta_range_t>(rx_fe_path / "freq" / "range") - .set_publisher([this, chan_idx](){ return get_rx_frequency_range(chan_idx); }) + .set_publisher([this, chan_idx]() { return get_rx_frequency_range(chan_idx); }) .add_coerced_subscriber([](const meta_range_t&) { throw uhd::runtime_error("Attempting to update freq range!"); }); @@ -205,7 +207,7 @@ void magnesium_radio_control_impl::_init_frontend_subtree( }) .set_publisher([this, chan_idx]() { return this->get_tx_bandwidth(chan_idx); }); subtree->create<meta_range_t>(tx_fe_path / "bandwidth" / "range") - .set_publisher([this, chan_idx](){ return get_tx_bandwidth_range(chan_idx); }) + .set_publisher([this, chan_idx]() { return get_tx_bandwidth_range(chan_idx); }) .add_coerced_subscriber([](const meta_range_t&) { throw uhd::runtime_error("Attempting to update bandwidth range!"); }); @@ -217,7 +219,7 @@ void magnesium_radio_control_impl::_init_frontend_subtree( }) .set_publisher([this, chan_idx]() { return this->get_rx_bandwidth(chan_idx); }); subtree->create<meta_range_t>(rx_fe_path / "bandwidth" / "range") - .set_publisher([this, chan_idx](){ return get_rx_bandwidth_range(chan_idx); }) + .set_publisher([this, chan_idx]() { return get_rx_bandwidth_range(chan_idx); }) .add_coerced_subscriber([](const meta_range_t&) { throw uhd::runtime_error("Attempting to update bandwidth range!"); }); @@ -230,13 +232,16 @@ void magnesium_radio_control_impl::_init_frontend_subtree( .set_coercer([this, chan_idx, gain_name](const double gain) { return this->set_tx_gain(gain, gain_name, chan_idx); }) - .set_publisher( - [this, chan_idx, gain_name]() { return get_tx_gain(gain_name, chan_idx); }); + .set_publisher([this, chan_idx, gain_name]() { + return get_tx_gain(gain_name, chan_idx); + }); subtree->create<meta_range_t>(tx_fe_path / "gains" / gain_name / "range") .add_coerced_subscriber([](const meta_range_t&) { throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this, gain_name, chan_idx]() { return get_tx_gain_range(gain_name, chan_idx); }); + .set_publisher([this, gain_name, chan_idx]() { + return get_tx_gain_range(gain_name, chan_idx); + }); } subtree->create<std::vector<std::string>>(tx_fe_path / "gains/all/profile/options") .set_publisher( @@ -256,13 +261,16 @@ void magnesium_radio_control_impl::_init_frontend_subtree( .set_coercer([this, chan_idx, gain_name](const double gain) { return this->set_rx_gain(gain, gain_name, chan_idx); }) - .set_publisher( - [this, chan_idx, gain_name]() { return get_rx_gain(gain_name, chan_idx); }); + .set_publisher([this, chan_idx, gain_name]() { + return get_rx_gain(gain_name, chan_idx); + }); subtree->create<meta_range_t>(rx_fe_path / "gains" / gain_name / "range") .add_coerced_subscriber([](const meta_range_t&) { throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this, gain_name, chan_idx]() { return get_rx_gain_range(gain_name, chan_idx); }); + .set_publisher([this, gain_name, chan_idx]() { + return get_rx_gain_range(gain_name, chan_idx); + }); } subtree->create<std::vector<std::string>>(rx_fe_path / "gains/all/profile/options") .set_publisher( @@ -375,7 +383,8 @@ void magnesium_radio_control_impl::_init_frontend_subtree( auto rx_sensor_names = get_rx_sensor_names(chan_idx); for (const auto& sensor_name : rx_sensor_names) { RFNOC_LOG_TRACE("Adding RX sensor " << sensor_name); - get_tree()->create<sensor_value_t>(rx_fe_path / "sensors" / sensor_name) + get_tree() + ->create<sensor_value_t>(rx_fe_path / "sensors" / sensor_name) .add_coerced_subscriber([](const sensor_value_t&) { throw uhd::runtime_error("Attempting to write to sensor!"); }) @@ -386,7 +395,8 @@ void magnesium_radio_control_impl::_init_frontend_subtree( auto tx_sensor_names = get_tx_sensor_names(chan_idx); for (const auto& sensor_name : tx_sensor_names) { RFNOC_LOG_TRACE("Adding TX sensor " << sensor_name); - get_tree()->create<sensor_value_t>(tx_fe_path / "sensors" / sensor_name) + get_tree() + ->create<sensor_value_t>(tx_fe_path / "sensors" / sensor_name) .add_coerced_subscriber([](const sensor_value_t&) { throw uhd::runtime_error("Attempting to write to sensor!"); }) @@ -403,7 +413,8 @@ void magnesium_radio_control_impl::_init_prop_tree() } // DB EEPROM - get_tree()->create<eeprom_map_t>("eeprom") + get_tree() + ->create<eeprom_map_t>("eeprom") .add_coerced_subscriber( [this](const eeprom_map_t& db_eeprom) { set_db_eeprom(db_eeprom); }) .set_publisher([this]() { return get_db_eeprom(); }); @@ -446,4 +457,3 @@ void magnesium_radio_control_impl::_init_mpm() _n3xx_timekeeper->update_tick_rate(_master_clock_rate); radio_control_impl::set_rate(_master_clock_rate); } - diff --git a/host/lib/usrp/dboard/rhodium/rhodium_bands.cpp b/host/lib/usrp/dboard/rhodium/rhodium_bands.cpp index 9e0a1d3d3..9f72135dd 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_bands.cpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_bands.cpp @@ -14,58 +14,58 @@ using namespace uhd::rfnoc; using namespace uhd::math::fp_compare; namespace { - constexpr double FREQ_COMPARE_EPSILON = 1e-5; +constexpr double FREQ_COMPARE_EPSILON = 1e-5; - /* Note on the RX filter bank: - * - * The RX path has 8 bands, which we call BAND0 through BAND7. BAND0 is the - * lowest frequency band. BAND7 is the highest frequency band. - * - * The following constants define lower cutoff frequencies for each band. - * RHODIUM_RX_BAND1_MIN_FREQ is the cutover frequency for switching from - * BAND0 to BAND1, and so on. - * - * Bands 1-7 have both high- and low-pass filters (effectively band - * passes). Band 0 has only low-pass filters. Frequencies have been - * chosen to allow as much of the full bandwidth through unattenuated. - * - * Switch selection logic for these bands can be found in - * rhodium_radio_control_impl::_update_rx_freq_switches() - */ - constexpr double RHODIUM_RX_BAND0_MIN_FREQ = RHODIUM_MIN_FREQ; - constexpr double RHODIUM_RX_BAND1_MIN_FREQ = 450e6; - constexpr double RHODIUM_RX_BAND2_MIN_FREQ = 760e6; - constexpr double RHODIUM_RX_BAND3_MIN_FREQ = 1100e6; - constexpr double RHODIUM_RX_BAND4_MIN_FREQ = 1410e6; - constexpr double RHODIUM_RX_BAND5_MIN_FREQ = 2050e6; - constexpr double RHODIUM_RX_BAND6_MIN_FREQ = 3000e6; - constexpr double RHODIUM_RX_BAND7_MIN_FREQ = 4500e6; +/* Note on the RX filter bank: + * + * The RX path has 8 bands, which we call BAND0 through BAND7. BAND0 is the + * lowest frequency band. BAND7 is the highest frequency band. + * + * The following constants define lower cutoff frequencies for each band. + * RHODIUM_RX_BAND1_MIN_FREQ is the cutover frequency for switching from + * BAND0 to BAND1, and so on. + * + * Bands 1-7 have both high- and low-pass filters (effectively band + * passes). Band 0 has only low-pass filters. Frequencies have been + * chosen to allow as much of the full bandwidth through unattenuated. + * + * Switch selection logic for these bands can be found in + * rhodium_radio_control_impl::_update_rx_freq_switches() + */ +constexpr double RHODIUM_RX_BAND0_MIN_FREQ = RHODIUM_MIN_FREQ; +constexpr double RHODIUM_RX_BAND1_MIN_FREQ = 450e6; +constexpr double RHODIUM_RX_BAND2_MIN_FREQ = 760e6; +constexpr double RHODIUM_RX_BAND3_MIN_FREQ = 1100e6; +constexpr double RHODIUM_RX_BAND4_MIN_FREQ = 1410e6; +constexpr double RHODIUM_RX_BAND5_MIN_FREQ = 2050e6; +constexpr double RHODIUM_RX_BAND6_MIN_FREQ = 3000e6; +constexpr double RHODIUM_RX_BAND7_MIN_FREQ = 4500e6; - /* Note on the TX filter bank: - * - * The TX path has 8 bands, which we call BAND0 through BAND7. BAND0 is the - * lowest frequency band. BAND7 is the highest frequency band. - * - * The following constants define lower cutoff frequencies for each band. - * RHODIUM_TX_BAND1_MIN_FREQ is the cutover frequency for switching from - * BAND0 to BAND1, and so on. - * - * All filters on the TX filter bank are low pass filters (no high pass - * filters). Frequencies have been chosen to allow as much of the full - * bandwidth through unattenuated. - * - * Switch selection logic for these bands can be found in - * rhodium_radio_control_impl::_update_tx_freq_switches() - */ - constexpr double RHODIUM_TX_BAND0_MIN_FREQ = RHODIUM_MIN_FREQ; - constexpr double RHODIUM_TX_BAND1_MIN_FREQ = 450e6; - constexpr double RHODIUM_TX_BAND2_MIN_FREQ = 650e6; - constexpr double RHODIUM_TX_BAND3_MIN_FREQ = 1000e6; - constexpr double RHODIUM_TX_BAND4_MIN_FREQ = 1350e6; - constexpr double RHODIUM_TX_BAND5_MIN_FREQ = 1900e6; - constexpr double RHODIUM_TX_BAND6_MIN_FREQ = 3000e6; - constexpr double RHODIUM_TX_BAND7_MIN_FREQ = 4100e6; -} +/* Note on the TX filter bank: + * + * The TX path has 8 bands, which we call BAND0 through BAND7. BAND0 is the + * lowest frequency band. BAND7 is the highest frequency band. + * + * The following constants define lower cutoff frequencies for each band. + * RHODIUM_TX_BAND1_MIN_FREQ is the cutover frequency for switching from + * BAND0 to BAND1, and so on. + * + * All filters on the TX filter bank are low pass filters (no high pass + * filters). Frequencies have been chosen to allow as much of the full + * bandwidth through unattenuated. + * + * Switch selection logic for these bands can be found in + * rhodium_radio_control_impl::_update_tx_freq_switches() + */ +constexpr double RHODIUM_TX_BAND0_MIN_FREQ = RHODIUM_MIN_FREQ; +constexpr double RHODIUM_TX_BAND1_MIN_FREQ = 450e6; +constexpr double RHODIUM_TX_BAND2_MIN_FREQ = 650e6; +constexpr double RHODIUM_TX_BAND3_MIN_FREQ = 1000e6; +constexpr double RHODIUM_TX_BAND4_MIN_FREQ = 1350e6; +constexpr double RHODIUM_TX_BAND5_MIN_FREQ = 1900e6; +constexpr double RHODIUM_TX_BAND6_MIN_FREQ = 3000e6; +constexpr double RHODIUM_TX_BAND7_MIN_FREQ = 4100e6; +} // namespace rhodium_radio_control_impl::rx_band rhodium_radio_control_impl::_map_freq_to_rx_band( const double freq) @@ -132,4 +132,3 @@ bool rhodium_radio_control_impl::_is_tx_lowband(const double freq) { return _map_freq_to_tx_band(freq) == tx_band::TX_BAND_0; } - diff --git a/host/lib/usrp/dboard/rhodium/rhodium_constants.hpp b/host/lib/usrp/dboard/rhodium/rhodium_constants.hpp index 69e6bf676..cc6a70dc3 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_constants.hpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_constants.hpp @@ -8,9 +8,9 @@ #define INCLUDED_LIBUHD_RHODIUM_CONSTANTS_HPP #include <array> -#include <vector> -#include <string> #include <cstddef> +#include <string> +#include <vector> static constexpr double RHODIUM_FREQ_COMPARE_EPSILON = 1e-5; @@ -26,37 +26,34 @@ static constexpr double RHODIUM_LO1_MIN_FREQ = 450e6; // Hz static constexpr double RHODIUM_LO1_MAX_FREQ = 6e9; // Hz static constexpr double RHODIUM_LO1_REF_FREQ = 122.88e6; // Hz -static constexpr double RHODIUM_LO_0_9_GHZ_LPF_THRESHOLD_FREQ = 0.975e9; // Hz +static constexpr double RHODIUM_LO_0_9_GHZ_LPF_THRESHOLD_FREQ = 0.975e9; // Hz static constexpr double RHODIUM_LO_2_25_GHZ_LPF_THRESHOLD_FREQ = 2.3e9; // Hz static constexpr double RHODIUM_LOWBAND_FREQ = 450e6; // Hz -static constexpr double RHODIUM_RX_IF_FREQ = 2.44e9; // Hz -static constexpr double RHODIUM_TX_IF_FREQ = 1.95e9; // Hz +static constexpr double RHODIUM_RX_IF_FREQ = 2.44e9; // Hz +static constexpr double RHODIUM_TX_IF_FREQ = 1.95e9; // Hz -static constexpr double RX_MIN_GAIN = 0.0; -static constexpr double RX_MAX_GAIN = 60.0; +static constexpr double RX_MIN_GAIN = 0.0; +static constexpr double RX_MAX_GAIN = 60.0; static constexpr double RX_GAIN_STEP = 1.0; -static constexpr double TX_MIN_GAIN = 0.0; -static constexpr double TX_MAX_GAIN = 60.0; +static constexpr double TX_MIN_GAIN = 0.0; +static constexpr double TX_MAX_GAIN = 60.0; static constexpr double TX_GAIN_STEP = 1.0; -static constexpr double LO_MIN_GAIN = 0.0; -static constexpr double LO_MAX_GAIN = 30.0; +static constexpr double LO_MIN_GAIN = 0.0; +static constexpr double LO_MAX_GAIN = 30.0; static constexpr double LO_GAIN_STEP = 1.0; -static constexpr double LO_MIN_POWER = 0.0; -static constexpr double LO_MAX_POWER = 63.0; +static constexpr double LO_MIN_POWER = 0.0; +static constexpr double LO_MAX_POWER = 63.0; static constexpr double LO_POWER_STEP = 1.0; static constexpr double RHODIUM_DEFAULT_BANDWIDTH = 250e6; // Hz static const std::vector<std::string> RHODIUM_RX_ANTENNAS = { - "TX/RX", "RX2", "CAL", "TERM" -}; + "TX/RX", "RX2", "CAL", "TERM"}; -static const std::vector<std::string> RHODIUM_TX_ANTENNAS = { - "TX/RX", "CAL", "TERM" -}; +static const std::vector<std::string> RHODIUM_TX_ANTENNAS = {"TX/RX", "CAL", "TERM"}; // These names are taken from radio_rhodium.xml static constexpr char SPUR_DODGING_PROP_NAME[] = "spur_dodging"; @@ -69,13 +66,13 @@ static constexpr char RHODIUM_DEFAULT_HB_SPUR_REDUCTION_MODE[] = "disabled"; static constexpr char RHODIUM_FPGPIO_BANK[] = "FP0"; static constexpr uint32_t RHODIUM_GPIO_MASK = 0x1F; -static constexpr uint32_t SW10_GPIO_MASK = 0x3; -static constexpr uint32_t LED_GPIO_MASK = 0x1C; +static constexpr uint32_t SW10_GPIO_MASK = 0x3; +static constexpr uint32_t LED_GPIO_MASK = 0x1C; -static constexpr uint32_t SW10_FROMTXLOWBAND = 0x0; +static constexpr uint32_t SW10_FROMTXLOWBAND = 0x0; static constexpr uint32_t SW10_FROMTXHIGHBAND = 0x1; -static constexpr uint32_t SW10_ISOLATION = 0x2; -static constexpr uint32_t SW10_TORX = 0x3; +static constexpr uint32_t SW10_ISOLATION = 0x2; +static constexpr uint32_t SW10_TORX = 0x3; static constexpr uint32_t LED_RX = 0x04; static constexpr uint32_t LED_RX2 = 0x08; @@ -95,12 +92,8 @@ static constexpr char RHODIUM_LO_POWER[] = "lo"; static constexpr char RHODIUM_FE_NAME[] = "Rhodium"; static constexpr int NUM_LO_OUTPUT_PORT_NAMES = 4; -static constexpr std::array<const char*, NUM_LO_OUTPUT_PORT_NAMES> LO_OUTPUT_PORT_NAMES = { - "LO_OUT_0", - "LO_OUT_1", - "LO_OUT_2", - "LO_OUT_3" -}; +static constexpr std::array<const char*, NUM_LO_OUTPUT_PORT_NAMES> LO_OUTPUT_PORT_NAMES = + {"LO_OUT_0", "LO_OUT_1", "LO_OUT_2", "LO_OUT_3"}; static constexpr size_t RHODIUM_NUM_CHANS = 1; diff --git a/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.cpp b/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.cpp index 8d294bc48..0617cbd94 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.cpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.cpp @@ -6,8 +6,8 @@ #include "rhodium_cpld_ctrl.hpp" #include "rhodium_constants.hpp" -#include <uhd/utils/math.hpp> #include <uhd/utils/log.hpp> +#include <uhd/utils/math.hpp> #include <boost/format.hpp> #include <chrono> @@ -15,115 +15,100 @@ using namespace uhd; using namespace uhd::math::fp_compare; namespace { - //! Address of the CPLD scratch register - constexpr uint8_t CPLD_REGS_SCRATCH = 0x05; - //! Address of the CPLD gain table selection register - constexpr uint8_t CPLD_REGS_GAIN_TBL_SEL = 0x06; - - constexpr uint32_t MAX_GAIN_INDEX = 60; - constexpr uint32_t MAX_LO_GAIN_INDEX = 30; - - //! RX Demodulator Adjustment thresholds - constexpr double RX_DEMOD_ADJ_1500OHM_THRESHOLD = 3e9; - constexpr double RX_DEMOD_ADJ_200OHM_THRESHOLD = 4.5e9; - - /* - Unlike other CPLD fields, gain control doesn't use a register and instead - commands are directly sent over SPI. The format of these 24-bit commands is - as follows. - 23:22 Table select (1 = RX, 2 = TX) - 21:16 Gain index - 15:14 Reserved - 13 Write enable for DSA1 - 12:7 Reserved - 6 Write enable for DSA2 - 5:0 Reserved - The CPLD replies with the current attenuation settings as follows, but we - ignore this reply in our code. - 23:13 Reserved - 12:7 Current attenuator setting for DSA1 - 6 Reserved - 5:0 Current attenuator setting for DSA2 - */ - //! Gain loader constants - constexpr size_t GAIN_CTRL_TABLE_FIELD = 22; - constexpr size_t GAIN_CTRL_INDEX_FIELD = 16; - constexpr size_t GAIN_CTRL_DSA1_FIELD = 13; - constexpr size_t GAIN_CTRL_DSA2_FIELD = 6; - - constexpr uint32_t GAIN_CTRL_TABLE_RX = 1; - constexpr uint32_t GAIN_CTRL_TABLE_TX = 2; - constexpr uint32_t GAIN_CTRL_DSA1_WRITE_ENABLE = 1; - constexpr uint32_t GAIN_CTRL_DSA2_WRITE_ENABLE = 1; - - /* - Similar to gain control, LO control doesn't use a register and instead - commands are directly sent over SPI. The format of these 24-bit commands is - as follows: - 23:22 Table select (Always 3 = LO) - 21:16 Attenuator setting - 15:14 Reserved - 13 Write enable for RX LO DSA - 12:7 Reserved - 6 Write enable for TX LO DSA - 5:0 Reserved - The CPLD replies with the current attenuator settings as follows, but we - ignore this reply in our code. - 23:13 Reserved - 12:7 Current attenuator setting for RX LO DSA - 6 Reserved - 5:0 Current attenuator setting for TX LO DSA - */ - //! LO Gain loader constants - constexpr size_t LO_GAIN_CTRL_TABLE_FIELD = 22; - constexpr size_t LO_GAIN_CTRL_INDEX_FIELD = 16; - constexpr size_t LO_GAIN_CTRL_RX_LO_FIELD = 13; - constexpr size_t LO_GAIN_CTRL_TX_LO_FIELD = 6; - - constexpr uint32_t LO_GAIN_CTRL_TABLE_LO = 3; - constexpr uint32_t LO_GAIN_CTRL_RX_LO_WRITE_ENABLE = 1; - constexpr uint32_t LO_GAIN_CTRL_RX_LO_WRITE_DISABLE = 0; - constexpr uint32_t LO_GAIN_CTRL_TX_LO_WRITE_ENABLE = 1; - constexpr uint32_t LO_GAIN_CTRL_TX_LO_WRITE_DISABLE = 0; -} - -rhodium_cpld_ctrl::rhodium_cpld_ctrl( - write_spi_t write_fn, - read_spi_t read_fn -) +//! Address of the CPLD scratch register +constexpr uint8_t CPLD_REGS_SCRATCH = 0x05; +//! Address of the CPLD gain table selection register +constexpr uint8_t CPLD_REGS_GAIN_TBL_SEL = 0x06; + +constexpr uint32_t MAX_GAIN_INDEX = 60; +constexpr uint32_t MAX_LO_GAIN_INDEX = 30; + +//! RX Demodulator Adjustment thresholds +constexpr double RX_DEMOD_ADJ_1500OHM_THRESHOLD = 3e9; +constexpr double RX_DEMOD_ADJ_200OHM_THRESHOLD = 4.5e9; + +/* +Unlike other CPLD fields, gain control doesn't use a register and instead +commands are directly sent over SPI. The format of these 24-bit commands is +as follows. + 23:22 Table select (1 = RX, 2 = TX) + 21:16 Gain index + 15:14 Reserved + 13 Write enable for DSA1 + 12:7 Reserved + 6 Write enable for DSA2 + 5:0 Reserved +The CPLD replies with the current attenuation settings as follows, but we +ignore this reply in our code. + 23:13 Reserved + 12:7 Current attenuator setting for DSA1 + 6 Reserved + 5:0 Current attenuator setting for DSA2 +*/ +//! Gain loader constants +constexpr size_t GAIN_CTRL_TABLE_FIELD = 22; +constexpr size_t GAIN_CTRL_INDEX_FIELD = 16; +constexpr size_t GAIN_CTRL_DSA1_FIELD = 13; +constexpr size_t GAIN_CTRL_DSA2_FIELD = 6; + +constexpr uint32_t GAIN_CTRL_TABLE_RX = 1; +constexpr uint32_t GAIN_CTRL_TABLE_TX = 2; +constexpr uint32_t GAIN_CTRL_DSA1_WRITE_ENABLE = 1; +constexpr uint32_t GAIN_CTRL_DSA2_WRITE_ENABLE = 1; + +/* +Similar to gain control, LO control doesn't use a register and instead +commands are directly sent over SPI. The format of these 24-bit commands is +as follows: + 23:22 Table select (Always 3 = LO) + 21:16 Attenuator setting + 15:14 Reserved + 13 Write enable for RX LO DSA + 12:7 Reserved + 6 Write enable for TX LO DSA + 5:0 Reserved +The CPLD replies with the current attenuator settings as follows, but we +ignore this reply in our code. + 23:13 Reserved + 12:7 Current attenuator setting for RX LO DSA + 6 Reserved + 5:0 Current attenuator setting for TX LO DSA +*/ +//! LO Gain loader constants +constexpr size_t LO_GAIN_CTRL_TABLE_FIELD = 22; +constexpr size_t LO_GAIN_CTRL_INDEX_FIELD = 16; +constexpr size_t LO_GAIN_CTRL_RX_LO_FIELD = 13; +constexpr size_t LO_GAIN_CTRL_TX_LO_FIELD = 6; + +constexpr uint32_t LO_GAIN_CTRL_TABLE_LO = 3; +constexpr uint32_t LO_GAIN_CTRL_RX_LO_WRITE_ENABLE = 1; +constexpr uint32_t LO_GAIN_CTRL_RX_LO_WRITE_DISABLE = 0; +constexpr uint32_t LO_GAIN_CTRL_TX_LO_WRITE_ENABLE = 1; +constexpr uint32_t LO_GAIN_CTRL_TX_LO_WRITE_DISABLE = 0; +} // namespace + +rhodium_cpld_ctrl::rhodium_cpld_ctrl(write_spi_t write_fn, read_spi_t read_fn) { - _write_reg_fn = [write_fn](const uint8_t addr, const uint32_t data){ + _write_reg_fn = [write_fn](const uint8_t addr, const uint32_t data) { UHD_LOG_TRACE("RH_CPLD", - str(boost::format("Writing to CPLD: 0x%02X -> 0x%04X") - % uint32_t(addr) % data)); - const uint32_t spi_transaction = 0 - | ((addr & 0x7F) << 17) - | data - ; - UHD_LOG_TRACE("RH_CPLD", - str(boost::format("SPI Transaction: 0x%04X") - % spi_transaction)); + str(boost::format("Writing to CPLD: 0x%02X -> 0x%04X") % uint32_t(addr) + % data)); + const uint32_t spi_transaction = 0 | ((addr & 0x7F) << 17) | data; + UHD_LOG_TRACE( + "RH_CPLD", str(boost::format("SPI Transaction: 0x%04X") % spi_transaction)); write_fn(spi_transaction); }; _write_raw_fn = [write_fn](const uint32_t data) { - UHD_LOG_TRACE("RH_CPLD", - str(boost::format("Writing to CPLD: 0x%06X") - % data)); - UHD_LOG_TRACE("RH_CPLD", - str(boost::format("SPI Transaction: 0x%06X") - % data)); + UHD_LOG_TRACE("RH_CPLD", str(boost::format("Writing to CPLD: 0x%06X") % data)); + UHD_LOG_TRACE("RH_CPLD", str(boost::format("SPI Transaction: 0x%06X") % data)); write_fn(data); }; - _read_reg_fn = [read_fn](const uint8_t addr){ + _read_reg_fn = [read_fn](const uint8_t addr) { UHD_LOG_TRACE("RH_CPLD", - str(boost::format("Reading from CPLD address 0x%02X") - % uint32_t(addr))); - const uint32_t spi_transaction = (1<<16) - | ((addr & 0x7F) << 17) - ; - UHD_LOG_TRACE("RH_CPLD", - str(boost::format("SPI Transaction: 0x%04X") - % spi_transaction)); + str(boost::format("Reading from CPLD address 0x%02X") % uint32_t(addr))); + const uint32_t spi_transaction = (1 << 16) | ((addr & 0x7F) << 17); + UHD_LOG_TRACE( + "RH_CPLD", str(boost::format("SPI Transaction: 0x%04X") % spi_transaction)); return read_fn(spi_transaction); }; @@ -162,26 +147,23 @@ uint16_t rhodium_cpld_ctrl::get_scratch() return get_reg(CPLD_REGS_SCRATCH); } -void rhodium_cpld_ctrl::set_tx_switches( - const tx_sw2_t tx_sw2, +void rhodium_cpld_ctrl::set_tx_switches(const tx_sw2_t tx_sw2, const tx_sw3_sw4_t tx_sw3_sw4, const tx_sw5_t tx_sw5, const tx_hb_lb_sel_t tx_hb_lb_sel, - const bool defer_commit -) { + const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", - "Configuring TX band selection switches."\ - " sw2=" << tx_sw2 << - " sw3_sw4=" << tx_sw3_sw4 << - " sw5=" << tx_sw5 << - " hb_lb_sel=" << tx_hb_lb_sel - ); + "Configuring TX band selection switches." + " sw2=" + << tx_sw2 << " sw3_sw4=" << tx_sw3_sw4 << " sw5=" << tx_sw5 + << " hb_lb_sel=" << tx_hb_lb_sel); std::lock_guard<std::mutex> l(_set_mutex); - _regs.tx_sw2 = rhodium_cpld_regs_t::tx_sw2_t(tx_sw2); - _regs.tx_sw3_sw4 = rhodium_cpld_regs_t::tx_sw3_sw4_t(tx_sw3_sw4); - _regs.tx_sw5 = rhodium_cpld_regs_t::tx_sw5_t(tx_sw5); + _regs.tx_sw2 = rhodium_cpld_regs_t::tx_sw2_t(tx_sw2); + _regs.tx_sw3_sw4 = rhodium_cpld_regs_t::tx_sw3_sw4_t(tx_sw3_sw4); + _regs.tx_sw5 = rhodium_cpld_regs_t::tx_sw5_t(tx_sw5); _regs.tx_hb_lb_sel = rhodium_cpld_regs_t::tx_hb_lb_sel_t(tx_hb_lb_sel); if (not defer_commit) { @@ -189,29 +171,25 @@ void rhodium_cpld_ctrl::set_tx_switches( } } -void rhodium_cpld_ctrl::set_rx_switches( - const rx_sw2_sw7_t rx_sw2_sw7, +void rhodium_cpld_ctrl::set_rx_switches(const rx_sw2_sw7_t rx_sw2_sw7, const rx_sw3_t rx_sw3, const rx_sw4_sw5_t rx_sw4_sw5, const rx_sw6_t rx_sw6, const rx_hb_lb_sel_t rx_hb_lb_sel, - const bool defer_commit -) { + const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", - "Configuring RX band selection switches."\ - " sw2_sw7=" << rx_sw2_sw7 << - " sw3=" << rx_sw3 << - " sw4_sw5=" << rx_sw4_sw5 << - " sw6=" << rx_sw6 << - " hb_lb_sel=" << rx_hb_lb_sel - ); + "Configuring RX band selection switches." + " sw2_sw7=" + << rx_sw2_sw7 << " sw3=" << rx_sw3 << " sw4_sw5=" << rx_sw4_sw5 + << " sw6=" << rx_sw6 << " hb_lb_sel=" << rx_hb_lb_sel); std::lock_guard<std::mutex> l(_set_mutex); - _regs.rx_sw2_sw7 = rhodium_cpld_regs_t::rx_sw2_sw7_t(rx_sw2_sw7); - _regs.rx_sw3 = rhodium_cpld_regs_t::rx_sw3_t(rx_sw3); - _regs.rx_sw4_sw5 = rhodium_cpld_regs_t::rx_sw4_sw5_t(rx_sw4_sw5); - _regs.rx_sw6 = rhodium_cpld_regs_t::rx_sw6_t(rx_sw6); + _regs.rx_sw2_sw7 = rhodium_cpld_regs_t::rx_sw2_sw7_t(rx_sw2_sw7); + _regs.rx_sw3 = rhodium_cpld_regs_t::rx_sw3_t(rx_sw3); + _regs.rx_sw4_sw5 = rhodium_cpld_regs_t::rx_sw4_sw5_t(rx_sw4_sw5); + _regs.rx_sw6 = rhodium_cpld_regs_t::rx_sw6_t(rx_sw6); _regs.rx_hb_lb_sel = rhodium_cpld_regs_t::rx_hb_lb_sel_t(rx_hb_lb_sel); if (not defer_commit) { @@ -220,19 +198,16 @@ void rhodium_cpld_ctrl::set_rx_switches( } void rhodium_cpld_ctrl::set_rx_input_switches( - const rx_sw1_t rx_sw1, - const cal_iso_sw_t cal_iso_sw, - const bool defer_commit -) { + const rx_sw1_t rx_sw1, const cal_iso_sw_t cal_iso_sw, const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", - "Configuring RX input selection switches."\ - " sw1=" << rx_sw1 << - " cal_iso=" << cal_iso_sw - ); + "Configuring RX input selection switches." + " sw1=" + << rx_sw1 << " cal_iso=" << cal_iso_sw); std::lock_guard<std::mutex> l(_set_mutex); - _regs.rx_sw1 = rhodium_cpld_regs_t::rx_sw1_t(rx_sw1); + _regs.rx_sw1 = rhodium_cpld_regs_t::rx_sw1_t(rx_sw1); _regs.cal_iso_sw = rhodium_cpld_regs_t::cal_iso_sw_t(cal_iso_sw); if (not defer_commit) { @@ -241,13 +216,12 @@ void rhodium_cpld_ctrl::set_rx_input_switches( } void rhodium_cpld_ctrl::set_tx_output_switches( - const tx_sw1_t tx_sw1, - const bool defer_commit -) { + const tx_sw1_t tx_sw1, const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", - "Configuring TX output selection switches."\ - " sw1=" << tx_sw1 - ); + "Configuring TX output selection switches." + " sw1=" + << tx_sw1); std::lock_guard<std::mutex> l(_set_mutex); @@ -259,9 +233,8 @@ void rhodium_cpld_ctrl::set_tx_output_switches( } void rhodium_cpld_ctrl::set_rx_lo_source( - const rx_lo_input_sel_t rx_lo_input_sel, - const bool defer_commit -) { + const rx_lo_input_sel_t rx_lo_input_sel, const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", "Setting RX LO source to " << rx_lo_input_sel); std::lock_guard<std::mutex> l(_set_mutex); @@ -273,9 +246,8 @@ void rhodium_cpld_ctrl::set_rx_lo_source( } void rhodium_cpld_ctrl::set_tx_lo_source( - const tx_lo_input_sel_t tx_lo_input_sel, - const bool defer_commit -) { + const tx_lo_input_sel_t tx_lo_input_sel, const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", "Setting TX LO source to " << tx_lo_input_sel); std::lock_guard<std::mutex> l(_set_mutex); @@ -286,29 +258,32 @@ void rhodium_cpld_ctrl::set_tx_lo_source( } } -void rhodium_cpld_ctrl::set_rx_lo_path( - const double freq, - const bool defer_commit -) { +void rhodium_cpld_ctrl::set_rx_lo_path(const double freq, const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", "Configuring RX LO filter and settings. freq=" << freq); std::lock_guard<std::mutex> l(_set_mutex); auto freq_compare = fp_compare_epsilon<double>(freq, RHODIUM_FREQ_COMPARE_EPSILON); if (freq_compare < RX_DEMOD_ADJ_1500OHM_THRESHOLD) { - _regs.rx_demod_adj = rhodium_cpld_regs_t::rx_demod_adj_t::RX_DEMOD_ADJ_RES_1500_OHM; + _regs.rx_demod_adj = + rhodium_cpld_regs_t::rx_demod_adj_t::RX_DEMOD_ADJ_RES_1500_OHM; } else if (freq_compare < RX_DEMOD_ADJ_200OHM_THRESHOLD) { - _regs.rx_demod_adj = rhodium_cpld_regs_t::rx_demod_adj_t::RX_DEMOD_ADJ_RES_200_OHM; + _regs.rx_demod_adj = + rhodium_cpld_regs_t::rx_demod_adj_t::RX_DEMOD_ADJ_RES_200_OHM; } else { _regs.rx_demod_adj = rhodium_cpld_regs_t::rx_demod_adj_t::RX_DEMOD_ADJ_RES_OPEN; } if (freq_compare < RHODIUM_LO_0_9_GHZ_LPF_THRESHOLD_FREQ) { - _regs.rx_lo_filter_sel = rhodium_cpld_regs_t::rx_lo_filter_sel_t::RX_LO_FILTER_SEL_0_9GHZ_LPF; + _regs.rx_lo_filter_sel = + rhodium_cpld_regs_t::rx_lo_filter_sel_t::RX_LO_FILTER_SEL_0_9GHZ_LPF; } else if (freq_compare < RHODIUM_LO_2_25_GHZ_LPF_THRESHOLD_FREQ) { - _regs.rx_lo_filter_sel = rhodium_cpld_regs_t::rx_lo_filter_sel_t::RX_LO_FILTER_SEL_2_25GHZ_LPF; + _regs.rx_lo_filter_sel = + rhodium_cpld_regs_t::rx_lo_filter_sel_t::RX_LO_FILTER_SEL_2_25GHZ_LPF; } else { - _regs.rx_lo_filter_sel = rhodium_cpld_regs_t::rx_lo_filter_sel_t::RX_LO_FILTER_SEL_5_85GHZ_LPF; + _regs.rx_lo_filter_sel = + rhodium_cpld_regs_t::rx_lo_filter_sel_t::RX_LO_FILTER_SEL_5_85GHZ_LPF; } if (not defer_commit) { @@ -316,21 +291,22 @@ void rhodium_cpld_ctrl::set_rx_lo_path( } } -void rhodium_cpld_ctrl::set_tx_lo_path( - const double freq, - const bool defer_commit -) { +void rhodium_cpld_ctrl::set_tx_lo_path(const double freq, const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", "Configuring TX LO filter and settings. freq=" << freq); std::lock_guard<std::mutex> l(_set_mutex); auto freq_compare = fp_compare_epsilon<double>(freq, RHODIUM_FREQ_COMPARE_EPSILON); if (freq_compare < RHODIUM_LO_0_9_GHZ_LPF_THRESHOLD_FREQ) { - _regs.tx_lo_filter_sel = rhodium_cpld_regs_t::tx_lo_filter_sel_t::TX_LO_FILTER_SEL_0_9GHZ_LPF; + _regs.tx_lo_filter_sel = + rhodium_cpld_regs_t::tx_lo_filter_sel_t::TX_LO_FILTER_SEL_0_9GHZ_LPF; } else if (freq_compare < RHODIUM_LO_2_25_GHZ_LPF_THRESHOLD_FREQ) { - _regs.tx_lo_filter_sel = rhodium_cpld_regs_t::tx_lo_filter_sel_t::TX_LO_FILTER_SEL_2_25GHZ_LPF; + _regs.tx_lo_filter_sel = + rhodium_cpld_regs_t::tx_lo_filter_sel_t::TX_LO_FILTER_SEL_2_25GHZ_LPF; } else { - _regs.tx_lo_filter_sel = rhodium_cpld_regs_t::tx_lo_filter_sel_t::TX_LO_FILTER_SEL_5_85GHZ_LPF; + _regs.tx_lo_filter_sel = + rhodium_cpld_regs_t::tx_lo_filter_sel_t::TX_LO_FILTER_SEL_5_85GHZ_LPF; } if (not defer_commit) { @@ -338,43 +314,35 @@ void rhodium_cpld_ctrl::set_tx_lo_path( } } -void rhodium_cpld_ctrl::set_gain_index( - const uint32_t index, +void rhodium_cpld_ctrl::set_gain_index(const uint32_t index, const gain_band_t band, const uhd::direction_t dir, - const bool defer_commit -) { + const bool defer_commit) +{ UHD_ASSERT_THROW(index <= MAX_GAIN_INDEX); UHD_ASSERT_THROW(dir == RX_DIRECTION or dir == TX_DIRECTION); - if (band == HIGH) - { - if (dir == RX_DIRECTION) - { + if (band == HIGH) { + if (dir == RX_DIRECTION) { _regs.rx_gain_tbl_sel = rhodium_cpld_regs_t::RX_GAIN_TBL_SEL_HIGHBAND; - } - else { + } else { _regs.tx_gain_tbl_sel = rhodium_cpld_regs_t::TX_GAIN_TBL_SEL_HIGHBAND; } } else { - if (dir == RX_DIRECTION) - { + if (dir == RX_DIRECTION) { _regs.rx_gain_tbl_sel = rhodium_cpld_regs_t::RX_GAIN_TBL_SEL_LOWBAND; - } - else { + } else { _regs.tx_gain_tbl_sel = rhodium_cpld_regs_t::TX_GAIN_TBL_SEL_LOWBAND; } } - const uint8_t table_id = (dir == RX_DIRECTION) ? - GAIN_CTRL_TABLE_RX : - GAIN_CTRL_TABLE_TX; + const uint8_t table_id = (dir == RX_DIRECTION) ? GAIN_CTRL_TABLE_RX + : GAIN_CTRL_TABLE_TX; - const uint32_t cmd = - (table_id << GAIN_CTRL_TABLE_FIELD) | - (index << GAIN_CTRL_INDEX_FIELD) | - (GAIN_CTRL_DSA1_WRITE_ENABLE << GAIN_CTRL_DSA1_FIELD) | - (GAIN_CTRL_DSA2_WRITE_ENABLE << GAIN_CTRL_DSA2_FIELD); + const uint32_t cmd = (table_id << GAIN_CTRL_TABLE_FIELD) + | (index << GAIN_CTRL_INDEX_FIELD) + | (GAIN_CTRL_DSA1_WRITE_ENABLE << GAIN_CTRL_DSA1_FIELD) + | (GAIN_CTRL_DSA2_WRITE_ENABLE << GAIN_CTRL_DSA2_FIELD); std::lock_guard<std::mutex> l(_set_mutex); _gain_queue.emplace_back(cmd); @@ -385,28 +353,25 @@ void rhodium_cpld_ctrl::set_gain_index( } void rhodium_cpld_ctrl::set_lo_gain( - const uint32_t index, - const uhd::direction_t dir, - const bool defer_commit -) { + const uint32_t index, const uhd::direction_t dir, const bool defer_commit) +{ UHD_ASSERT_THROW(index <= MAX_LO_GAIN_INDEX); // The DSA has 0-30 dB of attenuation in 1 dB steps // This index directly controls the attenuation value of the LO DSA, // so reverse the gain value to write the value const uint32_t attenuation = MAX_LO_GAIN_INDEX - index; - const uint8_t set_rx = (dir == RX_DIRECTION or dir == DX_DIRECTION) ? - LO_GAIN_CTRL_RX_LO_WRITE_ENABLE : - LO_GAIN_CTRL_RX_LO_WRITE_DISABLE; - const uint8_t set_tx = (dir == TX_DIRECTION or dir == DX_DIRECTION) ? - LO_GAIN_CTRL_TX_LO_WRITE_ENABLE : - LO_GAIN_CTRL_TX_LO_WRITE_DISABLE; - - const uint32_t cmd = - (LO_GAIN_CTRL_TABLE_LO << LO_GAIN_CTRL_TABLE_FIELD) | - (attenuation << LO_GAIN_CTRL_INDEX_FIELD) | - (set_rx << LO_GAIN_CTRL_RX_LO_FIELD) | - (set_tx << LO_GAIN_CTRL_TX_LO_FIELD); + const uint8_t set_rx = (dir == RX_DIRECTION or dir == DX_DIRECTION) + ? LO_GAIN_CTRL_RX_LO_WRITE_ENABLE + : LO_GAIN_CTRL_RX_LO_WRITE_DISABLE; + const uint8_t set_tx = (dir == TX_DIRECTION or dir == DX_DIRECTION) + ? LO_GAIN_CTRL_TX_LO_WRITE_ENABLE + : LO_GAIN_CTRL_TX_LO_WRITE_DISABLE; + + const uint32_t cmd = (LO_GAIN_CTRL_TABLE_LO << LO_GAIN_CTRL_TABLE_FIELD) + | (attenuation << LO_GAIN_CTRL_INDEX_FIELD) + | (set_rx << LO_GAIN_CTRL_RX_LO_FIELD) + | (set_tx << LO_GAIN_CTRL_TX_LO_FIELD); std::lock_guard<std::mutex> l(_set_mutex); _gain_queue.emplace_back(cmd); @@ -431,9 +396,7 @@ void rhodium_cpld_ctrl::_loopback_test() if (actual != random_number) { UHD_LOGGER_ERROR("RH_CPLD") << "CPLD scratch loopback failed! " - << boost::format("Expected: 0x%04X Got: 0x%04X") - % random_number % actual - ; + << boost::format("Expected: 0x%04X Got: 0x%04X") % random_number % actual; throw uhd::runtime_error("CPLD scratch loopback failed!"); } UHD_LOG_TRACE("RH_CPLD", "CPLD scratch loopback test passed!"); @@ -442,33 +405,27 @@ void rhodium_cpld_ctrl::_loopback_test() void rhodium_cpld_ctrl::commit(const bool save_all) { UHD_LOGGER_TRACE("RH_CPLD") - << "Storing register cache " - << (save_all ? "completely" : "selectively") - << " to CPLD via SPI..." - ; - auto changed_addrs = save_all ? - _regs.get_all_addrs() : - _regs.get_changed_addrs<size_t>(); - for (const auto addr: changed_addrs) { + << "Storing register cache " << (save_all ? "completely" : "selectively") + << " to CPLD via SPI..."; + auto changed_addrs = save_all ? _regs.get_all_addrs() + : _regs.get_changed_addrs<size_t>(); + for (const auto addr : changed_addrs) { _write_reg_fn(addr, _regs.get_reg(addr)); } _regs.save_state(); UHD_LOG_TRACE("RH_CPLD", - "Storing cache complete: " \ - "Updated " << changed_addrs.size() << " registers.") - ; + "Storing cache complete: " + "Updated " + << changed_addrs.size() << " registers."); - UHD_LOGGER_TRACE("RH_CPLD") - << "Writing queued gain commands " - << "to CPLD via SPI..." - ; + UHD_LOGGER_TRACE("RH_CPLD") << "Writing queued gain commands " + << "to CPLD via SPI..."; for (const auto cmd : _gain_queue) { _write_raw_fn(cmd); } UHD_LOG_TRACE("RH_CPLD", - "Writing queued gain commands complete: " \ - "Wrote " << _gain_queue.size() << " commands.") - ; + "Writing queued gain commands complete: " + "Wrote " + << _gain_queue.size() << " commands."); _gain_queue.clear(); } - diff --git a/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.hpp b/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.hpp index d60ae6e66..18b0b8c78 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.hpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.hpp @@ -38,14 +38,14 @@ public: }; enum tx_sw1_t { - TX_SW1_TOLOWBAND = 0, - TX_SW1_TOSWITCH2 = 1, + TX_SW1_TOLOWBAND = 0, + TX_SW1_TOSWITCH2 = 1, TX_SW1_TOCALLOOPBACK = 2, - TX_SW1_ISOLATION = 3 + TX_SW1_ISOLATION = 3 }; enum tx_sw2_t { - TX_SW2_FROMSWITCH3 = 0, + TX_SW2_FROMSWITCH3 = 0, TX_SW2_FROMTXFILTERLP6000MHZ = 1, TX_SW2_FROMTXFILTERLP4100MHZ = 2, TX_SW2_FROMTXFILTERLP3000MHZ = 3 @@ -62,23 +62,23 @@ public: TX_SW5_TOTXFILTERLP3000MHZ = 0, TX_SW5_TOTXFILTERLP4100MHZ = 1, TX_SW5_TOTXFILTERLP6000MHZ = 2, - TX_SW5_TOSWITCH4 = 3 + TX_SW5_TOSWITCH4 = 3 }; enum rx_sw1_t { RX_SW1_FROMCALLOOPBACK = 0, - RX_SW1_FROMRX2INPUT = 1, - RX_SW1_ISOLATION = 2, - RX_SW1_FROMTXRXINPUT = 3 + RX_SW1_FROMRX2INPUT = 1, + RX_SW1_ISOLATION = 2, + RX_SW1_FROMTXRXINPUT = 3 }; enum rx_sw2_sw7_t { - RX_SW2_SW7_LOWBANDFILTERBANK = 0, + RX_SW2_SW7_LOWBANDFILTERBANK = 0, RX_SW2_SW7_HIGHBANDFILTERBANK = 1 }; enum rx_sw3_t { - RX_SW3_TOSWITCH4 = 0, + RX_SW3_TOSWITCH4 = 0, RX_SW3_TOFILTER4500X6000MHZ = 1, RX_SW3_TOFILTER3000X4500MHZ = 2, RX_SW3_TOFILTER2050X3000MHZ = 3 @@ -95,52 +95,33 @@ public: RX_SW6_FROMFILTER2050X3000MHZ = 0, RX_SW6_FROMFILTER3000X4500MHZ = 1, RX_SW6_FROMFILTER4500X6000MHZ = 2, - RX_SW6_FROMSWITCH5 = 3, + RX_SW6_FROMSWITCH5 = 3, }; - enum cal_iso_sw_t { - CAL_ISO_ISOLATION = 0, - CAL_ISO_CALLOOPBACK = 1 - }; + enum cal_iso_sw_t { CAL_ISO_ISOLATION = 0, CAL_ISO_CALLOOPBACK = 1 }; - enum tx_hb_lb_sel_t { - TX_HB_LB_SEL_LOWBAND = 0, - TX_HB_LB_SEL_HIGHBAND = 1 - }; + enum tx_hb_lb_sel_t { TX_HB_LB_SEL_LOWBAND = 0, TX_HB_LB_SEL_HIGHBAND = 1 }; - enum tx_lo_input_sel_t { - TX_LO_INPUT_SEL_INTERNAL = 0, - TX_LO_INPUT_SEL_EXTERNAL = 1 - }; + enum tx_lo_input_sel_t { TX_LO_INPUT_SEL_INTERNAL = 0, TX_LO_INPUT_SEL_EXTERNAL = 1 }; - enum rx_hb_lb_sel_t { - RX_HB_LB_SEL_LOWBAND = 0, - RX_HB_LB_SEL_HIGHBAND = 1 - }; + enum rx_hb_lb_sel_t { RX_HB_LB_SEL_LOWBAND = 0, RX_HB_LB_SEL_HIGHBAND = 1 }; - enum rx_lo_input_sel_t { - RX_LO_INPUT_SEL_INTERNAL = 1, - RX_LO_INPUT_SEL_EXTERNAL = 0 - }; + enum rx_lo_input_sel_t { RX_LO_INPUT_SEL_INTERNAL = 1, RX_LO_INPUT_SEL_EXTERNAL = 0 }; - enum rx_demod_adj { - RX_DEMOD_OPEN = 0, - RX_DEMOD_200OHM = 1, - RX_DEMOD_1500OHM = 2 - }; + enum rx_demod_adj { RX_DEMOD_OPEN = 0, RX_DEMOD_200OHM = 1, RX_DEMOD_1500OHM = 2 }; enum tx_lo_filter_sel_t { - TX_LO_FILTER_SEL_0_9GHZ_LPF = 0, + TX_LO_FILTER_SEL_0_9GHZ_LPF = 0, TX_LO_FILTER_SEL_5_85GHZ_LPF = 1, TX_LO_FILTER_SEL_2_25GHZ_LPF = 2, - TX_LO_FILTER_SEL_ISOLATION = 3 + TX_LO_FILTER_SEL_ISOLATION = 3 }; enum rx_lo_filter_sel_t { - RX_LO_FILTER_SEL_0_9GHZ_LPF = 0, + RX_LO_FILTER_SEL_0_9GHZ_LPF = 0, RX_LO_FILTER_SEL_5_85GHZ_LPF = 1, RX_LO_FILTER_SEL_2_25GHZ_LPF = 2, - RX_LO_FILTER_SEL_ISOLATION = 3 + RX_LO_FILTER_SEL_ISOLATION = 3 }; /*! Constructor. @@ -148,10 +129,7 @@ public: * \param write_spi_fn SPI write function * \param read_spi_fn SPI read function */ - rhodium_cpld_ctrl( - write_spi_t write_spi_fn, - read_spi_t read_spi_fn - ); + rhodium_cpld_ctrl(write_spi_t write_spi_fn, read_spi_t read_spi_fn); /************************************************************************** * API @@ -187,13 +165,11 @@ public: * \param tx_hb_lb_sel Power on the highband or lowband amplifier * \param tx_lo_filter_sel Select LPF filter for LO */ - void set_tx_switches( - const tx_sw2_t tx_sw2, + void set_tx_switches(const tx_sw2_t tx_sw2, const tx_sw3_sw4_t tx_sw3_sw4, const tx_sw5_t tx_sw5, const tx_hb_lb_sel_t tx_hb_lb_sel, - const bool defer_commit = false - ); + const bool defer_commit = false); /*! Frequency-related settings, receive side * @@ -204,14 +180,12 @@ public: * \param rx_hb_lb_sel Power on the highband or lowband amplifier * \param rx_lo_filter_sel Select LPF filter for LO */ - void set_rx_switches( - const rx_sw2_sw7_t rx_sw2_sw7, + void set_rx_switches(const rx_sw2_sw7_t rx_sw2_sw7, const rx_sw3_t rx_sw3, const rx_sw4_sw5_t rx_sw4_sw5, const rx_sw6_t rx_sw6, const rx_hb_lb_sel_t rx_hb_lb_sel, - const bool defer_commit = false - ); + const bool defer_commit = false); /*! Input switches for RX side * @@ -220,91 +194,72 @@ public: * \param rx_sw1 Input selection of RX path * \param cal_iso_sw Terminates the calibration loopback path */ - void set_rx_input_switches( - const rx_sw1_t rx_sw1, + void set_rx_input_switches(const rx_sw1_t rx_sw1, const cal_iso_sw_t cal_iso_sw, - const bool defer_commit = false - ); - - /*! Output switches for TX side - * - * Note: These are not frequency dependent. - * - * \param tx_sw1 Output selection of TX path - */ - void set_tx_output_switches( - const tx_sw1_t tx_sw1, - const bool defer_commit = false - ); - - /*! Input switch for RX LO - * - * \param rx_lo_input_sel Selects RX LO source - */ + const bool defer_commit = false); + + /*! Output switches for TX side + * + * Note: These are not frequency dependent. + * + * \param tx_sw1 Output selection of TX path + */ + void set_tx_output_switches(const tx_sw1_t tx_sw1, const bool defer_commit = false); + + /*! Input switch for RX LO + * + * \param rx_lo_input_sel Selects RX LO source + */ void set_rx_lo_source( - const rx_lo_input_sel_t rx_lo_input_sel, - const bool defer_commit = false - ); - - /*! Input switch for TX LO - * - * \param tx_lo_input_sel Selects TX LO source - */ + const rx_lo_input_sel_t rx_lo_input_sel, const bool defer_commit = false); + + /*! Input switch for TX LO + * + * \param tx_lo_input_sel Selects TX LO source + */ void set_tx_lo_source( - const tx_lo_input_sel_t tx_lo_input_sel, - const bool defer_commit = false - ); - - /*! Configure RX LO filter, synth, and mixer settings - * - * \param freq RX LO Frequency - */ - void set_rx_lo_path( - const double freq, - const bool defer_commit = false - ); - - /*! Configure TX LO filter, synth, and mixer settings - * - * \param freq TX LO Frequency - */ - void set_tx_lo_path( - const double freq, - const bool defer_commit = false - ); - - - /*! Gain index setting for the RF frontend - * - * Sets the gain index to one of the predefined values that have been - * loaded into the CPLD by gain table loader in MPM. - * - * \param index Index of the gain table entry to apply (0-60) - * \param band Selects which table to use (lowband or highband) - * \param dir Selects which RF frontend to apply to (RX or TX) - */ - void set_gain_index( - const uint32_t index, + const tx_lo_input_sel_t tx_lo_input_sel, const bool defer_commit = false); + + /*! Configure RX LO filter, synth, and mixer settings + * + * \param freq RX LO Frequency + */ + void set_rx_lo_path(const double freq, const bool defer_commit = false); + + /*! Configure TX LO filter, synth, and mixer settings + * + * \param freq TX LO Frequency + */ + void set_tx_lo_path(const double freq, const bool defer_commit = false); + + + /*! Gain index setting for the RF frontend + * + * Sets the gain index to one of the predefined values that have been + * loaded into the CPLD by gain table loader in MPM. + * + * \param index Index of the gain table entry to apply (0-60) + * \param band Selects which table to use (lowband or highband) + * \param dir Selects which RF frontend to apply to (RX or TX) + */ + void set_gain_index(const uint32_t index, const gain_band_t band, const uhd::direction_t dir, - const bool defer_commit = false - ); - - /*! Gain setting for LO1 - * - * Sets the attenuation of the RX LO1 DSA or TX LO1 DSA. - * - * Note: This function uses gain as a parameter, although it is - * setting an attenuation. - * - * \param index Gain value to apply (0-30) - * \param dir Selects which LO to apply to (RX, TX, or DX) - */ - void set_lo_gain( - const uint32_t index, + const bool defer_commit = false); + + /*! Gain setting for LO1 + * + * Sets the attenuation of the RX LO1 DSA or TX LO1 DSA. + * + * Note: This function uses gain as a parameter, although it is + * setting an attenuation. + * + * \param index Gain value to apply (0-30) + * \param dir Selects which LO to apply to (RX, TX, or DX) + */ + void set_lo_gain(const uint32_t index, const uhd::direction_t dir, - const bool defer_commit = false - ); + const bool defer_commit = false); private: //! Write function: Take address / data pair, craft SPI transaction diff --git a/host/lib/usrp/dboard/rhodium/rhodium_radio_control.cpp b/host/lib/usrp/dboard/rhodium/rhodium_radio_control.cpp index 54c6333bc..f8ec47c18 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_radio_control.cpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_radio_control.cpp @@ -18,9 +18,9 @@ #include <uhdlib/utils/narrow.hpp> #include <boost/algorithm/string.hpp> #include <boost/format.hpp> -#include <memory> #include <cmath> #include <cstdlib> +#include <memory> #include <sstream> using namespace uhd; @@ -29,16 +29,16 @@ using namespace uhd::rfnoc; using namespace uhd::math::fp_compare; namespace { - constexpr char RX_FE_CONNECTION_LOWBAND[] = "QI"; - constexpr char RX_FE_CONNECTION_HIGHBAND[] = "IQ"; - constexpr char TX_FE_CONNECTION_LOWBAND[] = "QI"; - constexpr char TX_FE_CONNECTION_HIGHBAND[] = "IQ"; +constexpr char RX_FE_CONNECTION_LOWBAND[] = "QI"; +constexpr char RX_FE_CONNECTION_HIGHBAND[] = "IQ"; +constexpr char TX_FE_CONNECTION_LOWBAND[] = "QI"; +constexpr char TX_FE_CONNECTION_HIGHBAND[] = "IQ"; - constexpr double DEFAULT_IDENTIFY_DURATION = 5.0; // seconds +constexpr double DEFAULT_IDENTIFY_DURATION = 5.0; // seconds - constexpr uint64_t SET_RATE_RPC_TIMEOUT_MS = 10000; +constexpr uint64_t SET_RATE_RPC_TIMEOUT_MS = 10000; -} +} // namespace /****************************************************************************** @@ -51,8 +51,7 @@ rhodium_radio_control_impl::rhodium_radio_control_impl(make_args_ptr make_args) UHD_ASSERT_THROW(get_block_id().get_block_count() < 2); const char radio_slot_name[] = {'A', 'B'}; _radio_slot = radio_slot_name[get_block_id().get_block_count()]; - _rpc_prefix = - (_radio_slot == "A") ? "db_0_" : "db_1_"; + _rpc_prefix = (_radio_slot == "A") ? "db_0_" : "db_1_"; RFNOC_LOG_TRACE("Radio slot: " << _radio_slot); UHD_ASSERT_THROW(get_num_input_ports() == RHODIUM_NUM_CHANS); UHD_ASSERT_THROW(get_num_output_ports() == RHODIUM_NUM_CHANS); @@ -207,14 +206,12 @@ double rhodium_radio_control_impl::set_tx_frequency(const double freq, const siz const bool is_highband = !_is_tx_lowband(coerced_target_freq); - const double target_lo_freq = is_highband ? - coerced_target_freq : _get_lowband_lo_freq() - coerced_target_freq; - const double actual_lo_freq = - set_tx_lo_freq(target_lo_freq, RHODIUM_LO1, chan); - const double coerced_freq = is_highband ? - actual_lo_freq : _get_lowband_lo_freq() - actual_lo_freq; - const auto conn = is_highband ? - TX_FE_CONNECTION_HIGHBAND : TX_FE_CONNECTION_LOWBAND; + const double target_lo_freq = + is_highband ? coerced_target_freq : _get_lowband_lo_freq() - coerced_target_freq; + const double actual_lo_freq = set_tx_lo_freq(target_lo_freq, RHODIUM_LO1, chan); + const double coerced_freq = is_highband ? actual_lo_freq + : _get_lowband_lo_freq() - actual_lo_freq; + const auto conn = is_highband ? TX_FE_CONNECTION_HIGHBAND : TX_FE_CONNECTION_LOWBAND; // update the cached frequency value now so calls to set gain and update // switches will read the new frequency @@ -224,7 +221,8 @@ double rhodium_radio_control_impl::set_tx_frequency(const double freq, const siz set_tx_gain(radio_control_impl::get_tx_gain(chan), 0); if (_get_highband_spur_reduction_enabled(TX_DIRECTION)) { - if (_get_timed_command_enabled() and _is_tx_lowband(old_freq) != not is_highband) { + if (_get_timed_command_enabled() + and _is_tx_lowband(old_freq) != not is_highband) { RFNOC_LOG_WARNING( "Timed tuning commands that transition between lowband and highband, 450 " "MHz, do not function correctly when highband_spur_reduction is enabled! " @@ -260,14 +258,12 @@ double rhodium_radio_control_impl::set_rx_frequency(const double freq, const siz const bool is_highband = !_is_rx_lowband(coerced_target_freq); - const double target_lo_freq = is_highband ? - coerced_target_freq : _get_lowband_lo_freq() - coerced_target_freq; - const double actual_lo_freq = - set_rx_lo_freq(target_lo_freq, RHODIUM_LO1, chan); - const double coerced_freq = is_highband ? - actual_lo_freq : _get_lowband_lo_freq() - actual_lo_freq; - const auto conn = is_highband ? - RX_FE_CONNECTION_HIGHBAND : RX_FE_CONNECTION_LOWBAND; + const double target_lo_freq = + is_highband ? coerced_target_freq : _get_lowband_lo_freq() - coerced_target_freq; + const double actual_lo_freq = set_rx_lo_freq(target_lo_freq, RHODIUM_LO1, chan); + const double coerced_freq = is_highband ? actual_lo_freq + : _get_lowband_lo_freq() - actual_lo_freq; + const auto conn = is_highband ? RX_FE_CONNECTION_HIGHBAND : RX_FE_CONNECTION_LOWBAND; // update the cached frequency value now so calls to set gain and update // switches will read the new frequency @@ -277,7 +273,8 @@ double rhodium_radio_control_impl::set_rx_frequency(const double freq, const siz set_rx_gain(radio_control_impl::get_rx_gain(chan), 0); if (_get_highband_spur_reduction_enabled(RX_DIRECTION)) { - if (_get_timed_command_enabled() and _is_rx_lowband(old_freq) != not is_highband) { + if (_get_timed_command_enabled() + and _is_rx_lowband(old_freq) != not is_highband) { RFNOC_LOG_WARNING( "Timed tuning commands that transition between lowband and highband, 450 " "MHz, do not function correctly when highband_spur_reduction is enabled! " @@ -313,17 +310,17 @@ double rhodium_radio_control_impl::set_tx_gain(const double gain, const size_t c RFNOC_LOG_TRACE("set_tx_gain(gain=" << gain << ", chan=" << chan << ")"); UHD_ASSERT_THROW(chan == 0); - auto freq = this->get_tx_frequency(chan); + auto freq = this->get_tx_frequency(chan); auto index = get_tx_gain_range(chan).clip(gain); - auto old_band = _is_tx_lowband(_tx_frequency_at_last_gain_write) ? - rhodium_cpld_ctrl::gain_band_t::LOW : - rhodium_cpld_ctrl::gain_band_t::HIGH; - auto new_band = _is_tx_lowband(freq) ? - rhodium_cpld_ctrl::gain_band_t::LOW : - rhodium_cpld_ctrl::gain_band_t::HIGH; + auto old_band = _is_tx_lowband(_tx_frequency_at_last_gain_write) + ? rhodium_cpld_ctrl::gain_band_t::LOW + : rhodium_cpld_ctrl::gain_band_t::HIGH; + auto new_band = _is_tx_lowband(freq) ? rhodium_cpld_ctrl::gain_band_t::LOW + : rhodium_cpld_ctrl::gain_band_t::HIGH; - // The CPLD requires a rewrite of the gain control command on a change of lowband or highband + // The CPLD requires a rewrite of the gain control command on a change of lowband or + // highband if (radio_control_impl::get_tx_gain(chan) != index or old_band != new_band) { RFNOC_LOG_TRACE("Writing new TX gain index: " << index); _cpld->set_gain_index(index, new_band, TX_DIRECTION); @@ -342,17 +339,17 @@ double rhodium_radio_control_impl::set_rx_gain(const double gain, const size_t c RFNOC_LOG_TRACE("set_rx_gain(gain=" << gain << ", chan=" << chan << ")"); UHD_ASSERT_THROW(chan == 0); - auto freq = this->get_rx_frequency(chan); + auto freq = this->get_rx_frequency(chan); auto index = get_rx_gain_range(chan).clip(gain); - auto old_band = _is_rx_lowband(_rx_frequency_at_last_gain_write) ? - rhodium_cpld_ctrl::gain_band_t::LOW : - rhodium_cpld_ctrl::gain_band_t::HIGH; - auto new_band = _is_rx_lowband(freq) ? - rhodium_cpld_ctrl::gain_band_t::LOW : - rhodium_cpld_ctrl::gain_band_t::HIGH; + auto old_band = _is_rx_lowband(_rx_frequency_at_last_gain_write) + ? rhodium_cpld_ctrl::gain_band_t::LOW + : rhodium_cpld_ctrl::gain_band_t::HIGH; + auto new_band = _is_rx_lowband(freq) ? rhodium_cpld_ctrl::gain_band_t::LOW + : rhodium_cpld_ctrl::gain_band_t::HIGH; - // The CPLD requires a rewrite of the gain control command on a change of lowband or highband + // The CPLD requires a rewrite of the gain control command on a change of lowband or + // highband if (radio_control_impl::get_rx_gain(chan) != index or old_band != new_band) { RFNOC_LOG_TRACE("Writing new RX gain index: " << index); _cpld->set_gain_index(index, new_band, RX_DIRECTION); @@ -398,13 +395,13 @@ void rhodium_radio_control_impl::_update_atr( const auto rx_ant = (dir == RX_DIRECTION) ? ant : get_rx_antenna(0); const auto tx_ant = (dir == TX_DIRECTION) ? ant : get_tx_antenna(0); - const auto sw10_tx = _is_tx_lowband(get_tx_frequency(0)) ? - SW10_FROMTXLOWBAND : SW10_FROMTXHIGHBAND; + const auto sw10_tx = _is_tx_lowband(get_tx_frequency(0)) ? SW10_FROMTXLOWBAND + : SW10_FROMTXHIGHBAND; const uint32_t atr_idle = SW10_ISOLATION; - const uint32_t atr_rx = [rx_ant]{ + const uint32_t atr_rx = [rx_ant] { if (rx_ant == "TX/RX") { return SW10_TORX | LED_RX; } else if (rx_ant == "RX2") { @@ -414,8 +411,7 @@ void rhodium_radio_control_impl::_update_atr( } }(); - const uint32_t atr_tx = (tx_ant == "TX/RX") ? - (sw10_tx | LED_TX) : SW10_ISOLATION; + const uint32_t atr_tx = (tx_ant == "TX/RX") ? (sw10_tx | LED_TX) : SW10_ISOLATION; const uint32_t atr_dx = [tx_ant, rx_ant, sw10_tx] { uint32_t sw10_return; diff --git a/host/lib/usrp/dboard/rhodium/rhodium_radio_control.hpp b/host/lib/usrp/dboard/rhodium/rhodium_radio_control.hpp index 8cee33f17..4d2bc38ad 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_radio_control.hpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_radio_control.hpp @@ -71,8 +71,8 @@ public: double set_rate(double rate); // Setters - void set_tx_antenna(const std::string &ant, const size_t chan); - void set_rx_antenna(const std::string &ant, const size_t chan); + void set_tx_antenna(const std::string& ant, const size_t chan); + void set_rx_antenna(const std::string& ant, const size_t chan); double set_tx_frequency(const double freq, const size_t chan); double set_rx_frequency(const double freq, const size_t chan); void set_tx_tune_args(const uhd::device_addr_t&, const size_t chan); @@ -163,8 +163,10 @@ public: * ??? calls ***********************************************************************/ // LO Distribution Control - void set_tx_lo_output_enabled(const bool enabled, const std::string& port_name, const size_t chan); - void set_rx_lo_output_enabled(const bool enabled, const std::string& port_name, const size_t chan); + void set_tx_lo_output_enabled( + const bool enabled, const std::string& port_name, const size_t chan); + void set_rx_lo_output_enabled( + const bool enabled, const std::string& port_name, const size_t chan); bool get_tx_lo_output_enabled(const std::string& port_name, const size_t chan); bool get_rx_lo_output_enabled(const std::string& port_name, const size_t chan); @@ -172,27 +174,29 @@ public: //! Set the external gain for a TX LO // Out of range values will be coerced - double set_tx_lo_gain(const double gain, const std::string &name, const size_t chan); + double set_tx_lo_gain(const double gain, const std::string& name, const size_t chan); //! Set the external gain for an RX LO // Out of range values will be coerced - double set_rx_lo_gain(const double gain, const std::string &name, const size_t chan); + double set_rx_lo_gain(const double gain, const std::string& name, const size_t chan); - double get_tx_lo_gain(const std::string &name, const size_t chan); - double get_rx_lo_gain(const std::string &name, const size_t chan); + double get_tx_lo_gain(const std::string& name, const size_t chan); + double get_rx_lo_gain(const std::string& name, const size_t chan); // LO Output Power Control //! Set the output power setting of a TX LO // Out of range values will be coerced - double set_tx_lo_power(const double power, const std::string &name, const size_t chan); + double set_tx_lo_power( + const double power, const std::string& name, const size_t chan); //! Set the output power setting of a RX LO // Out of range values will be coerced - double set_rx_lo_power(const double power, const std::string &name, const size_t chan); + double set_rx_lo_power( + const double power, const std::string& name, const size_t chan); - double get_tx_lo_power(const std::string &name, const size_t chan); - double get_rx_lo_power(const std::string &name, const size_t chan); + double get_tx_lo_power(const std::string& name, const size_t chan); + double get_rx_lo_power(const std::string& name, const size_t chan); private: @@ -239,42 +243,28 @@ private: void _init_mpm_sensors(const direction_t dir, const size_t chan_idx); //! Get the frequency range for an LO - freq_range_t _get_lo_freq_range(const std::string &name) const; + freq_range_t _get_lo_freq_range(const std::string& name) const; //! Get the current lowband intermediate frequency double _get_lowband_lo_freq() const; //! Configure LO1's export - void _set_lo1_export_enabled( - const bool enabled, - const direction_t dir - ); + void _set_lo1_export_enabled(const bool enabled, const direction_t dir); //! Validate that port_name is valid, and that LO distribution functions // can be called in this instance void _validate_output_port( - const std::string& port_name, - const std::string& function_name - ); + const std::string& port_name, const std::string& function_name); //! Configure LO Distribution board's termination switches void _set_lo_output_enabled( - const bool enabled, - const std::string& port_name, - const direction_t dir - ); + const bool enabled, const std::string& port_name, const direction_t dir); - bool _get_lo_output_enabled( - const std::string& port_name, - const direction_t dir - ); + bool _get_lo_output_enabled(const std::string& port_name, const direction_t dir); //! Configure LO1's output power // Out of range values will be coerced to [0-63] - double _set_lo1_power( - const double power, - const direction_t dir - ); + double _set_lo1_power(const double power, const direction_t dir); //! Flash all front end LEDs at 1 Hz for the specified amount of time void _identify_with_leds(double identify_duration); @@ -328,29 +318,21 @@ private: * Frontend Controls *************************************************************************/ - void _set_tx_fe_connection(const std::string &conn); - void _set_rx_fe_connection(const std::string &conn); + void _set_tx_fe_connection(const std::string& conn); + void _set_rx_fe_connection(const std::string& conn); std::string _get_tx_fe_connection() const; std::string _get_rx_fe_connection() const; /************************************************************************** * CPLD Controls (implemented in rhodium_radio_ctrl_cpld.cpp) *************************************************************************/ - void _update_rx_freq_switches( - const double freq - ); + void _update_rx_freq_switches(const double freq); - void _update_tx_freq_switches( - const double freq - ); + void _update_tx_freq_switches(const double freq); - void _update_rx_input_switches( - const std::string &input - ); + void _update_rx_input_switches(const std::string& input); - void _update_tx_output_switches( - const std::string &output - ); + void _update_tx_output_switches(const std::string& output); /************************************************************************** * Private attributes @@ -412,7 +394,7 @@ private: //! Saved frontend connection for DSP core std::string _rx_fe_connection; std::string _tx_fe_connection; - //! Desired RF frequency + //! Desired RF frequency std::map<direction_t, double> _desired_rf_freq = { {RX_DIRECTION, 2.44e9}, {TX_DIRECTION, 2.44e9}}; //! Frequency at which gain setting was last applied. The CPLD requires a new gain @@ -446,8 +428,8 @@ private: bool _lo_dist_present = false; //! LO Distribution board output status - bool _lo_dist_rx_out_enabled[4] = { false, false, false, false }; - bool _lo_dist_tx_out_enabled[4] = { false, false, false, false }; + bool _lo_dist_rx_out_enabled[4] = {false, false, false, false}; + bool _lo_dist_tx_out_enabled[4] = {false, false, false, false}; std::unordered_map<uhd::direction_t, uhd::device_addr_t, std::hash<size_t>> _tune_args{{uhd::RX_DIRECTION, uhd::device_addr_t()}, @@ -477,4 +459,3 @@ private: }} /* namespace uhd::rfnoc */ #endif /* INCLUDED_LIBUHD_RFNOC_RHODIUM_RADIO_CTRL_IMPL_HPP */ - diff --git a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp index 85ed3ddb7..3752a2e70 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp @@ -7,11 +7,11 @@ #include "twinrx_ctrl.hpp" #include "twinrx_ids.hpp" +#include <uhd/utils/math.hpp> +#include <uhd/utils/safe_call.hpp> #include <uhdlib/usrp/common/adf435x.hpp> #include <uhdlib/usrp/common/adf535x.hpp> #include <uhdlib/utils/narrow.hpp> -#include <uhd/utils/math.hpp> -#include <uhd/utils/safe_call.hpp> #include <chrono> #include <thread> @@ -20,39 +20,44 @@ using namespace usrp; using namespace dboard::twinrx; namespace { - typedef twinrx_cpld_regmap rm; - - typedef enum { LO1, LO2 } lo_t; +typedef twinrx_cpld_regmap rm; - inline uint32_t bool2bin(bool x) { return x ? 1 : 0; } +typedef enum { LO1, LO2 } lo_t; - const double TWINRX_DESIRED_REFERENCE_FREQ = 50e6; - const double TWINRX_REV_AB_PFD_FREQ = 6.25e6; - const double TWINRX_REV_C_PFD_FREQ = 12.5e6; - const double TWINRX_SPI_CLOCK_FREQ = 3e6; +inline uint32_t bool2bin(bool x) +{ + return x ? 1 : 0; } -class twinrx_ctrl_impl : public twinrx_ctrl { +const double TWINRX_DESIRED_REFERENCE_FREQ = 50e6; +const double TWINRX_REV_AB_PFD_FREQ = 6.25e6; +const double TWINRX_REV_C_PFD_FREQ = 12.5e6; +const double TWINRX_SPI_CLOCK_FREQ = 3e6; +} // namespace + +class twinrx_ctrl_impl : public twinrx_ctrl +{ public: - twinrx_ctrl_impl( - dboard_iface::sptr db_iface, + twinrx_ctrl_impl(dboard_iface::sptr db_iface, twinrx_gpio::sptr gpio_iface, twinrx_cpld_regmap::sptr cpld_regmap, - const dboard_id_t rx_id - ) : _db_iface(db_iface), _gpio_iface(gpio_iface), _cpld_regs(cpld_regmap) + const dboard_id_t rx_id) + : _db_iface(db_iface), _gpio_iface(gpio_iface), _cpld_regs(cpld_regmap) { // SPI configuration _spi_config.use_custom_divider = true; _spi_config.divider = uhd::narrow_cast<size_t>(std::ceil( _db_iface->get_codec_rate(dboard_iface::UNIT_TX) / TWINRX_SPI_CLOCK_FREQ)); - //Initialize dboard clocks + // Initialize dboard clocks bool found_rate = false; - for(double rate: _db_iface->get_clock_rates(dboard_iface::UNIT_TX)) { - found_rate |= uhd::math::frequencies_are_equal(rate, TWINRX_DESIRED_REFERENCE_FREQ); + for (double rate : _db_iface->get_clock_rates(dboard_iface::UNIT_TX)) { + found_rate |= + uhd::math::frequencies_are_equal(rate, TWINRX_DESIRED_REFERENCE_FREQ); } - for(double rate: _db_iface->get_clock_rates(dboard_iface::UNIT_RX)) { - found_rate |= uhd::math::frequencies_are_equal(rate, TWINRX_DESIRED_REFERENCE_FREQ); + for (double rate : _db_iface->get_clock_rates(dboard_iface::UNIT_RX)) { + found_rate |= + uhd::math::frequencies_are_equal(rate, TWINRX_DESIRED_REFERENCE_FREQ); } if (not found_rate) { throw uhd::runtime_error("TwinRX not supported on this motherboard"); @@ -63,7 +68,7 @@ public: _db_iface->set_clock_enabled(dboard_iface::UNIT_TX, true); _db_iface->set_clock_enabled(dboard_iface::UNIT_RX, true); - //Initialize default switch and attenuator states + // Initialize default switch and attenuator states set_chan_enabled(BOTH, false, false); set_preamp1(BOTH, PREAMP_BYPASS, false); set_preamp2(BOTH, false, false); @@ -82,7 +87,7 @@ public: set_crossover_cal_mode(CAL_DISABLED, false); _cpld_regs->flush(); - //Turn on power and wait for power good + // Turn on power and wait for power good _gpio_iface->set_field(twinrx_gpio::FIELD_SWPS_EN, 1); size_t timeout_ms = 100; while (_gpio_iface->get_field(twinrx_gpio::FIELD_SWPS_PWR_GOOD) == 0) { @@ -98,7 +103,7 @@ public: _gpio_iface->set_field(twinrx_gpio::FIELD_LO2_CE_CH1, 1); _gpio_iface->set_field(twinrx_gpio::FIELD_LO2_CE_CH2, 1); - //Initialize synthesizers + // Initialize synthesizers for (size_t i = 0; i < NUM_CHANS; i++) { // LO1 if (rx_id == twinrx::TWINRX_REV_C_ID) { @@ -108,8 +113,7 @@ public: }, [this](uint32_t microseconds) { _db_iface->sleep(boost::chrono::microseconds(microseconds)); - } - ); + }); _lo1_iface[i]->set_pfd_freq(TWINRX_REV_C_PFD_FREQ); } else { _lo1_iface[i] = adf535x_iface::make_adf5355( @@ -118,8 +122,7 @@ public: }, [this](uint32_t microseconds) { _db_iface->sleep(boost::chrono::microseconds(microseconds)); - } - ); + }); _lo1_iface[i]->set_pfd_freq(TWINRX_REV_AB_PFD_FREQ); } _lo1_iface[i]->set_output_power(adf535x_iface::OUTPUT_POWER_5DBM); @@ -128,11 +131,10 @@ public: _lo1_iface[i]->set_frequency(3e9, 1.0e3); // LO2 - _lo2_iface[i] = adf435x_iface::make_adf4351( - [this](const std::vector<uint32_t>& regs) { + _lo2_iface[i] = + adf435x_iface::make_adf4351([this](const std::vector<uint32_t>& regs) { _write_lo_spi(dboard_iface::UNIT_RX, regs); - } - ); + }); _lo2_iface[i]->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED); _lo2_iface[i]->set_output_power(adf435x_iface::OUTPUT_POWER_5DBM); _lo2_iface[i]->set_reference_freq(TWINRX_DESIRED_REFERENCE_FREQ); @@ -145,10 +147,8 @@ public: ~twinrx_ctrl_impl() { - UHD_SAFE_CALL( - boost::lock_guard<boost::mutex> lock(_mutex); - _gpio_iface->set_field(twinrx_gpio::FIELD_SWPS_EN, 0); - ) + UHD_SAFE_CALL(boost::lock_guard<boost::mutex> lock(_mutex); + _gpio_iface->set_field(twinrx_gpio::FIELD_SWPS_EN, 0);) } void commit() @@ -171,80 +171,117 @@ public: _cpld_regs->if0_reg0.set(rm::if0_reg0_t::AMP_LO2_EN_CH2, bool2bin(enabled)); _chan_enabled[size_t(CH2)] = enabled; } - _set_lo1_amp(_chan_enabled[size_t(CH1)], _chan_enabled[size_t(CH2)], _lo1_src[size_t(CH2)]); - if (commit) _commit(); + _set_lo1_amp(_chan_enabled[size_t(CH1)], + _chan_enabled[size_t(CH2)], + _lo1_src[size_t(CH2)]); + if (commit) + _commit(); } void set_preamp1(channel_t ch, preamp_state_t value, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf0_reg1.set(rm::rf0_reg1_t::SWPA1_CTL_CH1, bool2bin(value==PREAMP_HIGHBAND)); - _cpld_regs->rf2_reg2.set(rm::rf2_reg2_t::SWPA2_CTRL_CH1, bool2bin(value==PREAMP_BYPASS)); - _cpld_regs->rf0_reg1.set(rm::rf0_reg1_t::HB_PREAMP_EN_CH1, bool2bin(value==PREAMP_HIGHBAND)); - _cpld_regs->rf0_reg1.set(rm::rf0_reg1_t::LB_PREAMP_EN_CH1, bool2bin(value==PREAMP_LOWBAND)); + _cpld_regs->rf0_reg1.set( + rm::rf0_reg1_t::SWPA1_CTL_CH1, bool2bin(value == PREAMP_HIGHBAND)); + _cpld_regs->rf2_reg2.set( + rm::rf2_reg2_t::SWPA2_CTRL_CH1, bool2bin(value == PREAMP_BYPASS)); + _cpld_regs->rf0_reg1.set( + rm::rf0_reg1_t::HB_PREAMP_EN_CH1, bool2bin(value == PREAMP_HIGHBAND)); + _cpld_regs->rf0_reg1.set( + rm::rf0_reg1_t::LB_PREAMP_EN_CH1, bool2bin(value == PREAMP_LOWBAND)); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf0_reg7.set(rm::rf0_reg7_t::SWPA1_CTRL_CH2, bool2bin(value==PREAMP_HIGHBAND)); - _cpld_regs->rf2_reg5.set(rm::rf2_reg5_t::SWPA2_CTRL_CH2, bool2bin(value==PREAMP_BYPASS)); - _cpld_regs->rf0_reg5.set(rm::rf0_reg5_t::HB_PREAMP_EN_CH2, bool2bin(value==PREAMP_HIGHBAND)); - _cpld_regs->rf2_reg6.set(rm::rf2_reg6_t::LB_PREAMP_EN_CH2, bool2bin(value==PREAMP_LOWBAND)); - } - if (commit) _commit(); + _cpld_regs->rf0_reg7.set( + rm::rf0_reg7_t::SWPA1_CTRL_CH2, bool2bin(value == PREAMP_HIGHBAND)); + _cpld_regs->rf2_reg5.set( + rm::rf2_reg5_t::SWPA2_CTRL_CH2, bool2bin(value == PREAMP_BYPASS)); + _cpld_regs->rf0_reg5.set( + rm::rf0_reg5_t::HB_PREAMP_EN_CH2, bool2bin(value == PREAMP_HIGHBAND)); + _cpld_regs->rf2_reg6.set( + rm::rf2_reg6_t::LB_PREAMP_EN_CH2, bool2bin(value == PREAMP_LOWBAND)); + } + if (commit) + _commit(); } void set_preamp2(channel_t ch, bool enabled, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf2_reg7.set(rm::rf2_reg7_t::SWPA4_CTRL_CH1, bool2bin(not enabled)); + _cpld_regs->rf2_reg7.set( + rm::rf2_reg7_t::SWPA4_CTRL_CH1, bool2bin(not enabled)); _cpld_regs->rf2_reg3.set(rm::rf2_reg3_t::PREAMP2_EN_CH1, bool2bin(enabled)); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf0_reg6.set(rm::rf0_reg6_t::SWPA4_CTRL_CH2, bool2bin(not enabled)); + _cpld_regs->rf0_reg6.set( + rm::rf0_reg6_t::SWPA4_CTRL_CH2, bool2bin(not enabled)); _cpld_regs->rf1_reg6.set(rm::rf1_reg6_t::PREAMP2_EN_CH2, bool2bin(enabled)); } - if (commit) _commit(); + if (commit) + _commit(); } void set_lb_preamp_preselector(channel_t ch, bool enabled, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf0_reg7.set(rm::rf0_reg7_t::SWPA3_CTRL_CH1, bool2bin(not enabled)); + _cpld_regs->rf0_reg7.set( + rm::rf0_reg7_t::SWPA3_CTRL_CH1, bool2bin(not enabled)); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf0_reg1.set(rm::rf0_reg1_t::SWPA3_CTRL_CH2, bool2bin(not enabled)); + _cpld_regs->rf0_reg1.set( + rm::rf0_reg1_t::SWPA3_CTRL_CH2, bool2bin(not enabled)); } - if (commit) _commit(); + if (commit) + _commit(); } void set_signal_path(channel_t ch, signal_path_t path, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf2_reg2.set(rm::rf2_reg2_t::SW11_CTRL_CH1, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->rf1_reg2.set(rm::rf1_reg2_t::SW12_CTRL_CH1, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->rf1_reg6.set(rm::rf1_reg6_t::HB_PRESEL_PGA_EN_CH1, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::SW6_CTRL_CH1, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->if0_reg3.set(rm::if0_reg3_t::SW13_CTRL_CH1, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->if0_reg2.set(rm::if0_reg2_t::AMP_LB_IF1_EN_CH1, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->if0_reg0.set(rm::if0_reg0_t::AMP_HB_IF1_EN_CH1, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->rf1_reg2.set(rm::rf1_reg2_t::AMP_HB_EN_CH1, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->rf2_reg2.set(rm::rf2_reg2_t::AMP_LB_EN_CH1, bool2bin(path==PATH_LOWBAND)); + _cpld_regs->rf2_reg2.set( + rm::rf2_reg2_t::SW11_CTRL_CH1, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->rf1_reg2.set( + rm::rf1_reg2_t::SW12_CTRL_CH1, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->rf1_reg6.set( + rm::rf1_reg6_t::HB_PRESEL_PGA_EN_CH1, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->rf0_reg2.set( + rm::rf0_reg2_t::SW6_CTRL_CH1, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->if0_reg3.set( + rm::if0_reg3_t::SW13_CTRL_CH1, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->if0_reg2.set( + rm::if0_reg2_t::AMP_LB_IF1_EN_CH1, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->if0_reg0.set( + rm::if0_reg0_t::AMP_HB_IF1_EN_CH1, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->rf1_reg2.set( + rm::rf1_reg2_t::AMP_HB_EN_CH1, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->rf2_reg2.set( + rm::rf2_reg2_t::AMP_LB_EN_CH1, bool2bin(path == PATH_LOWBAND)); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf2_reg7.set(rm::rf2_reg7_t::SW11_CTRL_CH2, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->rf1_reg7.set(rm::rf1_reg7_t::SW12_CTRL_CH2, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->rf1_reg2.set(rm::rf1_reg2_t::HB_PRESEL_PGA_EN_CH2, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->rf0_reg6.set(rm::rf0_reg6_t::SW6_CTRL_CH2, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->if0_reg6.set(rm::if0_reg6_t::SW13_CTRL_CH2, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->if0_reg2.set(rm::if0_reg2_t::AMP_LB_IF1_EN_CH2, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->if0_reg6.set(rm::if0_reg6_t::AMP_HB_IF1_EN_CH2, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->rf1_reg7.set(rm::rf1_reg7_t::AMP_HB_EN_CH2, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->rf2_reg7.set(rm::rf2_reg7_t::AMP_LB_EN_CH2, bool2bin(path==PATH_LOWBAND)); - } - if (commit) _commit(); + _cpld_regs->rf2_reg7.set( + rm::rf2_reg7_t::SW11_CTRL_CH2, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->rf1_reg7.set( + rm::rf1_reg7_t::SW12_CTRL_CH2, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->rf1_reg2.set( + rm::rf1_reg2_t::HB_PRESEL_PGA_EN_CH2, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->rf0_reg6.set( + rm::rf0_reg6_t::SW6_CTRL_CH2, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->if0_reg6.set( + rm::if0_reg6_t::SW13_CTRL_CH2, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->if0_reg2.set( + rm::if0_reg2_t::AMP_LB_IF1_EN_CH2, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->if0_reg6.set( + rm::if0_reg6_t::AMP_HB_IF1_EN_CH2, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->rf1_reg7.set( + rm::rf1_reg7_t::AMP_HB_EN_CH2, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->rf2_reg7.set( + rm::rf2_reg7_t::AMP_LB_EN_CH2, bool2bin(path == PATH_LOWBAND)); + } + if (commit) + _commit(); } void set_lb_preselector(channel_t ch, preselector_path_t path, bool commit = true) @@ -252,11 +289,24 @@ public: boost::lock_guard<boost::mutex> lock(_mutex); uint32_t sw7val = 0, sw8val = 0; switch (path) { - case PRESEL_PATH1: sw7val = 3; sw8val = 1; break; - case PRESEL_PATH2: sw7val = 2; sw8val = 0; break; - case PRESEL_PATH3: sw7val = 0; sw8val = 2; break; - case PRESEL_PATH4: sw7val = 1; sw8val = 3; break; - default: UHD_THROW_INVALID_CODE_PATH(); + case PRESEL_PATH1: + sw7val = 3; + sw8val = 1; + break; + case PRESEL_PATH2: + sw7val = 2; + sw8val = 0; + break; + case PRESEL_PATH3: + sw7val = 0; + sw8val = 2; + break; + case PRESEL_PATH4: + sw7val = 1; + sw8val = 3; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } if (ch == CH1 or ch == BOTH) { _cpld_regs->rf0_reg3.set(rm::rf0_reg3_t::SW7_CTRL_CH1, sw7val); @@ -266,7 +316,8 @@ public: _cpld_regs->rf0_reg7.set(rm::rf0_reg7_t::SW7_CTRL_CH2, sw7val); _cpld_regs->rf2_reg7.set(rm::rf2_reg7_t::SW8_CTRL_CH2, sw8val); } - if (commit) _commit(); + if (commit) + _commit(); } void set_hb_preselector(channel_t ch, preselector_path_t path, bool commit = true) @@ -274,11 +325,32 @@ public: boost::lock_guard<boost::mutex> lock(_mutex); uint32_t sw9ch1val = 0, sw10ch1val = 0, sw9ch2val = 0, sw10ch2val = 0; switch (path) { - case PRESEL_PATH1: sw9ch1val = 3; sw10ch1val = 0; sw9ch2val = 0; sw10ch2val = 3; break; - case PRESEL_PATH2: sw9ch1val = 1; sw10ch1val = 2; sw9ch2val = 1; sw10ch2val = 1; break; - case PRESEL_PATH3: sw9ch1val = 2; sw10ch1val = 1; sw9ch2val = 2; sw10ch2val = 2; break; - case PRESEL_PATH4: sw9ch1val = 0; sw10ch1val = 3; sw9ch2val = 3; sw10ch2val = 0; break; - default: UHD_THROW_INVALID_CODE_PATH(); + case PRESEL_PATH1: + sw9ch1val = 3; + sw10ch1val = 0; + sw9ch2val = 0; + sw10ch2val = 3; + break; + case PRESEL_PATH2: + sw9ch1val = 1; + sw10ch1val = 2; + sw9ch2val = 1; + sw10ch2val = 1; + break; + case PRESEL_PATH3: + sw9ch1val = 2; + sw10ch1val = 1; + sw9ch2val = 2; + sw10ch2val = 2; + break; + case PRESEL_PATH4: + sw9ch1val = 0; + sw10ch1val = 3; + sw9ch2val = 3; + sw10ch2val = 0; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } if (ch == CH1 or ch == BOTH) { _cpld_regs->rf0_reg5.set(rm::rf0_reg5_t::SW9_CTRL_CH1, sw9ch1val); @@ -288,104 +360,129 @@ public: _cpld_regs->rf0_reg3.set(rm::rf0_reg3_t::SW9_CTRL_CH2, sw9ch2val); _cpld_regs->rf1_reg7.set(rm::rf1_reg7_t::SW10_CTRL_CH2, sw10ch2val); } - if (commit) _commit(); - + if (commit) + _commit(); } void set_input_atten(channel_t ch, uint8_t atten, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf0_reg0.set(rm::rf0_reg0_t::ATTEN_IN_CH1, atten&0x1F); + _cpld_regs->rf0_reg0.set(rm::rf0_reg0_t::ATTEN_IN_CH1, atten & 0x1F); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf0_reg4.set(rm::rf0_reg4_t::ATTEN_IN_CH2, atten&0x1F); + _cpld_regs->rf0_reg4.set(rm::rf0_reg4_t::ATTEN_IN_CH2, atten & 0x1F); } - if (commit) _commit(); + if (commit) + _commit(); } void set_lb_atten(channel_t ch, uint8_t atten, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf2_reg0.set(rm::rf2_reg0_t::ATTEN_LB_CH1, atten&0x1F); + _cpld_regs->rf2_reg0.set(rm::rf2_reg0_t::ATTEN_LB_CH1, atten & 0x1F); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf2_reg4.set(rm::rf2_reg4_t::ATTEN_LB_CH2, atten&0x1F); + _cpld_regs->rf2_reg4.set(rm::rf2_reg4_t::ATTEN_LB_CH2, atten & 0x1F); } - if (commit) _commit(); + if (commit) + _commit(); } void set_hb_atten(channel_t ch, uint8_t atten, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf1_reg0.set(rm::rf1_reg0_t::ATTEN_HB_CH1, atten&0x1F); + _cpld_regs->rf1_reg0.set(rm::rf1_reg0_t::ATTEN_HB_CH1, atten & 0x1F); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf1_reg4.set(rm::rf1_reg4_t::ATTEN_HB_CH2, atten&0x1F); + _cpld_regs->rf1_reg4.set(rm::rf1_reg4_t::ATTEN_HB_CH2, atten & 0x1F); } - if (commit) _commit(); + if (commit) + _commit(); } void set_lo1_source(channel_t ch, lo_source_t source, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf1_reg5.set(rm::rf1_reg5_t::SW14_CTRL_CH2, bool2bin(source!=LO_COMPANION)); - _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::SW15_CTRL_CH1, bool2bin(source==LO_EXTERNAL||source==LO_REIMPORT)); - _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::SW16_CTRL_CH1, bool2bin(source!=LO_INTERNAL)); + _cpld_regs->rf1_reg5.set( + rm::rf1_reg5_t::SW14_CTRL_CH2, bool2bin(source != LO_COMPANION)); + _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::SW15_CTRL_CH1, + bool2bin(source == LO_EXTERNAL || source == LO_REIMPORT)); + _cpld_regs->rf1_reg1.set( + rm::rf1_reg1_t::SW16_CTRL_CH1, bool2bin(source != LO_INTERNAL)); _lo1_src[size_t(CH1)] = source; } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::SW14_CTRL_CH1, bool2bin(source==LO_COMPANION)); - _cpld_regs->rf1_reg5.set(rm::rf1_reg5_t::SW15_CTRL_CH2, bool2bin(source!=LO_INTERNAL)); - _cpld_regs->rf1_reg6.set(rm::rf1_reg6_t::SW16_CTRL_CH2, bool2bin(source==LO_INTERNAL)); + _cpld_regs->rf1_reg1.set( + rm::rf1_reg1_t::SW14_CTRL_CH1, bool2bin(source == LO_COMPANION)); + _cpld_regs->rf1_reg5.set( + rm::rf1_reg5_t::SW15_CTRL_CH2, bool2bin(source != LO_INTERNAL)); + _cpld_regs->rf1_reg6.set( + rm::rf1_reg6_t::SW16_CTRL_CH2, bool2bin(source == LO_INTERNAL)); _lo1_src[size_t(CH2)] = source; - _set_lo1_amp(_chan_enabled[size_t(CH1)], _chan_enabled[size_t(CH2)], _lo1_src[size_t(CH2)]); + _set_lo1_amp(_chan_enabled[size_t(CH1)], + _chan_enabled[size_t(CH2)], + _lo1_src[size_t(CH2)]); } - if (commit) _commit(); + if (commit) + _commit(); } void set_lo2_source(channel_t ch, lo_source_t source, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->if0_reg0.set(rm::if0_reg0_t::SW19_CTRL_CH2, bool2bin(source==LO_COMPANION)); - _cpld_regs->if0_reg1.set(rm::if0_reg1_t::SW20_CTRL_CH1, bool2bin(source==LO_COMPANION)); - _cpld_regs->if0_reg4.set(rm::if0_reg4_t::SW21_CTRL_CH1, bool2bin(source==LO_INTERNAL)); + _cpld_regs->if0_reg0.set( + rm::if0_reg0_t::SW19_CTRL_CH2, bool2bin(source == LO_COMPANION)); + _cpld_regs->if0_reg1.set( + rm::if0_reg1_t::SW20_CTRL_CH1, bool2bin(source == LO_COMPANION)); + _cpld_regs->if0_reg4.set( + rm::if0_reg4_t::SW21_CTRL_CH1, bool2bin(source == LO_INTERNAL)); _lo2_src[size_t(CH1)] = source; } if (ch == CH2 or ch == BOTH) { - _cpld_regs->if0_reg4.set(rm::if0_reg4_t::SW19_CTRL_CH1, bool2bin(source==LO_EXTERNAL||source==LO_REIMPORT)); - _cpld_regs->if0_reg0.set(rm::if0_reg0_t::SW20_CTRL_CH2, bool2bin(source==LO_INTERNAL||source==LO_DISABLED)); - _cpld_regs->if0_reg4.set(rm::if0_reg4_t::SW21_CTRL_CH2, bool2bin(source==LO_INTERNAL)); + _cpld_regs->if0_reg4.set(rm::if0_reg4_t::SW19_CTRL_CH1, + bool2bin(source == LO_EXTERNAL || source == LO_REIMPORT)); + _cpld_regs->if0_reg0.set(rm::if0_reg0_t::SW20_CTRL_CH2, + bool2bin(source == LO_INTERNAL || source == LO_DISABLED)); + _cpld_regs->if0_reg4.set( + rm::if0_reg4_t::SW21_CTRL_CH2, bool2bin(source == LO_INTERNAL)); _lo2_src[size_t(CH2)] = source; } - if (commit) _commit(); + if (commit) + _commit(); } void set_lo1_export_source(lo_export_source_t source, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); - //SW22 may conflict with the cal switch but this attr takes priority and we assume - //that the cal switch is disabled (by disabling it!) + // SW22 may conflict with the cal switch but this attr takes priority and we + // assume that the cal switch is disabled (by disabling it!) _set_cal_mode(CAL_DISABLED, source); - _cpld_regs->rf1_reg3.set(rm::rf1_reg3_t::SW23_CTRL, bool2bin(source!=LO_CH1_SYNTH)); + _cpld_regs->rf1_reg3.set( + rm::rf1_reg3_t::SW23_CTRL, bool2bin(source != LO_CH1_SYNTH)); _lo1_export = source; - if (commit) _commit(); + if (commit) + _commit(); } void set_lo2_export_source(lo_export_source_t source, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); - _cpld_regs->if0_reg7.set(rm::if0_reg7_t::SW24_CTRL_CH2, bool2bin(source==LO_CH2_SYNTH)); - _cpld_regs->if0_reg4.set(rm::if0_reg4_t::SW25_CTRL, bool2bin(source!=LO_CH1_SYNTH)); - _cpld_regs->if0_reg3.set(rm::if0_reg3_t::SW24_CTRL_CH1, bool2bin(source!=LO_CH1_SYNTH)); + _cpld_regs->if0_reg7.set( + rm::if0_reg7_t::SW24_CTRL_CH2, bool2bin(source == LO_CH2_SYNTH)); + _cpld_regs->if0_reg4.set( + rm::if0_reg4_t::SW25_CTRL, bool2bin(source != LO_CH1_SYNTH)); + _cpld_regs->if0_reg3.set( + rm::if0_reg3_t::SW24_CTRL_CH1, bool2bin(source != LO_CH1_SYNTH)); _lo2_export = source; - if (commit) _commit(); + if (commit) + _commit(); } void set_antenna_mapping(antenna_mapping_t mapping, bool commit = true) @@ -396,40 +493,60 @@ public: switch_path_t path1, path2; switch (mapping) { - case ANTX_NATIVE: - path1 = CONNECT; path2 = CONNECT; break; - case ANT1_SHARED: - path1 = EXPORT; path2 = IMPORT; break; - case ANT2_SHARED: - path1 = IMPORT; path2 = EXPORT; break; - case ANTX_SWAPPED: - path1 = SWAP; path2 = SWAP; break; - default: - path1 = TERM; path2 = TERM; break; - } - - _cpld_regs->rf0_reg5.set(rm::rf0_reg5_t::SW3_CTRL_CH1, bool2bin(path1==EXPORT||path1==SWAP)); - _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::SW4_CTRL_CH1, bool2bin(!(path1==IMPORT||path1==SWAP))); - _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::SW5_CTRL_CH1, bool2bin(path1==CONNECT)); - _cpld_regs->rf0_reg7.set(rm::rf0_reg7_t::SW3_CTRL_CH2, bool2bin(path2==EXPORT||path2==SWAP)); - _cpld_regs->rf0_reg6.set(rm::rf0_reg6_t::SW4_CTRL_CH2, bool2bin(path2==IMPORT||path2==SWAP)); - _cpld_regs->rf0_reg6.set(rm::rf0_reg6_t::SW5_CTRL_CH2, bool2bin(path2==CONNECT)); - - if (commit) _commit(); + case ANTX_NATIVE: + path1 = CONNECT; + path2 = CONNECT; + break; + case ANT1_SHARED: + path1 = EXPORT; + path2 = IMPORT; + break; + case ANT2_SHARED: + path1 = IMPORT; + path2 = EXPORT; + break; + case ANTX_SWAPPED: + path1 = SWAP; + path2 = SWAP; + break; + default: + path1 = TERM; + path2 = TERM; + break; + } + + _cpld_regs->rf0_reg5.set( + rm::rf0_reg5_t::SW3_CTRL_CH1, bool2bin(path1 == EXPORT || path1 == SWAP)); + _cpld_regs->rf0_reg2.set( + rm::rf0_reg2_t::SW4_CTRL_CH1, bool2bin(!(path1 == IMPORT || path1 == SWAP))); + _cpld_regs->rf0_reg2.set( + rm::rf0_reg2_t::SW5_CTRL_CH1, bool2bin(path1 == CONNECT)); + _cpld_regs->rf0_reg7.set( + rm::rf0_reg7_t::SW3_CTRL_CH2, bool2bin(path2 == EXPORT || path2 == SWAP)); + _cpld_regs->rf0_reg6.set( + rm::rf0_reg6_t::SW4_CTRL_CH2, bool2bin(path2 == IMPORT || path2 == SWAP)); + _cpld_regs->rf0_reg6.set( + rm::rf0_reg6_t::SW5_CTRL_CH2, bool2bin(path2 == CONNECT)); + + if (commit) + _commit(); } void set_crossover_cal_mode(cal_mode_t cal_mode, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (_lo1_export == LO_CH1_SYNTH && cal_mode == CAL_CH2) { - throw uhd::runtime_error("cannot enable cal crossover on CH2 when LO1 in CH1 is exported"); + throw uhd::runtime_error( + "cannot enable cal crossover on CH2 when LO1 in CH1 is exported"); } if (_lo1_export == LO_CH2_SYNTH && cal_mode == CAL_CH1) { - throw uhd::runtime_error("cannot enable cal crossover on CH1 when LO1 in CH2 is exported"); + throw uhd::runtime_error( + "cannot enable cal crossover on CH1 when LO1 in CH2 is exported"); } _set_cal_mode(cal_mode, _lo1_export); - if (commit) _commit(); + if (commit) + _commit(); } double set_lo1_synth_freq(channel_t ch, double freq, bool commit = true) @@ -439,15 +556,18 @@ public: double coerced_freq = 0.0; if (ch == CH1 or ch == BOTH) { - coerced_freq = _lo1_iface[size_t(CH1)]->set_frequency(freq, RESOLUTION, false); + coerced_freq = + _lo1_iface[size_t(CH1)]->set_frequency(freq, RESOLUTION, false); _lo1_freq[size_t(CH1)] = tune_freq_t(freq); } if (ch == CH2 or ch == BOTH) { - coerced_freq = _lo1_iface[size_t(CH2)]->set_frequency(freq, RESOLUTION, false); + coerced_freq = + _lo1_iface[size_t(CH2)]->set_frequency(freq, RESOLUTION, false); _lo1_freq[size_t(CH2)] = tune_freq_t(freq); } - if (commit) _commit(); + if (commit) + _commit(); return coerced_freq; } @@ -465,7 +585,8 @@ public: _lo2_freq[size_t(CH2)] = tune_freq_t(freq); } - if (commit) _commit(); + if (commit) + _commit(); return coerced_freq; } @@ -525,10 +646,12 @@ public: bool locked = true; if (ch == CH1 or ch == BOTH) { - locked = locked && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO1_MUXOUT_CH1) == 1); + locked = locked + && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO1_MUXOUT_CH1) == 1); } if (ch == CH2 or ch == BOTH) { - locked = locked && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO1_MUXOUT_CH2) == 1); + locked = locked + && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO1_MUXOUT_CH2) == 1); } return locked; } @@ -539,102 +662,124 @@ public: bool locked = true; if (ch == CH1 or ch == BOTH) { - locked = locked && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO2_MUXOUT_CH1) == 1); + locked = locked + && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO2_MUXOUT_CH1) == 1); } if (ch == CH2 or ch == BOTH) { - locked = locked && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO2_MUXOUT_CH2) == 1); + locked = locked + && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO2_MUXOUT_CH2) == 1); } return locked; } -private: //Functions +private: // Functions void _set_cal_mode(cal_mode_t cal_mode, lo_export_source_t lo1_export_src) { - _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::SW17_CTRL_CH1, bool2bin(cal_mode!=CAL_CH1)); - _cpld_regs->rf1_reg6.set(rm::rf1_reg6_t::SW17_CTRL_CH2, bool2bin(cal_mode!=CAL_CH2)); - _cpld_regs->rf1_reg5.set(rm::rf1_reg5_t::SW18_CTRL_CH1, bool2bin(cal_mode!=CAL_CH1)); - _cpld_regs->rf2_reg3.set(rm::rf2_reg3_t::SW18_CTRL_CH2, bool2bin(cal_mode!=CAL_CH2)); - _cpld_regs->rf1_reg3.set(rm::rf1_reg3_t::SW22_CTRL_CH1, bool2bin((lo1_export_src!=LO_CH1_SYNTH)||(cal_mode==CAL_CH1))); - _cpld_regs->rf1_reg7.set(rm::rf1_reg7_t::SW22_CTRL_CH2, bool2bin((lo1_export_src!=LO_CH2_SYNTH)||(cal_mode==CAL_CH2))); + _cpld_regs->rf1_reg1.set( + rm::rf1_reg1_t::SW17_CTRL_CH1, bool2bin(cal_mode != CAL_CH1)); + _cpld_regs->rf1_reg6.set( + rm::rf1_reg6_t::SW17_CTRL_CH2, bool2bin(cal_mode != CAL_CH2)); + _cpld_regs->rf1_reg5.set( + rm::rf1_reg5_t::SW18_CTRL_CH1, bool2bin(cal_mode != CAL_CH1)); + _cpld_regs->rf2_reg3.set( + rm::rf2_reg3_t::SW18_CTRL_CH2, bool2bin(cal_mode != CAL_CH2)); + _cpld_regs->rf1_reg3.set(rm::rf1_reg3_t::SW22_CTRL_CH1, + bool2bin((lo1_export_src != LO_CH1_SYNTH) || (cal_mode == CAL_CH1))); + _cpld_regs->rf1_reg7.set(rm::rf1_reg7_t::SW22_CTRL_CH2, + bool2bin((lo1_export_src != LO_CH2_SYNTH) || (cal_mode == CAL_CH2))); } void _set_lo1_amp(bool ch1_enabled, bool ch2_enabled, lo_source_t ch2_lo1_src) { // AMP_LO1_EN_CH1 also controls the amp for the external LO1 port, // which could be in use by ch2 - _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::AMP_LO1_EN_CH1, bool2bin( - ch1_enabled || (ch2_enabled && (ch2_lo1_src == LO_EXTERNAL || ch2_lo1_src == LO_REIMPORT)))); + _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::AMP_LO1_EN_CH1, + bool2bin( + ch1_enabled + || (ch2_enabled + && (ch2_lo1_src == LO_EXTERNAL || ch2_lo1_src == LO_REIMPORT)))); } void _config_lo_route(lo_t lo, channel_t channel) { - //Route SPI LEs through CPLD (will not assert them) - _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::LO1_LE_CH1, bool2bin(lo == LO1 and (channel == CH1 or channel == BOTH))); - _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::LO1_LE_CH2, bool2bin(lo == LO1 and (channel == CH2 or channel == BOTH))); + // Route SPI LEs through CPLD (will not assert them) + _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::LO1_LE_CH1, + bool2bin(lo == LO1 and (channel == CH1 or channel == BOTH))); + _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::LO1_LE_CH2, + bool2bin(lo == LO1 and (channel == CH2 or channel == BOTH))); _cpld_regs->rf0_reg2.flush(); - _cpld_regs->if0_reg2.set(rm::if0_reg2_t::LO2_LE_CH1, bool2bin(lo == LO2 and (channel == CH1 or channel == BOTH))); - _cpld_regs->if0_reg2.set(rm::if0_reg2_t::LO2_LE_CH2, bool2bin(lo == LO2 and (channel == CH2 or channel == BOTH))); + _cpld_regs->if0_reg2.set(rm::if0_reg2_t::LO2_LE_CH1, + bool2bin(lo == LO2 and (channel == CH1 or channel == BOTH))); + _cpld_regs->if0_reg2.set(rm::if0_reg2_t::LO2_LE_CH2, + bool2bin(lo == LO2 and (channel == CH2 or channel == BOTH))); _cpld_regs->if0_reg2.flush(); } - void _write_lo_spi(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s) + void _write_lo_spi(dboard_iface::unit_t unit, const std::vector<uint32_t>& regs) { - for(uint32_t reg: regs) { + for (uint32_t reg : regs) { _db_iface->write_spi(unit, _spi_config, reg, 32); } } void _commit() { - //Commit everything except the LO synthesizers + // Commit everything except the LO synthesizers _cpld_regs->flush(); // Disable unused LO synthesizers - _lo1_enable[size_t(CH1)] = _lo1_src[size_t(CH1)] == LO_INTERNAL || - _lo1_src[size_t(CH2)] == LO_COMPANION || - _lo1_export == LO_CH1_SYNTH; - - _lo1_enable[size_t(CH2)] = _lo1_src[size_t(CH2)] == LO_INTERNAL || - _lo1_src[size_t(CH1)] == LO_COMPANION || - _lo1_export == LO_CH2_SYNTH; - _lo2_enable[size_t(CH1)] = _lo2_src[size_t(CH1)] == LO_INTERNAL || - _lo2_src[size_t(CH2)] == LO_COMPANION || - _lo2_export == LO_CH1_SYNTH; - - _lo2_enable[size_t(CH2)] = _lo2_src[size_t(CH2)] == LO_INTERNAL || - _lo2_src[size_t(CH1)] == LO_COMPANION || - _lo2_export == LO_CH2_SYNTH; - - _lo1_iface[size_t(CH1)]->set_output_enable(adf535x_iface::RF_OUTPUT_A, _lo1_enable[size_t(CH1)].get()); - _lo1_iface[size_t(CH2)]->set_output_enable(adf535x_iface::RF_OUTPUT_A, _lo1_enable[size_t(CH2)].get()); - - _lo2_iface[size_t(CH1)]->set_output_enable(adf435x_iface::RF_OUTPUT_A, _lo2_enable[size_t(CH1)].get()); - _lo2_iface[size_t(CH2)]->set_output_enable(adf435x_iface::RF_OUTPUT_A, _lo2_enable[size_t(CH2)].get()); - - //Commit LO1 frequency - // Commit Channel 1's settings to both channels simultaneously if the frequency is the same. - bool simultaneous_commit_lo1 = _lo1_freq[size_t(CH1)].is_dirty() and - _lo1_freq[size_t(CH2)].is_dirty() and - _lo1_freq[size_t(CH1)].get() == _lo1_freq[size_t(CH2)].get() and - _lo1_enable[size_t(CH1)].get() == _lo1_enable[size_t(CH2)].get(); + _lo1_enable[size_t(CH1)] = _lo1_src[size_t(CH1)] == LO_INTERNAL + || _lo1_src[size_t(CH2)] == LO_COMPANION + || _lo1_export == LO_CH1_SYNTH; + + _lo1_enable[size_t(CH2)] = _lo1_src[size_t(CH2)] == LO_INTERNAL + || _lo1_src[size_t(CH1)] == LO_COMPANION + || _lo1_export == LO_CH2_SYNTH; + _lo2_enable[size_t(CH1)] = _lo2_src[size_t(CH1)] == LO_INTERNAL + || _lo2_src[size_t(CH2)] == LO_COMPANION + || _lo2_export == LO_CH1_SYNTH; + + _lo2_enable[size_t(CH2)] = _lo2_src[size_t(CH2)] == LO_INTERNAL + || _lo2_src[size_t(CH1)] == LO_COMPANION + || _lo2_export == LO_CH2_SYNTH; + + _lo1_iface[size_t(CH1)]->set_output_enable( + adf535x_iface::RF_OUTPUT_A, _lo1_enable[size_t(CH1)].get()); + _lo1_iface[size_t(CH2)]->set_output_enable( + adf535x_iface::RF_OUTPUT_A, _lo1_enable[size_t(CH2)].get()); + + _lo2_iface[size_t(CH1)]->set_output_enable( + adf435x_iface::RF_OUTPUT_A, _lo2_enable[size_t(CH1)].get()); + _lo2_iface[size_t(CH2)]->set_output_enable( + adf435x_iface::RF_OUTPUT_A, _lo2_enable[size_t(CH2)].get()); + + // Commit LO1 frequency + // Commit Channel 1's settings to both channels simultaneously if the frequency is + // the same. + bool simultaneous_commit_lo1 = + _lo1_freq[size_t(CH1)].is_dirty() and _lo1_freq[size_t(CH2)].is_dirty() + and _lo1_freq[size_t(CH1)].get() == _lo1_freq[size_t(CH2)].get() + and _lo1_enable[size_t(CH1)].get() == _lo1_enable[size_t(CH2)].get(); if (simultaneous_commit_lo1) { _config_lo_route(LO1, BOTH); - //Only commit one of the channels. The route LO_CONFIG_BOTH - //will ensure that the LEs for both channels are enabled + // Only commit one of the channels. The route LO_CONFIG_BOTH + // will ensure that the LEs for both channels are enabled _lo1_iface[size_t(CH1)]->commit(); _lo1_freq[size_t(CH1)].mark_clean(); _lo1_freq[size_t(CH2)].mark_clean(); _lo1_enable[size_t(CH1)].mark_clean(); _lo1_enable[size_t(CH2)].mark_clean(); } else { - if (_lo1_freq[size_t(CH1)].is_dirty() || _lo1_enable[size_t(CH1)].is_dirty()) { + if (_lo1_freq[size_t(CH1)].is_dirty() + || _lo1_enable[size_t(CH1)].is_dirty()) { _config_lo_route(LO1, CH1); _lo1_iface[size_t(CH1)]->commit(); _lo1_freq[size_t(CH1)].mark_clean(); _lo1_enable[size_t(CH1)].mark_clean(); } - if (_lo1_freq[size_t(CH2)].is_dirty() || _lo1_enable[size_t(CH2)].is_dirty()) { + if (_lo1_freq[size_t(CH2)].is_dirty() + || _lo1_enable[size_t(CH2)].is_dirty()) { _config_lo_route(LO1, CH2); _lo1_iface[size_t(CH2)]->commit(); _lo1_freq[size_t(CH2)].mark_clean(); @@ -642,29 +787,31 @@ private: //Functions } } - //Commit LO2 frequency - bool simultaneous_commit_lo2 = _lo2_freq[size_t(CH1)].is_dirty() and - _lo2_freq[size_t(CH2)].is_dirty() and - _lo2_freq[size_t(CH1)].get() == _lo2_freq[size_t(CH2)].get() and - _lo2_enable[size_t(CH1)].get() == _lo2_enable[size_t(CH2)].get(); + // Commit LO2 frequency + bool simultaneous_commit_lo2 = + _lo2_freq[size_t(CH1)].is_dirty() and _lo2_freq[size_t(CH2)].is_dirty() + and _lo2_freq[size_t(CH1)].get() == _lo2_freq[size_t(CH2)].get() + and _lo2_enable[size_t(CH1)].get() == _lo2_enable[size_t(CH2)].get(); if (simultaneous_commit_lo2) { _config_lo_route(LO2, BOTH); - //Only commit one of the channels. The route LO_CONFIG_BOTH - //will ensure that the LEs for both channels are enabled + // Only commit one of the channels. The route LO_CONFIG_BOTH + // will ensure that the LEs for both channels are enabled _lo2_iface[size_t(CH1)]->commit(); _lo2_freq[size_t(CH1)].mark_clean(); _lo2_freq[size_t(CH2)].mark_clean(); _lo2_enable[size_t(CH1)].mark_clean(); _lo2_enable[size_t(CH2)].mark_clean(); } else { - if (_lo2_freq[size_t(CH1)].is_dirty() || _lo2_enable[size_t(CH1)].is_dirty()) { + if (_lo2_freq[size_t(CH1)].is_dirty() + || _lo2_enable[size_t(CH1)].is_dirty()) { _config_lo_route(LO2, CH1); _lo2_iface[size_t(CH1)]->commit(); _lo2_freq[size_t(CH1)].mark_clean(); _lo2_enable[size_t(CH1)].mark_clean(); } - if (_lo2_freq[size_t(CH2)].is_dirty() || _lo2_enable[size_t(CH2)].is_dirty()) { + if (_lo2_freq[size_t(CH2)].is_dirty() + || _lo2_enable[size_t(CH2)].is_dirty()) { _config_lo_route(LO2, CH2); _lo2_iface[size_t(CH2)]->commit(); _lo2_freq[size_t(CH2)].mark_clean(); @@ -673,40 +820,46 @@ private: //Functions } } -private: //Members +private: // Members static const size_t NUM_CHANS = 2; - struct tune_freq_t : public uhd::math::fp_compare::fp_compare_delta<double> { - tune_freq_t() : uhd::math::fp_compare::fp_compare_delta<double>( - 0.0, uhd::math::FREQ_COMPARISON_DELTA_HZ) {} + struct tune_freq_t : public uhd::math::fp_compare::fp_compare_delta<double> + { + tune_freq_t() + : uhd::math::fp_compare::fp_compare_delta<double>( + 0.0, uhd::math::FREQ_COMPARISON_DELTA_HZ) + { + } - tune_freq_t(double freq) : uhd::math::fp_compare::fp_compare_delta<double>( - freq, uhd::math::FREQ_COMPARISON_DELTA_HZ) {} + tune_freq_t(double freq) + : uhd::math::fp_compare::fp_compare_delta<double>( + freq, uhd::math::FREQ_COMPARISON_DELTA_HZ) + { + } }; - boost::mutex _mutex; - dboard_iface::sptr _db_iface; - twinrx_gpio::sptr _gpio_iface; - twinrx_cpld_regmap::sptr _cpld_regs; - spi_config_t _spi_config; - adf535x_iface::sptr _lo1_iface[NUM_CHANS]; - adf435x_iface::sptr _lo2_iface[NUM_CHANS]; - lo_source_t _lo1_src[NUM_CHANS]; - lo_source_t _lo2_src[NUM_CHANS]; - dirty_tracked<tune_freq_t> _lo1_freq[NUM_CHANS]; - dirty_tracked<tune_freq_t> _lo2_freq[NUM_CHANS]; - dirty_tracked<bool> _lo1_enable[NUM_CHANS]; - dirty_tracked<bool> _lo2_enable[NUM_CHANS]; - lo_export_source_t _lo1_export; - lo_export_source_t _lo2_export; - bool _chan_enabled[NUM_CHANS]; + boost::mutex _mutex; + dboard_iface::sptr _db_iface; + twinrx_gpio::sptr _gpio_iface; + twinrx_cpld_regmap::sptr _cpld_regs; + spi_config_t _spi_config; + adf535x_iface::sptr _lo1_iface[NUM_CHANS]; + adf435x_iface::sptr _lo2_iface[NUM_CHANS]; + lo_source_t _lo1_src[NUM_CHANS]; + lo_source_t _lo2_src[NUM_CHANS]; + dirty_tracked<tune_freq_t> _lo1_freq[NUM_CHANS]; + dirty_tracked<tune_freq_t> _lo2_freq[NUM_CHANS]; + dirty_tracked<bool> _lo1_enable[NUM_CHANS]; + dirty_tracked<bool> _lo2_enable[NUM_CHANS]; + lo_export_source_t _lo1_export; + lo_export_source_t _lo2_export; + bool _chan_enabled[NUM_CHANS]; }; -twinrx_ctrl::sptr twinrx_ctrl::make( - dboard_iface::sptr db_iface, +twinrx_ctrl::sptr twinrx_ctrl::make(dboard_iface::sptr db_iface, twinrx_gpio::sptr gpio_iface, twinrx_cpld_regmap::sptr cpld_regmap, - const dboard_id_t rx_id -) { + const dboard_id_t rx_id) +{ return std::make_shared<twinrx_ctrl_impl>(db_iface, gpio_iface, cpld_regmap, rx_id); } diff --git a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.hpp b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.hpp index dfdacde11..2f4d84ed5 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.hpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.hpp @@ -9,22 +9,21 @@ #define INCLUDED_DBOARD_TWINRX_CTRL_HPP #include "twinrx_io.hpp" +#include <uhd/types/ranges.hpp> #include <uhd/types/wb_iface.hpp> #include <uhd/utils/noncopyable.hpp> -#include <uhd/types/ranges.hpp> namespace uhd { namespace usrp { namespace dboard { namespace twinrx { -class twinrx_ctrl : public uhd::noncopyable { +class twinrx_ctrl : public uhd::noncopyable +{ public: typedef std::shared_ptr<twinrx_ctrl> sptr; - static sptr make( - dboard_iface::sptr db_iface, + static sptr make(dboard_iface::sptr db_iface, twinrx_gpio::sptr gpio_iface, twinrx_cpld_regmap::sptr cpld_regmap, - dboard_id_t rx_id - ); + dboard_id_t rx_id); virtual ~twinrx_ctrl() {} @@ -40,7 +39,13 @@ public: enum lo_export_source_t { LO_CH1_SYNTH, LO_CH2_SYNTH, LO_EXPORT_DISABLED }; - enum antenna_mapping_t { ANTX_NATIVE, ANT1_SHARED, ANT2_SHARED, ANTX_SWAPPED, ANTX_DISABLED }; + enum antenna_mapping_t { + ANTX_NATIVE, + ANT1_SHARED, + ANT2_SHARED, + ANTX_SWAPPED, + ANTX_DISABLED + }; enum cal_mode_t { CAL_DISABLED, CAL_CH1, CAL_CH2 }; @@ -52,13 +57,17 @@ public: virtual void set_preamp2(channel_t ch, bool enabled, bool commit = true) = 0; - virtual void set_lb_preamp_preselector(channel_t ch, bool enabled, bool commit = true) = 0; + virtual void set_lb_preamp_preselector( + channel_t ch, bool enabled, bool commit = true) = 0; - virtual void set_signal_path(channel_t ch, signal_path_t path, bool commit = true) = 0; + virtual void set_signal_path( + channel_t ch, signal_path_t path, bool commit = true) = 0; - virtual void set_lb_preselector(channel_t ch, preselector_path_t path, bool commit = true) = 0; + virtual void set_lb_preselector( + channel_t ch, preselector_path_t path, bool commit = true) = 0; - virtual void set_hb_preselector(channel_t ch, preselector_path_t path, bool commit = true) = 0; + virtual void set_hb_preselector( + channel_t ch, preselector_path_t path, bool commit = true) = 0; virtual void set_input_atten(channel_t ch, uint8_t atten, bool commit = true) = 0; @@ -82,9 +91,11 @@ public: virtual double set_lo2_synth_freq(channel_t ch, double freq, bool commit = true) = 0; - virtual double set_lo1_charge_pump(channel_t ch, double current, bool commit = true) = 0; + virtual double set_lo1_charge_pump( + channel_t ch, double current, bool commit = true) = 0; - virtual double set_lo2_charge_pump(channel_t ch, double current, bool commit = true) = 0; + virtual double set_lo2_charge_pump( + channel_t ch, double current, bool commit = true) = 0; virtual uhd::meta_range_t get_lo1_charge_pump_range() = 0; @@ -95,6 +106,6 @@ public: virtual bool read_lo2_locked(channel_t ch) = 0; }; -}}}} //namespaces +}}}} // namespace uhd::usrp::dboard::twinrx #endif /* INCLUDED_DBOARD_TWINRX_CTRL_HPP */ diff --git a/host/lib/usrp/dboard/twinrx/twinrx_experts.cpp b/host/lib/usrp/dboard/twinrx/twinrx_experts.cpp index f98521cc9..36bcc1863 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_experts.cpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_experts.cpp @@ -7,12 +7,11 @@ #include "twinrx_experts.hpp" #include "twinrx_gain_tables.hpp" -#include <uhd/utils/math.hpp> -#include <uhd/utils/log.hpp> #include <uhd/exception.hpp> #include <uhd/types/dict.hpp> #include <uhd/types/ranges.hpp> -#include <uhd/types/dict.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/math.hpp> #include <boost/assign/list_of.hpp> #include <boost/math/special_functions/round.hpp> @@ -37,15 +36,15 @@ void twinrx_scheduling_expert::resolve() */ void twinrx_freq_path_expert::resolve() { - //Lowband/highband switch point + // Lowband/highband switch point static const double LB_HB_THRESHOLD_FREQ = 1.8e9; static const double LB_TARGET_IF1_FREQ = 2.345e9; static const double HB_TARGET_IF1_FREQ = 1.25e9; static const double INJ_SIDE_THRESHOLD_FREQ = 5.1e9; - static const double FIXED_LO1_THRESHOLD_FREQ= 50e6; + static const double FIXED_LO1_THRESHOLD_FREQ = 50e6; - //Preselector filter switch point + // Preselector filter switch point static const double LB_FILT1_THRESHOLD_FREQ = 0.5e9; static const double LB_FILT2_THRESHOLD_FREQ = 0.8e9; static const double LB_FILT3_THRESHOLD_FREQ = 1.2e9; @@ -57,7 +56,7 @@ void twinrx_freq_path_expert::resolve() static const double LB_PREAMP_PRESEL_THRESHOLD_FREQ = 0.8e9; - //Misc + // Misc static const double INST_BANDWIDTH = 80e6; static const double MANUAL_LO_HYSTERESIS_PPM = 1.0; @@ -65,8 +64,8 @@ void twinrx_freq_path_expert::resolve() rf_freq_abs_t rf_freq(FREQ_RANGE.clip(_rf_freq_d)); // Choose low-band vs high-band depending on frequency - _signal_path = (rf_freq > LB_HB_THRESHOLD_FREQ) ? - twinrx_ctrl::PATH_HIGHBAND : twinrx_ctrl::PATH_LOWBAND; + _signal_path = (rf_freq > LB_HB_THRESHOLD_FREQ) ? twinrx_ctrl::PATH_HIGHBAND + : twinrx_ctrl::PATH_LOWBAND; if (_signal_path == twinrx_ctrl::PATH_LOWBAND) { // Choose low-band preselector filter if (rf_freq < LB_FILT1_THRESHOLD_FREQ) { @@ -97,41 +96,43 @@ void twinrx_freq_path_expert::resolve() UHD_THROW_INVALID_CODE_PATH(); } - //Choose low-band preamp preselector + // Choose low-band preamp preselector _lb_preamp_presel = (rf_freq > LB_PREAMP_PRESEL_THRESHOLD_FREQ); - //Choose LO frequencies - const double target_if1_freq = (_signal_path == twinrx_ctrl::PATH_HIGHBAND) ? - HB_TARGET_IF1_FREQ : LB_TARGET_IF1_FREQ; + // Choose LO frequencies + const double target_if1_freq = (_signal_path == twinrx_ctrl::PATH_HIGHBAND) + ? HB_TARGET_IF1_FREQ + : LB_TARGET_IF1_FREQ; const double target_if2_freq = _if_freq_d; // LO1 double lo1_freq_ideal = 0.0, lo2_freq_ideal = 0.0; if (rf_freq <= FIXED_LO1_THRESHOLD_FREQ) { - //LO1 Freq static + // LO1 Freq static lo1_freq_ideal = target_if1_freq + FIXED_LO1_THRESHOLD_FREQ; } else if (rf_freq <= INJ_SIDE_THRESHOLD_FREQ) { - //High-side LO1 Injection + // High-side LO1 Injection lo1_freq_ideal = rf_freq.get() + target_if1_freq; } else { - //Low-side LO1 Injection + // Low-side LO1 Injection lo1_freq_ideal = rf_freq.get() - target_if1_freq; } if (_lo1_freq_d.get_author() == experts::AUTHOR_USER) { - if (_lo1_freq_d.is_dirty()) { //Are we here because the LO frequency was set? + if (_lo1_freq_d.is_dirty()) { // Are we here because the LO frequency was set? // The user explicitly requested to set the LO freq so don't touch it! } else { // Something else changed which may cause the LO frequency to update. // Only commit if the frequency is stale. If the user's value is stale // reset the author to expert. - if (rf_freq_ppm_t(lo1_freq_ideal, MANUAL_LO_HYSTERESIS_PPM) != _lo1_freq_d.get()) { - _lo1_freq_d = lo1_freq_ideal; //Reset author + if (rf_freq_ppm_t(lo1_freq_ideal, MANUAL_LO_HYSTERESIS_PPM) + != _lo1_freq_d.get()) { + _lo1_freq_d = lo1_freq_ideal; // Reset author } } } else { // The LO frequency was never set by the user. Let the expert take care of it - _lo1_freq_d = lo1_freq_ideal; //Reset author + _lo1_freq_d = lo1_freq_ideal; // Reset author } // LO2 @@ -144,37 +145,40 @@ void twinrx_freq_path_expert::resolve() } if (_lo2_freq_d.get_author() == experts::AUTHOR_USER) { - if (_lo2_freq_d.is_dirty()) { //Are we here because the LO frequency was set? + if (_lo2_freq_d.is_dirty()) { // Are we here because the LO frequency was set? // The user explicitly requested to set the LO freq so don't touch it! } else { // Something else changed which may cause the LO frequency to update. // Only commit if the frequency is stale. If the user's value is stale // reset the author to expert. - if (rf_freq_ppm_t(lo2_freq_ideal, MANUAL_LO_HYSTERESIS_PPM) != _lo2_freq_d.get()) { - _lo2_freq_d = lo2_freq_ideal; //Reset author + if (rf_freq_ppm_t(lo2_freq_ideal, MANUAL_LO_HYSTERESIS_PPM) + != _lo2_freq_d.get()) { + _lo2_freq_d = lo2_freq_ideal; // Reset author } } } else { // The LO frequency was never set by the user. Let the expert take care of it - _lo2_freq_d = lo2_freq_ideal; //Reset author + _lo2_freq_d = lo2_freq_ideal; // Reset author } // Determine injection side using the final LO frequency - _lo1_inj_side = (_lo1_freq_d > rf_freq.get()) ? INJ_HIGH_SIDE : INJ_LOW_SIDE; + _lo1_inj_side = (_lo1_freq_d > rf_freq.get()) ? INJ_HIGH_SIDE : INJ_LOW_SIDE; _lo2_inj_side = (_lo2_freq_d > target_if1_freq) ? INJ_HIGH_SIDE : INJ_LOW_SIDE; } lo_inj_side_t twinrx_freq_path_expert::_compute_lo2_inj_side( - double lo1_freq, double if1_freq, double if2_freq, double bandwidth -) { + double lo1_freq, double if1_freq, double if2_freq, double bandwidth) +{ static const int MAX_SPUR_ORDER = 5; for (int ord = MAX_SPUR_ORDER; ord >= 1; ord--) { // Check high-side injection first - if (not _has_mixer_spurs(lo1_freq, if1_freq + if2_freq, if2_freq, bandwidth, ord)) { + if (not _has_mixer_spurs( + lo1_freq, if1_freq + if2_freq, if2_freq, bandwidth, ord)) { return INJ_HIGH_SIDE; } // Check low-side injection second - if (not _has_mixer_spurs(lo1_freq, if1_freq - if2_freq, if2_freq, bandwidth, ord)) { + if (not _has_mixer_spurs( + lo1_freq, if1_freq - if2_freq, if2_freq, bandwidth, ord)) { return INJ_LOW_SIDE; } } @@ -183,19 +187,18 @@ lo_inj_side_t twinrx_freq_path_expert::_compute_lo2_inj_side( } bool twinrx_freq_path_expert::_has_mixer_spurs( - double lo1_freq, double lo2_freq, double if2_freq, - double bandwidth, int spur_order -) { + double lo1_freq, double lo2_freq, double if2_freq, double bandwidth, int spur_order) +{ // Iterate through all N-th order harmomic combinations // of LOs... for (int lo1h_i = 1; lo1h_i <= spur_order; lo1h_i++) { double lo1harm_freq = lo1_freq * lo1h_i; for (int lo2h_i = 1; lo2h_i <= spur_order; lo2h_i++) { double lo2harm_freq = lo2_freq * lo2h_i; - double hdelta = lo1harm_freq - lo2harm_freq; + double hdelta = lo1harm_freq - lo2harm_freq; // .. and check if there is a mixer spur in the IF band - if (std::abs(hdelta + if2_freq) < bandwidth/2 or - std::abs(hdelta - if2_freq) < bandwidth/2) { + if (std::abs(hdelta + if2_freq) < bandwidth / 2 + or std::abs(hdelta - if2_freq) < bandwidth / 2) { return true; } } @@ -211,11 +214,12 @@ bool twinrx_freq_path_expert::_has_mixer_spurs( void twinrx_freq_coercion_expert::resolve() { const double actual_if2_freq = _if_freq_d; - const double actual_if1_freq = (_lo2_inj_side == INJ_LOW_SIDE) ? - (_lo2_freq_c + actual_if2_freq) : (_lo2_freq_c - actual_if2_freq); + const double actual_if1_freq = (_lo2_inj_side == INJ_LOW_SIDE) + ? (_lo2_freq_c + actual_if2_freq) + : (_lo2_freq_c - actual_if2_freq); - _rf_freq_c = (_lo1_inj_side == INJ_LOW_SIDE) ? - (_lo1_freq_c + actual_if1_freq) : (_lo1_freq_c - actual_if1_freq); + _rf_freq_c = (_lo1_inj_side == INJ_LOW_SIDE) ? (_lo1_freq_c + actual_if1_freq) + : (_lo1_freq_c - actual_if1_freq); } /*!--------------------------------------------------------- @@ -238,12 +242,14 @@ void twinrx_nyquist_expert::resolve() _cached_cmd_time = _rx_frontend_time; double if_freq_sign = 1.0; - if (_lo1_inj_side == INJ_HIGH_SIDE) if_freq_sign *= -1.0; - if (_lo2_inj_side == INJ_HIGH_SIDE) if_freq_sign *= -1.0; + if (_lo1_inj_side == INJ_HIGH_SIDE) + if_freq_sign *= -1.0; + if (_lo2_inj_side == INJ_HIGH_SIDE) + if_freq_sign *= -1.0; _if_freq_c = _if_freq_d * if_freq_sign; - _db_iface->set_fe_connection(dboard_iface::UNIT_RX, _channel, - usrp::fe_connection_t(_codec_conn, _if_freq_c)); + _db_iface->set_fe_connection( + dboard_iface::UNIT_RX, _channel, usrp::fe_connection_t(_codec_conn, _if_freq_c)); } /*!--------------------------------------------------------- @@ -253,22 +259,22 @@ void twinrx_nyquist_expert::resolve() void twinrx_chan_gain_expert::resolve() { if (_gain_profile != "default") { - //TODO: Implement me! + // TODO: Implement me! throw uhd::not_implemented_error("custom gain strategies not implemeted yet"); } - //Lookup table using settings - const twinrx_gain_table table = twinrx_gain_table::lookup_table( - _signal_path, - (_signal_path==twinrx_ctrl::PATH_HIGHBAND) ? _hb_presel : _lb_presel, + // Lookup table using settings + const twinrx_gain_table table = twinrx_gain_table::lookup_table(_signal_path, + (_signal_path == twinrx_ctrl::PATH_HIGHBAND) ? _hb_presel : _lb_presel, _gain_profile); - //Compute minimum gain. The user-specified gain value will be interpreted as - //the gain applied on top of the minimum gain state. - //If antennas are shared or swapped, the switch has 6dB of loss - size_t gain_index = std::min(static_cast<size_t>(boost::math::round(_gain.get())), table.get_num_entries()-1); + // Compute minimum gain. The user-specified gain value will be interpreted as + // the gain applied on top of the minimum gain state. + // If antennas are shared or swapped, the switch has 6dB of loss + size_t gain_index = std::min(static_cast<size_t>(boost::math::round(_gain.get())), + table.get_num_entries() - 1); - //Translate gain to an index in the gain table + // Translate gain to an index in the gain table const twinrx_gain_config_t& config = table.find_by_index(gain_index); _input_atten = config.atten1; @@ -279,8 +285,10 @@ void twinrx_chan_gain_expert::resolve() } // Preamp 1 should use the Highband amp for frequencies above 3 GHz - if (_signal_path == twinrx_ctrl::PATH_HIGHBAND && _hb_presel != twinrx_ctrl::PRESEL_PATH1) { - _preamp1 = config.amp1 ? twinrx_ctrl::PREAMP_HIGHBAND : twinrx_ctrl::PREAMP_BYPASS; + if (_signal_path == twinrx_ctrl::PATH_HIGHBAND + && _hb_presel != twinrx_ctrl::PRESEL_PATH1) { + _preamp1 = config.amp1 ? twinrx_ctrl::PREAMP_HIGHBAND + : twinrx_ctrl::PREAMP_BYPASS; } else { _preamp1 = config.amp1 ? twinrx_ctrl::PREAMP_LOWBAND : twinrx_ctrl::PREAMP_BYPASS; } @@ -295,22 +303,21 @@ void twinrx_chan_gain_expert::resolve() void twinrx_lo_config_expert::resolve() { static const uhd::dict<std::string, twinrx_ctrl::lo_source_t> src_lookup = - boost::assign::map_list_of - ("internal", twinrx_ctrl::LO_INTERNAL) - ("external", twinrx_ctrl::LO_EXTERNAL) - ("companion", twinrx_ctrl::LO_COMPANION) - ("disabled", twinrx_ctrl::LO_DISABLED) - ("reimport", twinrx_ctrl::LO_REIMPORT); + boost::assign::map_list_of("internal", twinrx_ctrl::LO_INTERNAL)( + "external", twinrx_ctrl::LO_EXTERNAL)("companion", twinrx_ctrl::LO_COMPANION)( + "disabled", twinrx_ctrl::LO_DISABLED)("reimport", twinrx_ctrl::LO_REIMPORT); if (src_lookup.has_key(_lo_source_ch0)) { _lo1_src_ch0 = _lo2_src_ch0 = src_lookup[_lo_source_ch0]; } else { - throw uhd::value_error("Invalid LO source for channel 0.Choose from {internal, external, companion, reimport}"); + throw uhd::value_error("Invalid LO source for channel 0.Choose from {internal, " + "external, companion, reimport}"); } if (src_lookup.has_key(_lo_source_ch1)) { _lo1_src_ch1 = _lo2_src_ch1 = src_lookup[_lo_source_ch1]; } else { - throw uhd::value_error("Invalid LO source for channel 1.Choose from {internal, external, companion, reimport}"); + throw uhd::value_error("Invalid LO source for channel 1.Choose from {internal, " + "external, companion, reimport}"); } twinrx_ctrl::lo_export_source_t export_src = twinrx_ctrl::LO_EXPORT_DISABLED; @@ -325,11 +332,13 @@ void twinrx_lo_config_expert::resolve() if (_lo_export_ch0 and _lo_export_ch1) { throw uhd::value_error("Cannot export LOs for both channels"); } else if (_lo_export_ch0) { - export_src = (_lo1_src_ch0 == twinrx_ctrl::LO_COMPANION) ? - twinrx_ctrl::LO_CH2_SYNTH : twinrx_ctrl::LO_CH1_SYNTH; + export_src = (_lo1_src_ch0 == twinrx_ctrl::LO_COMPANION) + ? twinrx_ctrl::LO_CH2_SYNTH + : twinrx_ctrl::LO_CH1_SYNTH; } else if (_lo_export_ch1) { - export_src = (_lo1_src_ch1 == twinrx_ctrl::LO_COMPANION) ? - twinrx_ctrl::LO_CH1_SYNTH : twinrx_ctrl::LO_CH2_SYNTH; + export_src = (_lo1_src_ch1 == twinrx_ctrl::LO_COMPANION) + ? twinrx_ctrl::LO_CH1_SYNTH + : twinrx_ctrl::LO_CH2_SYNTH; } _lo1_export_src = _lo2_export_src = export_src; } @@ -348,12 +357,14 @@ void twinrx_lo_mapping_expert::resolve() // "internal" or "reimport" -> this channel // "companion" -> other channel size_t synth_map[] = {0, 0}; - if (_lox_src_ch0 == twinrx_ctrl::LO_INTERNAL or _lox_src_ch0 == twinrx_ctrl::LO_REIMPORT) { + if (_lox_src_ch0 == twinrx_ctrl::LO_INTERNAL + or _lox_src_ch0 == twinrx_ctrl::LO_REIMPORT) { synth_map[0] = synth_map[0] | CH0_MSK; } else if (_lox_src_ch0 == twinrx_ctrl::LO_COMPANION) { synth_map[1] = synth_map[1] | CH0_MSK; } - if (_lox_src_ch1 == twinrx_ctrl::LO_INTERNAL or _lox_src_ch1 == twinrx_ctrl::LO_REIMPORT) { + if (_lox_src_ch1 == twinrx_ctrl::LO_INTERNAL + or _lox_src_ch1 == twinrx_ctrl::LO_REIMPORT) { synth_map[1] = synth_map[1] | CH1_MSK; } else if (_lox_src_ch1 == twinrx_ctrl::LO_COMPANION) { synth_map[0] = synth_map[0] | CH1_MSK; @@ -365,20 +376,22 @@ void twinrx_lo_mapping_expert::resolve() // to overlap tuning with signal dwell time. bool hopping_enabled = false; if (_lox_src_ch0 == twinrx_ctrl::LO_DISABLED) { - if (_lox_src_ch1 == twinrx_ctrl::LO_INTERNAL or _lox_src_ch1 == twinrx_ctrl::LO_REIMPORT) { - synth_map[0] = synth_map[0] | CH0_MSK; + if (_lox_src_ch1 == twinrx_ctrl::LO_INTERNAL + or _lox_src_ch1 == twinrx_ctrl::LO_REIMPORT) { + synth_map[0] = synth_map[0] | CH0_MSK; hopping_enabled = true; } else if (_lox_src_ch1 == twinrx_ctrl::LO_COMPANION) { - synth_map[1] = synth_map[1] | CH0_MSK; + synth_map[1] = synth_map[1] | CH0_MSK; hopping_enabled = true; } } if (_lox_src_ch1 == twinrx_ctrl::LO_DISABLED) { - if (_lox_src_ch0 == twinrx_ctrl::LO_INTERNAL or _lox_src_ch0 == twinrx_ctrl::LO_REIMPORT) { - synth_map[1] = synth_map[1] | CH1_MSK; + if (_lox_src_ch0 == twinrx_ctrl::LO_INTERNAL + or _lox_src_ch0 == twinrx_ctrl::LO_REIMPORT) { + synth_map[1] = synth_map[1] | CH1_MSK; hopping_enabled = true; } else if (_lox_src_ch0 == twinrx_ctrl::LO_COMPANION) { - synth_map[0] = synth_map[0] | CH1_MSK; + synth_map[0] = synth_map[0] | CH1_MSK; hopping_enabled = true; } } @@ -387,7 +400,7 @@ void twinrx_lo_mapping_expert::resolve() for (size_t synth = 0; synth < 2; synth++) { experts::data_writer_t<lo_synth_mapping_t>& lox_mapping = (synth == 0) ? _lox_mapping_synth0 : _lox_mapping_synth1; - if (synth_map[synth] == (CH0_MSK|CH1_MSK)) { + if (synth_map[synth] == (CH0_MSK | CH1_MSK)) { lox_mapping = MAPPING_SHARED; } else if (synth_map[synth] == CH0_MSK) { lox_mapping = MAPPING_CH0; @@ -429,18 +442,22 @@ void twinrx_antenna_expert::resolve() } else if (_antenna_ch0 == ANT1 and _antenna_ch1 == ANT0) { _ant_mapping = twinrx_ctrl::ANTX_SWAPPED; } else if (_antenna_ch0 != ANT0 and _antenna_ch0 != ANT1) { - throw uhd::value_error("Invalid antenna selection " + _antenna_ch0.get() + " for channel 0. Must be " + ANT0 + " or " + ANT1); + throw uhd::value_error("Invalid antenna selection " + _antenna_ch0.get() + + " for channel 0. Must be " + ANT0 + " or " + ANT1); } else if (_antenna_ch1 != ANT0 and _antenna_ch1 != ANT1) { - throw uhd::value_error("Invalid antenna selection " + _antenna_ch1.get() + " for channel 1. Must be " + ANT0 + " or " + ANT1); + throw uhd::value_error("Invalid antenna selection " + _antenna_ch1.get() + + " for channel 1. Must be " + ANT0 + " or " + ANT1); } - //TODO: Implement hooks for the calibration switch + // TODO: Implement hooks for the calibration switch _cal_mode = twinrx_ctrl::CAL_DISABLED; if (_cal_mode == twinrx_ctrl::CAL_CH1 and _lo_export_ch1) { - throw uhd::value_error("Cannot calibrate channel 0 and export the LO for channel 1."); + throw uhd::value_error( + "Cannot calibrate channel 0 and export the LO for channel 1."); } else if (_cal_mode == twinrx_ctrl::CAL_CH2 and _lo_export_ch0) { - throw uhd::value_error("Cannot calibrate channel 1 and export the LO for channel 0."); + throw uhd::value_error( + "Cannot calibrate channel 1 and export the LO for channel 0."); } } @@ -451,72 +468,72 @@ void twinrx_antenna_expert::resolve() void twinrx_ant_gain_expert::resolve() { switch (_ant_mapping) { - case twinrx_ctrl::ANTX_NATIVE: - _ant0_input_atten = _ch0_input_atten; - _ant0_preamp1 = _ch0_preamp1; - _ant0_preamp2 = _ch0_preamp2; - _ant0_lb_preamp_presel = _ch0_lb_preamp_presel; - _ant1_input_atten = _ch1_input_atten; - _ant1_preamp1 = _ch1_preamp1; - _ant1_preamp2 = _ch1_preamp2; - _ant1_lb_preamp_presel = _ch1_lb_preamp_presel; - break; - case twinrx_ctrl::ANTX_SWAPPED: - _ant0_input_atten = _ch1_input_atten; - _ant0_preamp1 = _ch1_preamp1; - _ant0_preamp2 = _ch1_preamp2; - _ant0_lb_preamp_presel = _ch1_lb_preamp_presel; - _ant1_input_atten = _ch0_input_atten; - _ant1_preamp1 = _ch0_preamp1; - _ant1_preamp2 = _ch0_preamp2; - _ant1_lb_preamp_presel = _ch0_lb_preamp_presel; - break; - case twinrx_ctrl::ANT1_SHARED: - if ((_ch0_input_atten != _ch1_input_atten) or - (_ch0_preamp1 != _ch1_preamp1) or - (_ch0_preamp2 != _ch1_preamp2) or - (_ch0_lb_preamp_presel != _ch1_lb_preamp_presel)) - { - UHD_LOGGER_WARNING("TWINRX") << "incompatible gain settings for antenna sharing. temporarily using Ch0 settings for Ch1."; - } - _ant0_input_atten = _ch0_input_atten; - _ant0_preamp1 = _ch0_preamp1; - _ant0_preamp2 = _ch0_preamp2; - _ant0_lb_preamp_presel = _ch0_lb_preamp_presel; - - _ant1_input_atten = 0; - _ant1_preamp1 = twinrx_ctrl::PREAMP_BYPASS; - _ant1_preamp2 = false; - _ant1_lb_preamp_presel = false; - break; - case twinrx_ctrl::ANT2_SHARED: - if ((_ch0_input_atten != _ch1_input_atten) or - (_ch0_preamp1 != _ch1_preamp1) or - (_ch0_preamp2 != _ch1_preamp2) or - (_ch0_lb_preamp_presel != _ch1_lb_preamp_presel)) - { - UHD_LOGGER_WARNING("TWINRX") << "incompatible gain settings for antenna sharing. temporarily using Ch0 settings for Ch1."; - } - _ant1_input_atten = _ch0_input_atten; - _ant1_preamp1 = _ch0_preamp1; - _ant1_preamp2 = _ch0_preamp2; - _ant1_lb_preamp_presel = _ch0_lb_preamp_presel; - - _ant0_input_atten = 0; - _ant0_preamp1 = twinrx_ctrl::PREAMP_BYPASS; - _ant0_preamp2 = false; - _ant0_lb_preamp_presel = false; - break; - default: - _ant0_input_atten = 0; - _ant0_preamp1 = twinrx_ctrl::PREAMP_BYPASS; - _ant0_preamp2 = false; - _ant0_lb_preamp_presel = false; - _ant1_input_atten = 0; - _ant1_preamp1 = twinrx_ctrl::PREAMP_BYPASS; - _ant1_preamp2 = false; - _ant1_lb_preamp_presel = false; - break; + case twinrx_ctrl::ANTX_NATIVE: + _ant0_input_atten = _ch0_input_atten; + _ant0_preamp1 = _ch0_preamp1; + _ant0_preamp2 = _ch0_preamp2; + _ant0_lb_preamp_presel = _ch0_lb_preamp_presel; + _ant1_input_atten = _ch1_input_atten; + _ant1_preamp1 = _ch1_preamp1; + _ant1_preamp2 = _ch1_preamp2; + _ant1_lb_preamp_presel = _ch1_lb_preamp_presel; + break; + case twinrx_ctrl::ANTX_SWAPPED: + _ant0_input_atten = _ch1_input_atten; + _ant0_preamp1 = _ch1_preamp1; + _ant0_preamp2 = _ch1_preamp2; + _ant0_lb_preamp_presel = _ch1_lb_preamp_presel; + _ant1_input_atten = _ch0_input_atten; + _ant1_preamp1 = _ch0_preamp1; + _ant1_preamp2 = _ch0_preamp2; + _ant1_lb_preamp_presel = _ch0_lb_preamp_presel; + break; + case twinrx_ctrl::ANT1_SHARED: + if ((_ch0_input_atten != _ch1_input_atten) or (_ch0_preamp1 != _ch1_preamp1) + or (_ch0_preamp2 != _ch1_preamp2) + or (_ch0_lb_preamp_presel != _ch1_lb_preamp_presel)) { + UHD_LOGGER_WARNING("TWINRX") + << "incompatible gain settings for antenna sharing. temporarily " + "using Ch0 settings for Ch1."; + } + _ant0_input_atten = _ch0_input_atten; + _ant0_preamp1 = _ch0_preamp1; + _ant0_preamp2 = _ch0_preamp2; + _ant0_lb_preamp_presel = _ch0_lb_preamp_presel; + + _ant1_input_atten = 0; + _ant1_preamp1 = twinrx_ctrl::PREAMP_BYPASS; + _ant1_preamp2 = false; + _ant1_lb_preamp_presel = false; + break; + case twinrx_ctrl::ANT2_SHARED: + if ((_ch0_input_atten != _ch1_input_atten) or (_ch0_preamp1 != _ch1_preamp1) + or (_ch0_preamp2 != _ch1_preamp2) + or (_ch0_lb_preamp_presel != _ch1_lb_preamp_presel)) { + UHD_LOGGER_WARNING("TWINRX") + << "incompatible gain settings for antenna sharing. temporarily " + "using Ch0 settings for Ch1."; + } + _ant1_input_atten = _ch0_input_atten; + _ant1_preamp1 = _ch0_preamp1; + _ant1_preamp2 = _ch0_preamp2; + _ant1_lb_preamp_presel = _ch0_lb_preamp_presel; + + _ant0_input_atten = 0; + _ant0_preamp1 = twinrx_ctrl::PREAMP_BYPASS; + _ant0_preamp2 = false; + _ant0_lb_preamp_presel = false; + break; + default: + _ant0_input_atten = 0; + _ant0_preamp1 = twinrx_ctrl::PREAMP_BYPASS; + _ant0_preamp2 = false; + _ant0_lb_preamp_presel = false; + _ant1_input_atten = 0; + _ant1_preamp1 = twinrx_ctrl::PREAMP_BYPASS; + _ant1_preamp2 = false; + _ant1_lb_preamp_presel = false; + break; } } @@ -529,7 +546,7 @@ const bool twinrx_settings_expert::FORCE_COMMIT = false; void twinrx_settings_expert::resolve() { for (size_t i = 0; i < 2; i++) { - ch_settings& ch_set = (i == 1) ? _ch1 : _ch0; + ch_settings& ch_set = (i == 1) ? _ch1 : _ch0; twinrx_ctrl::channel_t ch = (i == 1) ? twinrx_ctrl::CH2 : twinrx_ctrl::CH1; _ctrl->set_chan_enabled(ch, ch_set.chan_enabled, FORCE_COMMIT); _ctrl->set_preamp1(ch, ch_set.preamp1, FORCE_COMMIT); @@ -550,34 +567,45 @@ void twinrx_settings_expert::resolve() } _resolve_lox_freq(STAGE_LO1, - _ch0.lo1_freq_d, _ch1.lo1_freq_d, _ch0.lo1_freq_c, _ch1.lo1_freq_c, - _ch0.lo1_source, _ch1.lo1_source, _lo1_synth0_mapping, _lo1_synth1_mapping, + _ch0.lo1_freq_d, + _ch1.lo1_freq_d, + _ch0.lo1_freq_c, + _ch1.lo1_freq_c, + _ch0.lo1_source, + _ch1.lo1_source, + _lo1_synth0_mapping, + _lo1_synth1_mapping, _lo1_hopping_enabled); _resolve_lox_freq(STAGE_LO2, - _ch0.lo2_freq_d, _ch1.lo2_freq_d, _ch0.lo2_freq_c, _ch1.lo2_freq_c, - _ch0.lo2_source, _ch1.lo2_source, _lo2_synth0_mapping, _lo2_synth1_mapping, + _ch0.lo2_freq_d, + _ch1.lo2_freq_d, + _ch0.lo2_freq_c, + _ch1.lo2_freq_c, + _ch0.lo2_source, + _ch1.lo2_source, + _lo2_synth0_mapping, + _lo2_synth1_mapping, _lo2_hopping_enabled); _ctrl->set_lo1_export_source(_lo1_export_src, FORCE_COMMIT); _ctrl->set_lo2_export_source(_lo2_export_src, FORCE_COMMIT); _ctrl->set_antenna_mapping(_ant_mapping, FORCE_COMMIT); - //TODO: Re-enable this when we support this mode + // TODO: Re-enable this when we support this mode //_ctrl->set_crossover_cal_mode(_cal_mode, FORCE_COMMIT); _ctrl->commit(); } -void twinrx_settings_expert::_resolve_lox_freq( - lo_stage_t lo_stage, +void twinrx_settings_expert::_resolve_lox_freq(lo_stage_t lo_stage, uhd::experts::data_reader_t<double>& ch0_freq_d, uhd::experts::data_reader_t<double>& ch1_freq_d, uhd::experts::data_writer_t<double>& ch0_freq_c, uhd::experts::data_writer_t<double>& ch1_freq_c, - twinrx_ctrl::lo_source_t ch0_lo_source, - twinrx_ctrl::lo_source_t ch1_lo_source, - lo_synth_mapping_t synth0_mapping, - lo_synth_mapping_t synth1_mapping, - bool hopping_enabled) + twinrx_ctrl::lo_source_t ch0_lo_source, + twinrx_ctrl::lo_source_t ch1_lo_source, + lo_synth_mapping_t synth0_mapping, + lo_synth_mapping_t synth1_mapping, + bool hopping_enabled) { if (ch0_lo_source == twinrx_ctrl::LO_EXTERNAL) { // If the LO is external then we don't need to program any synthesizers @@ -594,7 +622,8 @@ void twinrx_settings_expert::_resolve_lox_freq( ch0_freq_c = _set_lox_synth_freq(lo_stage, twinrx_ctrl::CH2, ch0_freq_d); } else if (synth0_mapping == MAPPING_SHARED or synth1_mapping == MAPPING_SHARED) { // If any synthesizer is being shared then we are not in hopping mode - twinrx_ctrl::channel_t ch = (synth0_mapping == MAPPING_SHARED) ? twinrx_ctrl::CH1 : twinrx_ctrl::CH2; + twinrx_ctrl::channel_t ch = + (synth0_mapping == MAPPING_SHARED) ? twinrx_ctrl::CH1 : twinrx_ctrl::CH2; ch0_freq_c = _set_lox_synth_freq(lo_stage, ch, ch0_freq_d); ch1_freq_c = ch0_freq_c; } @@ -609,28 +638,32 @@ void twinrx_settings_expert::_resolve_lox_freq( // hopping, then always write the frequency because other inputs might require // an LO re-commit const bool freq_update_request = (not hopping_enabled) or ch1_freq_d.is_dirty(); - // As an additional layer of protection from unnecessarily committing the LO, check - // if the frequency has actually changed. + // As an additional layer of protection from unnecessarily committing the LO, + // check if the frequency has actually changed. if (synth0_mapping == MAPPING_CH1 and freq_update_request) { ch1_freq_c = _set_lox_synth_freq(lo_stage, twinrx_ctrl::CH1, ch1_freq_d); } else if (synth1_mapping == MAPPING_CH1 and freq_update_request) { ch1_freq_c = _set_lox_synth_freq(lo_stage, twinrx_ctrl::CH2, ch1_freq_d); } else if (synth0_mapping == MAPPING_SHARED or synth1_mapping == MAPPING_SHARED) { // If any synthesizer is being shared then we are not in hopping mode - twinrx_ctrl::channel_t ch = (synth0_mapping == MAPPING_SHARED) ? twinrx_ctrl::CH1 : twinrx_ctrl::CH2; + twinrx_ctrl::channel_t ch = + (synth0_mapping == MAPPING_SHARED) ? twinrx_ctrl::CH1 : twinrx_ctrl::CH2; ch0_freq_c = _set_lox_synth_freq(lo_stage, ch, ch0_freq_d); ch1_freq_c = ch0_freq_c; } } } -double twinrx_settings_expert::_set_lox_synth_freq(lo_stage_t stage, twinrx_ctrl::channel_t ch, double freq) +double twinrx_settings_expert::_set_lox_synth_freq( + lo_stage_t stage, twinrx_ctrl::channel_t ch, double freq) { lo_freq_cache_t* freq_cache = NULL; if (stage == STAGE_LO1) { - freq_cache = (ch == twinrx_ctrl::CH1) ? &_cached_lo1_synth0_freq : &_cached_lo1_synth1_freq; + freq_cache = (ch == twinrx_ctrl::CH1) ? &_cached_lo1_synth0_freq + : &_cached_lo1_synth1_freq; } else if (stage == STAGE_LO2) { - freq_cache = (ch == twinrx_ctrl::CH1) ? &_cached_lo2_synth0_freq : &_cached_lo2_synth1_freq; + freq_cache = (ch == twinrx_ctrl::CH1) ? &_cached_lo2_synth0_freq + : &_cached_lo2_synth1_freq; } else { throw uhd::assertion_error("Invalid LO stage"); } @@ -650,4 +683,3 @@ double twinrx_settings_expert::_set_lox_synth_freq(lo_stage_t stage, twinrx_ctrl } return coerced_freq; } - diff --git a/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp b/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp index 16569849c..c7e021a90 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp @@ -9,8 +9,8 @@ #define INCLUDED_DBOARD_TWINRX_EXPERTS_HPP #include "twinrx_ctrl.hpp" -#include <uhdlib/experts/expert_nodes.hpp> #include <uhd/utils/math.hpp> +#include <uhdlib/experts/expert_nodes.hpp> namespace uhd { namespace usrp { namespace dboard { namespace twinrx { @@ -18,26 +18,37 @@ namespace uhd { namespace usrp { namespace dboard { namespace twinrx { // Misc types and definitions //--------------------------------------------------------- -struct rf_freq_abs_t : public uhd::math::fp_compare::fp_compare_delta<double> { - rf_freq_abs_t(double freq = 0.0, double epsilon = 1.0 /* 1Hz epsilon */) : - uhd::math::fp_compare::fp_compare_delta<double>(freq, epsilon) {} - inline double get() const { return _value; } +struct rf_freq_abs_t : public uhd::math::fp_compare::fp_compare_delta<double> +{ + rf_freq_abs_t(double freq = 0.0, double epsilon = 1.0 /* 1Hz epsilon */) + : uhd::math::fp_compare::fp_compare_delta<double>(freq, epsilon) + { + } + inline double get() const + { + return _value; + } }; -struct rf_freq_ppm_t : public rf_freq_abs_t { - rf_freq_ppm_t(double freq = 0.0, double epsilon_ppm = 0.1 /* 1PPM epsilon */) : - rf_freq_abs_t(freq, 1e-6 * freq * epsilon_ppm) {} +struct rf_freq_ppm_t : public rf_freq_abs_t +{ + rf_freq_ppm_t(double freq = 0.0, double epsilon_ppm = 0.1 /* 1PPM epsilon */) + : rf_freq_abs_t(freq, 1e-6 * freq * epsilon_ppm) + { + } }; enum lo_stage_t { STAGE_LO1, STAGE_LO2 }; enum lo_inj_side_t { INJ_LOW_SIDE, INJ_HIGH_SIDE }; enum lo_synth_mapping_t { MAPPING_NONE, MAPPING_CH0, MAPPING_CH1, MAPPING_SHARED }; -static const std::string prepend_ch(std::string name, const std::string& ch) { +static const std::string prepend_ch(std::string name, const std::string& ch) +{ return ch + "/" + name; } -static const std::string lo_stage_str(lo_stage_t stage, bool lower = false) { +static const std::string lo_stage_str(lo_stage_t stage, bool lower = false) +{ std::string prefix = lower ? "lo" : "LO"; return prefix + ((stage == STAGE_LO1) ? "1" : "2"); } @@ -53,12 +64,13 @@ static const std::string lo_stage_str(lo_stage_t stage, bool lower = false) { * * --------------------------------------------------------- */ -class twinrx_scheduling_expert : public experts::worker_node_t { +class twinrx_scheduling_expert : public experts::worker_node_t +{ public: twinrx_scheduling_expert(const experts::node_retriever_t& db, std::string ch) - : experts::worker_node_t(prepend_ch("twinrx_scheduling_expert", ch)), - _command_time (db, prepend_ch("time/cmd", ch)), - _rx_frontend_time (db, prepend_ch("time/rx_frontend", ch)) + : experts::worker_node_t(prepend_ch("twinrx_scheduling_expert", ch)) + , _command_time(db, prepend_ch("time/cmd", ch)) + , _rx_frontend_time(db, prepend_ch("time/rx_frontend", ch)) { bind_accessor(_command_time); bind_accessor(_rx_frontend_time); @@ -67,11 +79,11 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<time_spec_t> _command_time; + // Inputs + experts::data_reader_t<time_spec_t> _command_time; - //Outputs - experts::data_writer_t<time_spec_t> _rx_frontend_time; + // Outputs + experts::data_writer_t<time_spec_t> _rx_frontend_time; }; /*!--------------------------------------------------------- @@ -85,20 +97,21 @@ private: * One instance of this expert is required for each channel * --------------------------------------------------------- */ -class twinrx_freq_path_expert : public experts::worker_node_t { +class twinrx_freq_path_expert : public experts::worker_node_t +{ public: twinrx_freq_path_expert(const experts::node_retriever_t& db, std::string ch) - : experts::worker_node_t(prepend_ch("twinrx_freq_path_expert", ch)), - _rf_freq_d (db, prepend_ch("freq/desired", ch)), - _if_freq_d (db, prepend_ch("if_freq/desired", ch)), - _signal_path (db, prepend_ch("ch/signal_path", ch)), - _lb_presel (db, prepend_ch("ch/lb_presel", ch)), - _hb_presel (db, prepend_ch("ch/hb_presel", ch)), - _lb_preamp_presel (db, prepend_ch("ch/lb_preamp_presel", ch)), - _lo1_freq_d (db, prepend_ch("los/LO1/freq/desired", ch)), - _lo2_freq_d (db, prepend_ch("los/LO2/freq/desired", ch)), - _lo1_inj_side (db, prepend_ch("ch/LO1/inj_side", ch)), - _lo2_inj_side (db, prepend_ch("ch/LO2/inj_side", ch)) + : experts::worker_node_t(prepend_ch("twinrx_freq_path_expert", ch)) + , _rf_freq_d(db, prepend_ch("freq/desired", ch)) + , _if_freq_d(db, prepend_ch("if_freq/desired", ch)) + , _signal_path(db, prepend_ch("ch/signal_path", ch)) + , _lb_presel(db, prepend_ch("ch/lb_presel", ch)) + , _hb_presel(db, prepend_ch("ch/hb_presel", ch)) + , _lb_preamp_presel(db, prepend_ch("ch/lb_preamp_presel", ch)) + , _lo1_freq_d(db, prepend_ch("los/LO1/freq/desired", ch)) + , _lo2_freq_d(db, prepend_ch("los/LO2/freq/desired", ch)) + , _lo1_inj_side(db, prepend_ch("ch/LO1/inj_side", ch)) + , _lo2_inj_side(db, prepend_ch("ch/LO2/inj_side", ch)) { bind_accessor(_rf_freq_d); bind_accessor(_if_freq_d); @@ -115,23 +128,25 @@ public: private: virtual void resolve(); static lo_inj_side_t _compute_lo2_inj_side( - double lo1_freq, double if1_freq, double if2_freq, double bandwidth); - static bool _has_mixer_spurs( - double lo1_freq, double lo2_freq, double if2_freq, - double bandwidth, int spur_order); - - //Inputs - experts::data_reader_t<double> _rf_freq_d; - experts::data_reader_t<double> _if_freq_d; - //Outputs - experts::data_writer_t<twinrx_ctrl::signal_path_t> _signal_path; + double lo1_freq, double if1_freq, double if2_freq, double bandwidth); + static bool _has_mixer_spurs(double lo1_freq, + double lo2_freq, + double if2_freq, + double bandwidth, + int spur_order); + + // Inputs + experts::data_reader_t<double> _rf_freq_d; + experts::data_reader_t<double> _if_freq_d; + // Outputs + experts::data_writer_t<twinrx_ctrl::signal_path_t> _signal_path; experts::data_writer_t<twinrx_ctrl::preselector_path_t> _lb_presel; experts::data_writer_t<twinrx_ctrl::preselector_path_t> _hb_presel; - experts::data_writer_t<bool> _lb_preamp_presel; - experts::data_writer_t<double> _lo1_freq_d; - experts::data_writer_t<double> _lo2_freq_d; - experts::data_writer_t<lo_inj_side_t> _lo1_inj_side; - experts::data_writer_t<lo_inj_side_t> _lo2_inj_side; + experts::data_writer_t<bool> _lb_preamp_presel; + experts::data_writer_t<double> _lo1_freq_d; + experts::data_writer_t<double> _lo2_freq_d; + experts::data_writer_t<lo_inj_side_t> _lo1_inj_side; + experts::data_writer_t<lo_inj_side_t> _lo2_inj_side; }; /*!--------------------------------------------------------- @@ -145,20 +160,21 @@ private: * One instance of this expert is required for all channels * --------------------------------------------------------- */ -class twinrx_lo_config_expert : public experts::worker_node_t { +class twinrx_lo_config_expert : public experts::worker_node_t +{ public: twinrx_lo_config_expert(const experts::node_retriever_t& db) - : experts::worker_node_t("twinrx_lo_config_expert"), - _lo_source_ch0 (db, prepend_ch("los/all/source", "0")), - _lo_source_ch1 (db, prepend_ch("los/all/source", "1")), - _lo_export_ch0 (db, prepend_ch("los/all/export", "0")), - _lo_export_ch1 (db, prepend_ch("los/all/export", "1")), - _lo1_src_ch0 (db, prepend_ch("ch/LO1/source", "0")), - _lo1_src_ch1 (db, prepend_ch("ch/LO1/source", "1")), - _lo2_src_ch0 (db, prepend_ch("ch/LO2/source", "0")), - _lo2_src_ch1 (db, prepend_ch("ch/LO2/source", "1")), - _lo1_export_src (db, "com/LO1/export_source"), - _lo2_export_src (db, "com/LO2/export_source") + : experts::worker_node_t("twinrx_lo_config_expert") + , _lo_source_ch0(db, prepend_ch("los/all/source", "0")) + , _lo_source_ch1(db, prepend_ch("los/all/source", "1")) + , _lo_export_ch0(db, prepend_ch("los/all/export", "0")) + , _lo_export_ch1(db, prepend_ch("los/all/export", "1")) + , _lo1_src_ch0(db, prepend_ch("ch/LO1/source", "0")) + , _lo1_src_ch1(db, prepend_ch("ch/LO1/source", "1")) + , _lo2_src_ch0(db, prepend_ch("ch/LO2/source", "0")) + , _lo2_src_ch1(db, prepend_ch("ch/LO2/source", "1")) + , _lo1_export_src(db, "com/LO1/export_source") + , _lo2_export_src(db, "com/LO2/export_source") { bind_accessor(_lo_source_ch0); bind_accessor(_lo_source_ch1); @@ -175,16 +191,16 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<std::string> _lo_source_ch0; - experts::data_reader_t<std::string> _lo_source_ch1; - experts::data_reader_t<bool> _lo_export_ch0; - experts::data_reader_t<bool> _lo_export_ch1; - //Outputs - experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo1_src_ch0; - experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo1_src_ch1; - experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo2_src_ch0; - experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo2_src_ch1; + // Inputs + experts::data_reader_t<std::string> _lo_source_ch0; + experts::data_reader_t<std::string> _lo_source_ch1; + experts::data_reader_t<bool> _lo_export_ch0; + experts::data_reader_t<bool> _lo_export_ch1; + // Outputs + experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo1_src_ch0; + experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo1_src_ch1; + experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo2_src_ch0; + experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo2_src_ch1; experts::data_writer_t<twinrx_ctrl::lo_export_source_t> _lo1_export_src; experts::data_writer_t<twinrx_ctrl::lo_export_source_t> _lo2_export_src; }; @@ -201,15 +217,20 @@ private: * One instance of this expert is required for each LO stage * --------------------------------------------------------- */ -class twinrx_lo_mapping_expert : public experts::worker_node_t { +class twinrx_lo_mapping_expert : public experts::worker_node_t +{ public: twinrx_lo_mapping_expert(const experts::node_retriever_t& db, lo_stage_t stage) - : experts::worker_node_t("twinrx_" + lo_stage_str(stage, true) + "_mapping_expert"), - _lox_src_ch0 (db, prepend_ch("ch/" + lo_stage_str(stage) + "/source", "0")), - _lox_src_ch1 (db, prepend_ch("ch/" + lo_stage_str(stage) + "/source", "1")), - _lox_mapping_synth0 (db, prepend_ch("synth/" + lo_stage_str(stage) + "/mapping", "0")), - _lox_mapping_synth1 (db, prepend_ch("synth/" + lo_stage_str(stage) + "/mapping", "1")), - _lox_hopping_enabled (db, "com/synth/" + lo_stage_str(stage) + "/hopping_enabled") + : experts::worker_node_t( + "twinrx_" + lo_stage_str(stage, true) + "_mapping_expert") + , _lox_src_ch0(db, prepend_ch("ch/" + lo_stage_str(stage) + "/source", "0")) + , _lox_src_ch1(db, prepend_ch("ch/" + lo_stage_str(stage) + "/source", "1")) + , _lox_mapping_synth0( + db, prepend_ch("synth/" + lo_stage_str(stage) + "/mapping", "0")) + , _lox_mapping_synth1( + db, prepend_ch("synth/" + lo_stage_str(stage) + "/mapping", "1")) + , _lox_hopping_enabled( + db, "com/synth/" + lo_stage_str(stage) + "/hopping_enabled") { bind_accessor(_lox_src_ch0); bind_accessor(_lox_src_ch1); @@ -221,13 +242,13 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<twinrx_ctrl::lo_source_t> _lox_src_ch0; - experts::data_reader_t<twinrx_ctrl::lo_source_t> _lox_src_ch1; - //Outputs - experts::data_writer_t<lo_synth_mapping_t> _lox_mapping_synth0; - experts::data_writer_t<lo_synth_mapping_t> _lox_mapping_synth1; - experts::data_writer_t<bool> _lox_hopping_enabled; + // Inputs + experts::data_reader_t<twinrx_ctrl::lo_source_t> _lox_src_ch0; + experts::data_reader_t<twinrx_ctrl::lo_source_t> _lox_src_ch1; + // Outputs + experts::data_writer_t<lo_synth_mapping_t> _lox_mapping_synth0; + experts::data_writer_t<lo_synth_mapping_t> _lox_mapping_synth1; + experts::data_writer_t<bool> _lox_hopping_enabled; }; /*!--------------------------------------------------------- @@ -240,16 +261,17 @@ private: * One instance of this expert is required for each channel * --------------------------------------------------------- */ -class twinrx_freq_coercion_expert : public experts::worker_node_t { +class twinrx_freq_coercion_expert : public experts::worker_node_t +{ public: twinrx_freq_coercion_expert(const experts::node_retriever_t& db, std::string ch) - : experts::worker_node_t(prepend_ch("twinrx_freq_coercion_expert", ch)), - _lo1_freq_c (db, prepend_ch("los/LO1/freq/coerced", ch)), - _lo2_freq_c (db, prepend_ch("los/LO2/freq/coerced", ch)), - _if_freq_d (db, prepend_ch("if_freq/desired", ch)), - _lo1_inj_side (db, prepend_ch("ch/LO1/inj_side", ch)), - _lo2_inj_side (db, prepend_ch("ch/LO2/inj_side", ch)), - _rf_freq_c (db, prepend_ch("freq/coerced", ch)) + : experts::worker_node_t(prepend_ch("twinrx_freq_coercion_expert", ch)) + , _lo1_freq_c(db, prepend_ch("los/LO1/freq/coerced", ch)) + , _lo2_freq_c(db, prepend_ch("los/LO2/freq/coerced", ch)) + , _if_freq_d(db, prepend_ch("if_freq/desired", ch)) + , _lo1_inj_side(db, prepend_ch("ch/LO1/inj_side", ch)) + , _lo2_inj_side(db, prepend_ch("ch/LO2/inj_side", ch)) + , _rf_freq_c(db, prepend_ch("freq/coerced", ch)) { bind_accessor(_lo1_freq_c); bind_accessor(_lo2_freq_c); @@ -262,14 +284,14 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<double> _lo1_freq_c; - experts::data_reader_t<double> _lo2_freq_c; - experts::data_reader_t<double> _if_freq_d; - experts::data_reader_t<lo_inj_side_t> _lo1_inj_side; - experts::data_reader_t<lo_inj_side_t> _lo2_inj_side; - //Outputs - experts::data_writer_t<double> _rf_freq_c; + // Inputs + experts::data_reader_t<double> _lo1_freq_c; + experts::data_reader_t<double> _lo2_freq_c; + experts::data_reader_t<double> _if_freq_d; + experts::data_reader_t<lo_inj_side_t> _lo1_inj_side; + experts::data_reader_t<lo_inj_side_t> _lo2_inj_side; + // Outputs + experts::data_writer_t<double> _rf_freq_c; }; /*!--------------------------------------------------------- @@ -281,21 +303,23 @@ private: * One instance of this expert is required for each channel * --------------------------------------------------------- */ -class twinrx_nyquist_expert : public experts::worker_node_t { +class twinrx_nyquist_expert : public experts::worker_node_t +{ public: - twinrx_nyquist_expert(const experts::node_retriever_t& db, std::string ch, - dboard_iface::sptr db_iface) - : experts::worker_node_t(prepend_ch("twinrx_nyquist_expert", ch)), - _channel (ch), - _codec_conn (ch=="0"?"II":"QQ"), //Ch->ADC Port mapping - _lo1_freq_d (db, prepend_ch("los/LO1/freq/desired", ch)), - _lo2_freq_d (db, prepend_ch("los/LO2/freq/desired", ch)), - _if_freq_d (db, prepend_ch("if_freq/desired", ch)), - _lo1_inj_side (db, prepend_ch("ch/LO1/inj_side", ch)), - _lo2_inj_side (db, prepend_ch("ch/LO2/inj_side", ch)), - _rx_frontend_time (db, prepend_ch("time/rx_frontend", ch)), - _if_freq_c (db, prepend_ch("if_freq/coerced", ch)), - _db_iface (db_iface) + twinrx_nyquist_expert( + const experts::node_retriever_t& db, std::string ch, dboard_iface::sptr db_iface) + : experts::worker_node_t(prepend_ch("twinrx_nyquist_expert", ch)) + , _channel(ch) + , _codec_conn(ch == "0" ? "II" : "QQ") + , // Ch->ADC Port mapping + _lo1_freq_d(db, prepend_ch("los/LO1/freq/desired", ch)) + , _lo2_freq_d(db, prepend_ch("los/LO2/freq/desired", ch)) + , _if_freq_d(db, prepend_ch("if_freq/desired", ch)) + , _lo1_inj_side(db, prepend_ch("ch/LO1/inj_side", ch)) + , _lo2_inj_side(db, prepend_ch("ch/LO2/inj_side", ch)) + , _rx_frontend_time(db, prepend_ch("time/rx_frontend", ch)) + , _if_freq_c(db, prepend_ch("if_freq/coerced", ch)) + , _db_iface(db_iface) { bind_accessor(_lo1_freq_d); bind_accessor(_lo2_freq_d); @@ -309,22 +333,22 @@ public: private: virtual void resolve(); - //Inputs - const std::string _channel; - const std::string _codec_conn; - experts::data_reader_t<double> _lo1_freq_d; - experts::data_reader_t<double> _lo2_freq_d; - experts::data_reader_t<double> _if_freq_d; - experts::data_reader_t<lo_inj_side_t> _lo1_inj_side; - experts::data_reader_t<lo_inj_side_t> _lo2_inj_side; - experts::data_reader_t<time_spec_t> _rx_frontend_time; - - //Outputs - experts::data_writer_t<double> _if_freq_c; - dboard_iface::sptr _db_iface; - - //Misc - time_spec_t _cached_cmd_time; + // Inputs + const std::string _channel; + const std::string _codec_conn; + experts::data_reader_t<double> _lo1_freq_d; + experts::data_reader_t<double> _lo2_freq_d; + experts::data_reader_t<double> _if_freq_d; + experts::data_reader_t<lo_inj_side_t> _lo1_inj_side; + experts::data_reader_t<lo_inj_side_t> _lo2_inj_side; + experts::data_reader_t<time_spec_t> _rx_frontend_time; + + // Outputs + experts::data_writer_t<double> _if_freq_c; + dboard_iface::sptr _db_iface; + + // Misc + time_spec_t _cached_cmd_time; }; /*!--------------------------------------------------------- @@ -337,18 +361,19 @@ private: * One instance of this expert is required for all channels * --------------------------------------------------------- */ -class twinrx_antenna_expert : public experts::worker_node_t { +class twinrx_antenna_expert : public experts::worker_node_t +{ public: twinrx_antenna_expert(const experts::node_retriever_t& db) - : experts::worker_node_t("twinrx_antenna_expert"), - _antenna_ch0 (db, prepend_ch("antenna", "0")), - _antenna_ch1 (db, prepend_ch("antenna", "1")), - _enabled_ch0 (db, prepend_ch("enabled", "0")), - _enabled_ch1 (db, prepend_ch("enabled", "1")), - _lo_export_ch0 (db, prepend_ch("los/all/export", "0")), - _lo_export_ch1 (db, prepend_ch("los/all/export", "1")), - _ant_mapping (db, "com/ant_mapping"), - _cal_mode (db, "com/cal_mode") + : experts::worker_node_t("twinrx_antenna_expert") + , _antenna_ch0(db, prepend_ch("antenna", "0")) + , _antenna_ch1(db, prepend_ch("antenna", "1")) + , _enabled_ch0(db, prepend_ch("enabled", "0")) + , _enabled_ch1(db, prepend_ch("enabled", "1")) + , _lo_export_ch0(db, prepend_ch("los/all/export", "0")) + , _lo_export_ch1(db, prepend_ch("los/all/export", "1")) + , _ant_mapping(db, "com/ant_mapping") + , _cal_mode(db, "com/cal_mode") { bind_accessor(_antenna_ch0); bind_accessor(_antenna_ch1); @@ -363,16 +388,16 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<std::string> _antenna_ch0; - experts::data_reader_t<std::string> _antenna_ch1; - experts::data_reader_t<bool> _enabled_ch0; - experts::data_reader_t<bool> _enabled_ch1; - experts::data_reader_t<bool> _lo_export_ch0; - experts::data_reader_t<bool> _lo_export_ch1; - //Outputs - experts::data_writer_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; - experts::data_writer_t<twinrx_ctrl::cal_mode_t> _cal_mode; + // Inputs + experts::data_reader_t<std::string> _antenna_ch0; + experts::data_reader_t<std::string> _antenna_ch1; + experts::data_reader_t<bool> _enabled_ch0; + experts::data_reader_t<bool> _enabled_ch1; + experts::data_reader_t<bool> _lo_export_ch0; + experts::data_reader_t<bool> _lo_export_ch1; + // Outputs + experts::data_writer_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; + experts::data_writer_t<twinrx_ctrl::cal_mode_t> _cal_mode; }; /*!--------------------------------------------------------- @@ -386,21 +411,22 @@ private: * One instance of this expert is required for each channel * --------------------------------------------------------- */ -class twinrx_chan_gain_expert : public experts::worker_node_t { +class twinrx_chan_gain_expert : public experts::worker_node_t +{ public: twinrx_chan_gain_expert(const experts::node_retriever_t& db, std::string ch) - : experts::worker_node_t(prepend_ch("twinrx_chan_gain_expert", ch)), - _gain (db, prepend_ch("gain", ch)), - _gain_profile (db, prepend_ch("gain_profile", ch)), - _signal_path (db, prepend_ch("ch/signal_path", ch)), - _lb_presel (db, prepend_ch("ch/lb_presel", ch)), - _hb_presel (db, prepend_ch("ch/hb_presel", ch)), - _ant_mapping (db, "com/ant_mapping"), - _input_atten (db, prepend_ch("ch/input_atten", ch)), - _lb_atten (db, prepend_ch("ch/lb_atten", ch)), - _hb_atten (db, prepend_ch("ch/hb_atten", ch)), - _preamp1 (db, prepend_ch("ch/preamp1", ch)), - _preamp2 (db, prepend_ch("ch/preamp2", ch)) + : experts::worker_node_t(prepend_ch("twinrx_chan_gain_expert", ch)) + , _gain(db, prepend_ch("gain", ch)) + , _gain_profile(db, prepend_ch("gain_profile", ch)) + , _signal_path(db, prepend_ch("ch/signal_path", ch)) + , _lb_presel(db, prepend_ch("ch/lb_presel", ch)) + , _hb_presel(db, prepend_ch("ch/hb_presel", ch)) + , _ant_mapping(db, "com/ant_mapping") + , _input_atten(db, prepend_ch("ch/input_atten", ch)) + , _lb_atten(db, prepend_ch("ch/lb_atten", ch)) + , _hb_atten(db, prepend_ch("ch/hb_atten", ch)) + , _preamp1(db, prepend_ch("ch/preamp1", ch)) + , _preamp2(db, prepend_ch("ch/preamp2", ch)) { bind_accessor(_gain); bind_accessor(_gain_profile); @@ -418,19 +444,19 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<double> _gain; - experts::data_reader_t<std::string> _gain_profile; - experts::data_reader_t<twinrx_ctrl::signal_path_t> _signal_path; + // Inputs + experts::data_reader_t<double> _gain; + experts::data_reader_t<std::string> _gain_profile; + experts::data_reader_t<twinrx_ctrl::signal_path_t> _signal_path; experts::data_reader_t<twinrx_ctrl::preselector_path_t> _lb_presel; experts::data_reader_t<twinrx_ctrl::preselector_path_t> _hb_presel; - experts::data_reader_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; - //Outputs - experts::data_writer_t<uint8_t> _input_atten; - experts::data_writer_t<uint8_t> _lb_atten; - experts::data_writer_t<uint8_t> _hb_atten; - experts::data_writer_t<twinrx_ctrl::preamp_state_t> _preamp1; - experts::data_writer_t<bool> _preamp2; + experts::data_reader_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; + // Outputs + experts::data_writer_t<uint8_t> _input_atten; + experts::data_writer_t<uint8_t> _lb_atten; + experts::data_writer_t<uint8_t> _hb_atten; + experts::data_writer_t<twinrx_ctrl::preamp_state_t> _preamp1; + experts::data_writer_t<bool> _preamp2; }; /*!--------------------------------------------------------- @@ -443,27 +469,28 @@ private: * One instance of this expert is required for all channels * --------------------------------------------------------- */ -class twinrx_ant_gain_expert : public experts::worker_node_t { +class twinrx_ant_gain_expert : public experts::worker_node_t +{ public: twinrx_ant_gain_expert(const experts::node_retriever_t& db) - : experts::worker_node_t("twinrx_ant_gain_expert"), - _ant_mapping (db, "com/ant_mapping"), - _ch0_input_atten (db, prepend_ch("ch/input_atten", "0")), - _ch0_preamp1 (db, prepend_ch("ch/preamp1", "0")), - _ch0_preamp2 (db, prepend_ch("ch/preamp2", "0")), - _ch0_lb_preamp_presel (db, prepend_ch("ch/lb_preamp_presel", "0")), - _ch1_input_atten (db, prepend_ch("ch/input_atten", "1")), - _ch1_preamp1 (db, prepend_ch("ch/preamp1", "1")), - _ch1_preamp2 (db, prepend_ch("ch/preamp2", "1")), - _ch1_lb_preamp_presel (db, prepend_ch("ch/lb_preamp_presel", "1")), - _ant0_input_atten (db, prepend_ch("ant/input_atten", "0")), - _ant0_preamp1 (db, prepend_ch("ant/preamp1", "0")), - _ant0_preamp2 (db, prepend_ch("ant/preamp2", "0")), - _ant0_lb_preamp_presel(db, prepend_ch("ant/lb_preamp_presel", "0")), - _ant1_input_atten (db, prepend_ch("ant/input_atten", "1")), - _ant1_preamp1 (db, prepend_ch("ant/preamp1", "1")), - _ant1_preamp2 (db, prepend_ch("ant/preamp2", "1")), - _ant1_lb_preamp_presel(db, prepend_ch("ant/lb_preamp_presel", "1")) + : experts::worker_node_t("twinrx_ant_gain_expert") + , _ant_mapping(db, "com/ant_mapping") + , _ch0_input_atten(db, prepend_ch("ch/input_atten", "0")) + , _ch0_preamp1(db, prepend_ch("ch/preamp1", "0")) + , _ch0_preamp2(db, prepend_ch("ch/preamp2", "0")) + , _ch0_lb_preamp_presel(db, prepend_ch("ch/lb_preamp_presel", "0")) + , _ch1_input_atten(db, prepend_ch("ch/input_atten", "1")) + , _ch1_preamp1(db, prepend_ch("ch/preamp1", "1")) + , _ch1_preamp2(db, prepend_ch("ch/preamp2", "1")) + , _ch1_lb_preamp_presel(db, prepend_ch("ch/lb_preamp_presel", "1")) + , _ant0_input_atten(db, prepend_ch("ant/input_atten", "0")) + , _ant0_preamp1(db, prepend_ch("ant/preamp1", "0")) + , _ant0_preamp2(db, prepend_ch("ant/preamp2", "0")) + , _ant0_lb_preamp_presel(db, prepend_ch("ant/lb_preamp_presel", "0")) + , _ant1_input_atten(db, prepend_ch("ant/input_atten", "1")) + , _ant1_preamp1(db, prepend_ch("ant/preamp1", "1")) + , _ant1_preamp2(db, prepend_ch("ant/preamp2", "1")) + , _ant1_lb_preamp_presel(db, prepend_ch("ant/lb_preamp_presel", "1")) { bind_accessor(_ant_mapping); bind_accessor(_ch0_input_atten); @@ -487,26 +514,26 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; - experts::data_reader_t<uint8_t> _ch0_input_atten; - experts::data_reader_t<twinrx_ctrl::preamp_state_t> _ch0_preamp1; - experts::data_reader_t<bool> _ch0_preamp2; - experts::data_reader_t<bool> _ch0_lb_preamp_presel; - experts::data_reader_t<uint8_t> _ch1_input_atten; - experts::data_reader_t<twinrx_ctrl::preamp_state_t> _ch1_preamp1; - experts::data_reader_t<bool> _ch1_preamp2; - experts::data_reader_t<bool> _ch1_lb_preamp_presel; - - //Outputs - experts::data_writer_t<uint8_t> _ant0_input_atten; - experts::data_writer_t<twinrx_ctrl::preamp_state_t> _ant0_preamp1; - experts::data_writer_t<bool> _ant0_preamp2; - experts::data_writer_t<bool> _ant0_lb_preamp_presel; - experts::data_writer_t<uint8_t> _ant1_input_atten; - experts::data_writer_t<twinrx_ctrl::preamp_state_t> _ant1_preamp1; - experts::data_writer_t<bool> _ant1_preamp2; - experts::data_writer_t<bool> _ant1_lb_preamp_presel; + // Inputs + experts::data_reader_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; + experts::data_reader_t<uint8_t> _ch0_input_atten; + experts::data_reader_t<twinrx_ctrl::preamp_state_t> _ch0_preamp1; + experts::data_reader_t<bool> _ch0_preamp2; + experts::data_reader_t<bool> _ch0_lb_preamp_presel; + experts::data_reader_t<uint8_t> _ch1_input_atten; + experts::data_reader_t<twinrx_ctrl::preamp_state_t> _ch1_preamp1; + experts::data_reader_t<bool> _ch1_preamp2; + experts::data_reader_t<bool> _ch1_lb_preamp_presel; + + // Outputs + experts::data_writer_t<uint8_t> _ant0_input_atten; + experts::data_writer_t<twinrx_ctrl::preamp_state_t> _ant0_preamp1; + experts::data_writer_t<bool> _ant0_preamp2; + experts::data_writer_t<bool> _ant0_lb_preamp_presel; + experts::data_writer_t<uint8_t> _ant1_input_atten; + experts::data_writer_t<twinrx_ctrl::preamp_state_t> _ant1_preamp1; + experts::data_writer_t<bool> _ant1_preamp2; + experts::data_writer_t<bool> _ant1_lb_preamp_presel; }; /*!--------------------------------------------------------- @@ -521,25 +548,27 @@ private: * One instance of this expert is required for all channels * --------------------------------------------------------- */ -class twinrx_settings_expert : public experts::worker_node_t { +class twinrx_settings_expert : public experts::worker_node_t +{ public: twinrx_settings_expert(const experts::node_retriever_t& db, twinrx_ctrl::sptr ctrl) - : experts::worker_node_t("twinrx_settings_expert"), _ctrl(ctrl), - _ch0 (db, "0"), - _ch1 (db, "1"), - _lo1_synth0_mapping(db, "0/synth/LO1/mapping"), - _lo1_synth1_mapping(db, "1/synth/LO1/mapping"), - _lo2_synth0_mapping(db, "0/synth/LO2/mapping"), - _lo2_synth1_mapping(db, "1/synth/LO2/mapping"), - _lo1_hopping_enabled(db, "com/synth/LO1/hopping_enabled"), - _lo2_hopping_enabled(db, "com/synth/LO2/hopping_enabled"), - _lo1_export_src (db, "com/LO1/export_source"), - _lo2_export_src (db, "com/LO2/export_source"), - _ant_mapping (db, "com/ant_mapping"), - _cal_mode (db, "com/cal_mode") + : experts::worker_node_t("twinrx_settings_expert") + , _ctrl(ctrl) + , _ch0(db, "0") + , _ch1(db, "1") + , _lo1_synth0_mapping(db, "0/synth/LO1/mapping") + , _lo1_synth1_mapping(db, "1/synth/LO1/mapping") + , _lo2_synth0_mapping(db, "0/synth/LO2/mapping") + , _lo2_synth1_mapping(db, "1/synth/LO2/mapping") + , _lo1_hopping_enabled(db, "com/synth/LO1/hopping_enabled") + , _lo2_hopping_enabled(db, "com/synth/LO2/hopping_enabled") + , _lo1_export_src(db, "com/LO1/export_source") + , _lo2_export_src(db, "com/LO2/export_source") + , _ant_mapping(db, "com/ant_mapping") + , _cal_mode(db, "com/cal_mode") { for (size_t i = 0; i < 2; i++) { - ch_settings& ch = (i==1) ? _ch1 : _ch0; + ch_settings& ch = (i == 1) ? _ch1 : _ch0; bind_accessor(ch.chan_enabled); bind_accessor(ch.preamp1); bind_accessor(ch.preamp2); @@ -575,103 +604,105 @@ public: private: virtual void resolve(); - void _resolve_lox_freq( - lo_stage_t lo_stage, + void _resolve_lox_freq(lo_stage_t lo_stage, experts::data_reader_t<double>& ch0_freq_d, experts::data_reader_t<double>& ch1_freq_d, experts::data_writer_t<double>& ch0_freq_c, experts::data_writer_t<double>& ch1_freq_c, - twinrx_ctrl::lo_source_t ch0_lo_source, - twinrx_ctrl::lo_source_t ch1_lo_source, - lo_synth_mapping_t synth0_mapping, - lo_synth_mapping_t synth1_mapping, - bool hopping_enabled); + twinrx_ctrl::lo_source_t ch0_lo_source, + twinrx_ctrl::lo_source_t ch1_lo_source, + lo_synth_mapping_t synth0_mapping, + lo_synth_mapping_t synth1_mapping, + bool hopping_enabled); double _set_lox_synth_freq(lo_stage_t stage, twinrx_ctrl::channel_t ch, double freq); - class ch_settings { + class ch_settings + { public: - ch_settings(const experts::node_retriever_t& db, const std::string& ch) : - chan_enabled (db, prepend_ch("enabled", ch)), - preamp1 (db, prepend_ch("ant/preamp1", ch)), - preamp2 (db, prepend_ch("ant/preamp2", ch)), - lb_preamp_presel (db, prepend_ch("ant/lb_preamp_presel", ch)), - signal_path (db, prepend_ch("ch/signal_path", ch)), - lb_presel (db, prepend_ch("ch/lb_presel", ch)), - hb_presel (db, prepend_ch("ch/hb_presel", ch)), - input_atten (db, prepend_ch("ant/input_atten", ch)), - lb_atten (db, prepend_ch("ch/lb_atten", ch)), - hb_atten (db, prepend_ch("ch/hb_atten", ch)), - lo1_source (db, prepend_ch("ch/LO1/source", ch)), - lo2_source (db, prepend_ch("ch/LO2/source", ch)), - lo1_freq_d (db, prepend_ch("los/LO1/freq/desired", ch)), - lo2_freq_d (db, prepend_ch("los/LO2/freq/desired", ch)), - lo1_charge_pump_d (db, prepend_ch("los/LO1/charge_pump/desired", ch)), - lo2_charge_pump_d (db, prepend_ch("los/LO2/charge_pump/desired", ch)), - lo1_freq_c (db, prepend_ch("los/LO1/freq/coerced", ch)), - lo2_freq_c (db, prepend_ch("los/LO2/freq/coerced", ch)), - lo1_charge_pump_c (db, prepend_ch("los/LO1/charge_pump/coerced", ch)), - lo2_charge_pump_c (db, prepend_ch("los/LO2/charge_pump/coerced", ch)) - {} - - //Inputs (channel specific) - experts::data_reader_t<bool> chan_enabled; - experts::data_reader_t<twinrx_ctrl::preamp_state_t> preamp1; - experts::data_reader_t<bool> preamp2; - experts::data_reader_t<bool> lb_preamp_presel; - experts::data_reader_t<twinrx_ctrl::signal_path_t> signal_path; + ch_settings(const experts::node_retriever_t& db, const std::string& ch) + : chan_enabled(db, prepend_ch("enabled", ch)) + , preamp1(db, prepend_ch("ant/preamp1", ch)) + , preamp2(db, prepend_ch("ant/preamp2", ch)) + , lb_preamp_presel(db, prepend_ch("ant/lb_preamp_presel", ch)) + , signal_path(db, prepend_ch("ch/signal_path", ch)) + , lb_presel(db, prepend_ch("ch/lb_presel", ch)) + , hb_presel(db, prepend_ch("ch/hb_presel", ch)) + , input_atten(db, prepend_ch("ant/input_atten", ch)) + , lb_atten(db, prepend_ch("ch/lb_atten", ch)) + , hb_atten(db, prepend_ch("ch/hb_atten", ch)) + , lo1_source(db, prepend_ch("ch/LO1/source", ch)) + , lo2_source(db, prepend_ch("ch/LO2/source", ch)) + , lo1_freq_d(db, prepend_ch("los/LO1/freq/desired", ch)) + , lo2_freq_d(db, prepend_ch("los/LO2/freq/desired", ch)) + , lo1_charge_pump_d(db, prepend_ch("los/LO1/charge_pump/desired", ch)) + , lo2_charge_pump_d(db, prepend_ch("los/LO2/charge_pump/desired", ch)) + , lo1_freq_c(db, prepend_ch("los/LO1/freq/coerced", ch)) + , lo2_freq_c(db, prepend_ch("los/LO2/freq/coerced", ch)) + , lo1_charge_pump_c(db, prepend_ch("los/LO1/charge_pump/coerced", ch)) + , lo2_charge_pump_c(db, prepend_ch("los/LO2/charge_pump/coerced", ch)) + { + } + + // Inputs (channel specific) + experts::data_reader_t<bool> chan_enabled; + experts::data_reader_t<twinrx_ctrl::preamp_state_t> preamp1; + experts::data_reader_t<bool> preamp2; + experts::data_reader_t<bool> lb_preamp_presel; + experts::data_reader_t<twinrx_ctrl::signal_path_t> signal_path; experts::data_reader_t<twinrx_ctrl::preselector_path_t> lb_presel; experts::data_reader_t<twinrx_ctrl::preselector_path_t> hb_presel; - experts::data_reader_t<uint8_t> input_atten; - experts::data_reader_t<uint8_t> lb_atten; - experts::data_reader_t<uint8_t> hb_atten; - experts::data_reader_t<twinrx_ctrl::lo_source_t> lo1_source; - experts::data_reader_t<twinrx_ctrl::lo_source_t> lo2_source; - experts::data_reader_t<double> lo1_freq_d; - experts::data_reader_t<double> lo2_freq_d; - experts::data_reader_t<double> lo1_charge_pump_d; - experts::data_reader_t<double> lo2_charge_pump_d; - - //Output (channel specific) - experts::data_writer_t<double> lo1_freq_c; - experts::data_writer_t<double> lo2_freq_c; - experts::data_writer_t<double> lo1_charge_pump_c; - experts::data_writer_t<double> lo2_charge_pump_c; + experts::data_reader_t<uint8_t> input_atten; + experts::data_reader_t<uint8_t> lb_atten; + experts::data_reader_t<uint8_t> hb_atten; + experts::data_reader_t<twinrx_ctrl::lo_source_t> lo1_source; + experts::data_reader_t<twinrx_ctrl::lo_source_t> lo2_source; + experts::data_reader_t<double> lo1_freq_d; + experts::data_reader_t<double> lo2_freq_d; + experts::data_reader_t<double> lo1_charge_pump_d; + experts::data_reader_t<double> lo2_charge_pump_d; + + // Output (channel specific) + experts::data_writer_t<double> lo1_freq_c; + experts::data_writer_t<double> lo2_freq_c; + experts::data_writer_t<double> lo1_charge_pump_c; + experts::data_writer_t<double> lo2_charge_pump_c; }; - //External interface - twinrx_ctrl::sptr _ctrl; - - //Inputs (channel agnostic) - ch_settings _ch0; - ch_settings _ch1; - experts::data_reader_t<lo_synth_mapping_t> _lo1_synth0_mapping; - experts::data_reader_t<lo_synth_mapping_t> _lo1_synth1_mapping; - experts::data_reader_t<lo_synth_mapping_t> _lo2_synth0_mapping; - experts::data_reader_t<lo_synth_mapping_t> _lo2_synth1_mapping; - experts::data_reader_t<bool> _lo1_hopping_enabled; - experts::data_reader_t<bool> _lo2_hopping_enabled; + // External interface + twinrx_ctrl::sptr _ctrl; + + // Inputs (channel agnostic) + ch_settings _ch0; + ch_settings _ch1; + experts::data_reader_t<lo_synth_mapping_t> _lo1_synth0_mapping; + experts::data_reader_t<lo_synth_mapping_t> _lo1_synth1_mapping; + experts::data_reader_t<lo_synth_mapping_t> _lo2_synth0_mapping; + experts::data_reader_t<lo_synth_mapping_t> _lo2_synth1_mapping; + experts::data_reader_t<bool> _lo1_hopping_enabled; + experts::data_reader_t<bool> _lo2_hopping_enabled; experts::data_reader_t<twinrx_ctrl::lo_export_source_t> _lo1_export_src; experts::data_reader_t<twinrx_ctrl::lo_export_source_t> _lo2_export_src; - experts::data_reader_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; - experts::data_reader_t<twinrx_ctrl::cal_mode_t> _cal_mode; + experts::data_reader_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; + experts::data_reader_t<twinrx_ctrl::cal_mode_t> _cal_mode; - //Outputs (channel agnostic) - //None + // Outputs (channel agnostic) + // None - //Misc - struct lo_freq_cache_t { + // Misc + struct lo_freq_cache_t + { rf_freq_ppm_t desired; - double coerced; + double coerced; }; - lo_freq_cache_t _cached_lo1_synth0_freq; - lo_freq_cache_t _cached_lo2_synth0_freq; - lo_freq_cache_t _cached_lo1_synth1_freq; - lo_freq_cache_t _cached_lo2_synth1_freq; + lo_freq_cache_t _cached_lo1_synth0_freq; + lo_freq_cache_t _cached_lo2_synth0_freq; + lo_freq_cache_t _cached_lo1_synth1_freq; + lo_freq_cache_t _cached_lo2_synth1_freq; static const bool FORCE_COMMIT; }; -}}}} //namespaces +}}}} // namespace uhd::usrp::dboard::twinrx #endif /* INCLUDED_DBOARD_TWINRX_EXPERTS_HPP */ diff --git a/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.cpp b/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.cpp index cc9336f2a..729141b35 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.cpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.cpp @@ -796,13 +796,11 @@ static const std::vector<twinrx_gain_config_t> LOWBAND4_TABLE{ }; // clang-format on -const twinrx_gain_table twinrx_gain_table::lookup_table -( +const twinrx_gain_table twinrx_gain_table::lookup_table( twinrx_ctrl::signal_path_t signal_path, twinrx_ctrl::preselector_path_t preselector_path, - std::string -) { - + std::string) +{ if (signal_path == twinrx_ctrl::PATH_HIGHBAND) { switch (preselector_path) { case twinrx_ctrl::PRESEL_PATH1: @@ -829,12 +827,15 @@ const twinrx_gain_table twinrx_gain_table::lookup_table throw runtime_error("NO GAIN TABLE SELECTED"); } -const twinrx_gain_config_t& twinrx_gain_table::find_by_index(size_t index) const { - if (index >= get_num_entries()) throw uhd::value_error("invalid gain table index"); +const twinrx_gain_config_t& twinrx_gain_table::find_by_index(size_t index) const +{ + if (index >= get_num_entries()) + throw uhd::value_error("invalid gain table index"); return _tbl.at(index); } -uhd::gain_range_t twinrx_gain_table::get_gain_range() const { +uhd::gain_range_t twinrx_gain_table::get_gain_range() const +{ double max = std::numeric_limits<double>::min(); double min = std::numeric_limits<double>::max(); for (size_t i = 0; i < get_num_entries(); i++) { diff --git a/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.hpp b/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.hpp index 94469ab0b..f02241745 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.hpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.hpp @@ -8,56 +8,65 @@ #ifndef INCLUDED_DBOARD_TWINRX_GAIN_TABLES_HPP #define INCLUDED_DBOARD_TWINRX_GAIN_TABLES_HPP +#include "twinrx_ctrl.hpp" #include <uhd/config.hpp> -#include <stdint.h> #include <uhd/types/ranges.hpp> -#include "twinrx_ctrl.hpp" +#include <stdint.h> namespace uhd { namespace usrp { namespace dboard { namespace twinrx { -class twinrx_gain_config_t { +class twinrx_gain_config_t +{ public: - twinrx_gain_config_t( - size_t index_, double sys_gain_, - uint8_t atten1_, uint8_t atten2_, - bool amp1_, bool amp2_ - ): index(index_), sys_gain(sys_gain_), atten1(atten1_), atten2(atten2_), - amp1(amp1_), amp2(amp2_) - {} + twinrx_gain_config_t(size_t index_, + double sys_gain_, + uint8_t atten1_, + uint8_t atten2_, + bool amp1_, + bool amp2_) + : index(index_) + , sys_gain(sys_gain_) + , atten1(atten1_) + , atten2(atten2_) + , amp1(amp1_) + , amp2(amp2_) + { + } - twinrx_gain_config_t& operator=(const twinrx_gain_config_t& src) { + twinrx_gain_config_t& operator=(const twinrx_gain_config_t& src) + { if (this != &src) { - this->index = src.index; + this->index = src.index; this->sys_gain = src.sys_gain; - this->atten1 = src.atten1; - this->atten2 = src.atten2; - this->amp1 = src.amp1; - this->amp2 = src.amp2; + this->atten1 = src.atten1; + this->atten2 = src.atten2; + this->amp1 = src.amp1; + this->amp2 = src.amp2; } return *this; } - size_t index; - double sys_gain; + size_t index; + double sys_gain; uint8_t atten1; uint8_t atten2; - bool amp1; - bool amp2; + bool amp1; + bool amp2; }; -class twinrx_gain_table { +class twinrx_gain_table +{ public: - static const twinrx_gain_table lookup_table( - twinrx_ctrl::signal_path_t signal_path, + static const twinrx_gain_table lookup_table(twinrx_ctrl::signal_path_t signal_path, twinrx_ctrl::preselector_path_t presel_path, std::string profile); - twinrx_gain_table(const std::vector<twinrx_gain_config_t>& tbl) - : _tbl(tbl) {} + twinrx_gain_table(const std::vector<twinrx_gain_config_t>& tbl) : _tbl(tbl) {} const twinrx_gain_config_t& find_by_index(size_t index) const; - inline size_t get_num_entries() const { + inline size_t get_num_entries() const + { return _tbl.size(); } @@ -68,6 +77,6 @@ private: }; -}}}} //namespaces +}}}} // namespace uhd::usrp::dboard::twinrx #endif /* INCLUDED_DBOARD_TWINRX_GAIN_TABLES_HPP */ diff --git a/host/lib/usrp/dboard/twinrx/twinrx_ids.hpp b/host/lib/usrp/dboard/twinrx/twinrx_ids.hpp index 599b1d456..118090701 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_ids.hpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_ids.hpp @@ -8,9 +8,9 @@ using namespace uhd; using namespace usrp; namespace twinrx { - const dboard_id_t TWINRX_REV_A_ID(0x91); - const dboard_id_t TWINRX_REV_B_ID(0x93); - const dboard_id_t TWINRX_REV_C_ID(0x95); -} +const dboard_id_t TWINRX_REV_A_ID(0x91); +const dboard_id_t TWINRX_REV_B_ID(0x93); +const dboard_id_t TWINRX_REV_C_ID(0x95); +} // namespace twinrx #endif diff --git a/host/lib/usrp/dboard/twinrx/twinrx_io.hpp b/host/lib/usrp/dboard/twinrx/twinrx_io.hpp index e3e475148..2949138dd 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_io.hpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_io.hpp @@ -19,24 +19,35 @@ namespace uhd { namespace usrp { namespace dboard { namespace twinrx { static const uint32_t SET_ALL_BITS = 0xFFFFFFFF; namespace cpld { -static wb_iface::wb_addr_type addr(uint8_t cpld_num, uint8_t cpld_addr) { - //Decode CPLD addressing for the following bitmap: +static wb_iface::wb_addr_type addr(uint8_t cpld_num, uint8_t cpld_addr) +{ + // Decode CPLD addressing for the following bitmap: // {CPLD1_EN, CPLD2_EN, CPLD3_EN, CPLD4_EN, CPLD_ADDR[2:0]} uint8_t addr = 0; switch (cpld_num) { - case 1: addr = 0x8 << 3; break; - case 2: addr = 0x4 << 3; break; - case 3: addr = 0x2 << 3; break; - case 4: addr = 0x1 << 3; break; - default: UHD_THROW_INVALID_CODE_PATH(); + case 1: + addr = 0x8 << 3; + break; + case 2: + addr = 0x4 << 3; + break; + case 3: + addr = 0x2 << 3; + break; + case 4: + addr = 0x1 << 3; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } return static_cast<wb_iface::wb_addr_type>(addr | (cpld_addr & 0x7)); } -static uint32_t get_reg(wb_iface::wb_addr_type addr) { +static uint32_t get_reg(wb_iface::wb_addr_type addr) +{ return static_cast<uint32_t>(addr) & 0x7; } -} +} // namespace cpld class twinrx_gpio : public wb_iface { @@ -44,163 +55,196 @@ public: typedef std::shared_ptr<twinrx_gpio> sptr; //---------------------------------------------- - //Public GPIO fields - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_CE_CH1, /*width*/ 1, /*shift*/ 0); //GPIO[0] OUT - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_CE_CH2, /*width*/ 1, /*shift*/ 1); //GPIO[1] OUT - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_MUXOUT_CH1, /*width*/ 1, /*shift*/ 2); //GPIO[2] IN - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_MUXOUT_CH2, /*width*/ 1, /*shift*/ 3); //GPIO[3] IN - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_LD_CH1, /*width*/ 1, /*shift*/ 4); //GPIO[4] IN - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_LD_CH2, /*width*/ 1, /*shift*/ 5); //GPIO[5] IN - // NO CONNECT //GPIO[8:6] - // PRIVATE //GPIO[15:9] - // NO CONNECT //GPIO[16] - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO1_CE_CH1, /*width*/ 1, /*shift*/ 17); //GPIO[17] OUT - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO1_CE_CH2, /*width*/ 1, /*shift*/ 18); //GPIO[18] OUT - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO1_MUXOUT_CH1, /*width*/ 1, /*shift*/ 19); //GPIO[19] IN - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO1_MUXOUT_CH2, /*width*/ 1, /*shift*/ 20); //GPIO[20] IN - // NO CONNECT //GPIO[21:23] - UHD_DEFINE_SOFT_REG_FIELD(FIELD_SWPS_CLK, /*width*/ 1, /*shift*/ 24); //GPIO[24] IN - UHD_DEFINE_SOFT_REG_FIELD(FIELD_SWPS_PWR_GOOD, /*width*/ 1, /*shift*/ 25); //GPIO[25] IN - UHD_DEFINE_SOFT_REG_FIELD(FIELD_SWPS_EN, /*width*/ 1, /*shift*/ 26); //GPIO[26] OUT - // PRIVATE //GPIO[27:31] + // Public GPIO fields + UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_CE_CH1, /*width*/ 1, /*shift*/ 0); // GPIO[0] OUT + UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_CE_CH2, /*width*/ 1, /*shift*/ 1); // GPIO[1] OUT + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_LO2_MUXOUT_CH1, /*width*/ 1, /*shift*/ 2); // GPIO[2] IN + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_LO2_MUXOUT_CH2, /*width*/ 1, /*shift*/ 3); // GPIO[3] IN + UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_LD_CH1, /*width*/ 1, /*shift*/ 4); // GPIO[4] IN + UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_LD_CH2, /*width*/ 1, /*shift*/ 5); // GPIO[5] IN + // NO CONNECT //GPIO[8:6] PRIVATE //GPIO[15:9] NO CONNECT //GPIO[16] + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_LO1_CE_CH1, /*width*/ 1, /*shift*/ 17); // GPIO[17] OUT + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_LO1_CE_CH2, /*width*/ 1, /*shift*/ 18); // GPIO[18] OUT + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_LO1_MUXOUT_CH1, /*width*/ 1, /*shift*/ 19); // GPIO[19] IN + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_LO1_MUXOUT_CH2, /*width*/ 1, /*shift*/ 20); // GPIO[20] IN + // NO CONNECT //GPIO[21:23] + UHD_DEFINE_SOFT_REG_FIELD(FIELD_SWPS_CLK, /*width*/ 1, /*shift*/ 24); // GPIO[24] IN + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_SWPS_PWR_GOOD, /*width*/ 1, /*shift*/ 25); // GPIO[25] IN + UHD_DEFINE_SOFT_REG_FIELD(FIELD_SWPS_EN, /*width*/ 1, /*shift*/ 26); // GPIO[26] OUT + // PRIVATE //GPIO[27:31] //---------------------------------------------- - twinrx_gpio(dboard_iface::sptr iface) : _db_iface(iface) { + twinrx_gpio(dboard_iface::sptr iface) : _db_iface(iface) + { _db_iface->set_gpio_ddr(dboard_iface::UNIT_BOTH, GPIO_OUTPUT_MASK, SET_ALL_BITS); _db_iface->set_pin_ctrl(dboard_iface::UNIT_BOTH, GPIO_PINCTRL_MASK, SET_ALL_BITS); _db_iface->set_gpio_out(dboard_iface::UNIT_BOTH, 0, ~GPIO_PINCTRL_MASK); } - ~twinrx_gpio() { + ~twinrx_gpio() + { _db_iface->set_gpio_ddr(dboard_iface::UNIT_BOTH, ~GPIO_OUTPUT_MASK, SET_ALL_BITS); } - void set_field(const uhd::soft_reg_field_t field, const uint32_t value) { + void set_field(const uhd::soft_reg_field_t field, const uint32_t value) + { boost::lock_guard<boost::mutex> lock(_mutex); using namespace soft_reg_field; - _db_iface->set_gpio_out(dboard_iface::UNIT_BOTH, - (value << shift(field)), - mask<uint32_t>(field)); + _db_iface->set_gpio_out( + dboard_iface::UNIT_BOTH, (value << shift(field)), mask<uint32_t>(field)); } - uint32_t get_field(const uhd::soft_reg_field_t field) { + uint32_t get_field(const uhd::soft_reg_field_t field) + { boost::lock_guard<boost::mutex> lock(_mutex); using namespace soft_reg_field; - return (_db_iface->read_gpio(dboard_iface::UNIT_BOTH) & mask<uint32_t>(field)) >> shift(field); + return (_db_iface->read_gpio(dboard_iface::UNIT_BOTH) & mask<uint32_t>(field)) + >> shift(field); } // CPLD register write-only interface - void poke32(const wb_addr_type addr, const uint32_t data) { + void poke32(const wb_addr_type addr, const uint32_t data) + { boost::lock_guard<boost::mutex> lock(_mutex); using namespace soft_reg_field; - //Step 1: Write the reg offset and data to the GPIO bus and de-assert all enables + // Step 1: Write the reg offset and data to the GPIO bus and de-assert all enables _db_iface->set_gpio_out(dboard_iface::UNIT_BOTH, (cpld::get_reg(addr) << shift(CPLD_FULL_ADDR)) | (data << shift(CPLD_DATA)), - mask<uint32_t>(CPLD_FULL_ADDR)|mask<uint32_t>(CPLD_DATA)); - //Sleep for 166ns to ensure that we don't toggle the enables too quickly - //The underlying sleep function rounds to microsecond precision. + mask<uint32_t>(CPLD_FULL_ADDR) | mask<uint32_t>(CPLD_DATA)); + // Sleep for 166ns to ensure that we don't toggle the enables too quickly + // The underlying sleep function rounds to microsecond precision. _db_iface->sleep(boost::chrono::nanoseconds(166)); - //Step 2: Write the reg offset and data, and assert the necessary enable + // Step 2: Write the reg offset and data, and assert the necessary enable _db_iface->set_gpio_out(dboard_iface::UNIT_BOTH, - (static_cast<uint32_t>(addr) << shift(CPLD_FULL_ADDR)) | (data << shift(CPLD_DATA)), - mask<uint32_t>(CPLD_FULL_ADDR)|mask<uint32_t>(CPLD_DATA)); + (static_cast<uint32_t>(addr) << shift(CPLD_FULL_ADDR)) + | (data << shift(CPLD_DATA)), + mask<uint32_t>(CPLD_FULL_ADDR) | mask<uint32_t>(CPLD_DATA)); } -private: //Members/definitions - static const uint32_t GPIO_OUTPUT_MASK = 0xFC06FE03; - static const uint32_t GPIO_PINCTRL_MASK = 0x00000000; +private: // Members/definitions + static const uint32_t GPIO_OUTPUT_MASK = 0xFC06FE03; + static const uint32_t GPIO_PINCTRL_MASK = 0x00000000; - //Private GPIO fields - UHD_DEFINE_SOFT_REG_FIELD(CPLD_FULL_ADDR, /*width*/ 7, /*shift*/ 9); //GPIO[15:9] - UHD_DEFINE_SOFT_REG_FIELD(CPLD_DATA, /*width*/ 5, /*shift*/ 27); //GPIO[31:27] + // Private GPIO fields + UHD_DEFINE_SOFT_REG_FIELD(CPLD_FULL_ADDR, /*width*/ 7, /*shift*/ 9); // GPIO[15:9] + UHD_DEFINE_SOFT_REG_FIELD(CPLD_DATA, /*width*/ 5, /*shift*/ 27); // GPIO[31:27] - //Members - dboard_iface::sptr _db_iface; - boost::mutex _mutex; + // Members + dboard_iface::sptr _db_iface; + boost::mutex _mutex; }; -class twinrx_cpld_regmap : public uhd::soft_regmap_t { +class twinrx_cpld_regmap : public uhd::soft_regmap_t +{ public: typedef std::shared_ptr<twinrx_cpld_regmap> sptr; //---------------------------------------------- // IF CCA: CPLD 1 //---------------------------------------------- - class if0_reg0_t : public uhd::soft_reg32_wo_t { + class if0_reg0_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_IF1_EN_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(AMP_LO2_EN_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(AMP_LO2_EN_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW19_CTRL_CH2, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(SW20_CTRL_CH2, /*width*/ 1, /*shift*/ 4); - - if0_reg0_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 0), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_IF1_EN_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(AMP_LO2_EN_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(AMP_LO2_EN_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW19_CTRL_CH2, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(SW20_CTRL_CH2, /*width*/ 1, /*shift*/ 4); + + if0_reg0_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 0), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg0; - class if0_reg1_t : public uhd::soft_reg32_wo_t { + class if0_reg1_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW20_CTRL_CH1, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW20_CTRL_CH1, /*width*/ 1, /*shift*/ 2); - if0_reg1_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 1), OPTIMIZED_FLUSH) { + if0_reg1_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 1), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg1; - class if0_reg2_t : public uhd::soft_reg32_wo_t { + class if0_reg2_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_IF1_EN_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_IF1_EN_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(LO2_LE_CH1, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(LO2_LE_CH2, /*width*/ 1, /*shift*/ 4); - - if0_reg2_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 2), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_IF1_EN_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_IF1_EN_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(LO2_LE_CH1, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(LO2_LE_CH2, /*width*/ 1, /*shift*/ 4); + + if0_reg2_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 2), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg2; - class if0_reg3_t : public uhd::soft_reg32_wo_t { + class if0_reg3_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW24_CTRL_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW13_CTRL_CH1, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(IF1_IF2_EN_CH1, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(SW24_CTRL_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW13_CTRL_CH1, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(IF1_IF2_EN_CH1, /*width*/ 1, /*shift*/ 3); - if0_reg3_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 3), OPTIMIZED_FLUSH) { + if0_reg3_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 3), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg3; - class if0_reg4_t : public uhd::soft_reg32_wo_t { + class if0_reg4_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW21_CTRL_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW25_CTRL, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(IF1_IF2_EN_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW19_CTRL_CH1, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(SW21_CTRL_CH1, /*width*/ 1, /*shift*/ 4); - - if0_reg4_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 4), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SW21_CTRL_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW25_CTRL, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(IF1_IF2_EN_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW19_CTRL_CH1, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(SW21_CTRL_CH1, /*width*/ 1, /*shift*/ 4); + + if0_reg4_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 4), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg4; - class if0_reg6_t : public uhd::soft_reg32_wo_t { + class if0_reg6_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_IF1_EN_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW13_CTRL_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_IF1_EN_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW13_CTRL_CH2, /*width*/ 1, /*shift*/ 2); - if0_reg6_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 6), OPTIMIZED_FLUSH) { + if0_reg6_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 6), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg6; - class if0_reg7_t : public uhd::soft_reg32_wo_t { + class if0_reg7_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW24_CTRL_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW24_CTRL_CH2, /*width*/ 1, /*shift*/ 0); - if0_reg7_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 7), OPTIMIZED_FLUSH) { + if0_reg7_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 7), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg7; @@ -208,90 +252,114 @@ public: //---------------------------------------------- // RF CCA: CPLD 2 //---------------------------------------------- - class rf0_reg0_t : public uhd::soft_reg32_wo_t { + class rf0_reg0_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(ATTEN_IN_CH1, /*width*/ 5, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(ATTEN_IN_CH1, /*width*/ 5, /*shift*/ 0); - rf0_reg0_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 0), OPTIMIZED_FLUSH) { + rf0_reg0_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 0), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg0; - class rf0_reg1_t : public uhd::soft_reg32_wo_t { + class rf0_reg1_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SWPA1_CTL_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(HB_PREAMP_EN_CH1, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(LB_PREAMP_EN_CH1, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(SWPA3_CTRL_CH2, /*width*/ 1, /*shift*/ 4); - - rf0_reg1_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 1), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SWPA1_CTL_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(HB_PREAMP_EN_CH1, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(LB_PREAMP_EN_CH1, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(SWPA3_CTRL_CH2, /*width*/ 1, /*shift*/ 4); + + rf0_reg1_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 1), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg1; - class rf0_reg2_t : public uhd::soft_reg32_wo_t { + class rf0_reg2_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW6_CTRL_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW5_CTRL_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW4_CTRL_CH1, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(LO1_LE_CH1, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(LO1_LE_CH2, /*width*/ 1, /*shift*/ 4); - - rf0_reg2_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 2), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SW6_CTRL_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW5_CTRL_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW4_CTRL_CH1, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(LO1_LE_CH1, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(LO1_LE_CH2, /*width*/ 1, /*shift*/ 4); + + rf0_reg2_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 2), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg2; - class rf0_reg3_t : public uhd::soft_reg32_wo_t { + class rf0_reg3_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW9_CTRL_CH2, /*width*/ 2, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW7_CTRL_CH1, /*width*/ 2, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW9_CTRL_CH2, /*width*/ 2, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW7_CTRL_CH1, /*width*/ 2, /*shift*/ 2); - rf0_reg3_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 3), OPTIMIZED_FLUSH) { + rf0_reg3_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 3), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg3; - class rf0_reg4_t : public uhd::soft_reg32_wo_t { + class rf0_reg4_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(ATTEN_IN_CH2, /*width*/ 5, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(ATTEN_IN_CH2, /*width*/ 5, /*shift*/ 0); - rf0_reg4_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 4), OPTIMIZED_FLUSH) { + rf0_reg4_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 4), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg4; - class rf0_reg5_t : public uhd::soft_reg32_wo_t { + class rf0_reg5_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW9_CTRL_CH1, /*width*/ 2, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(HB_PREAMP_EN_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW3_CTRL_CH1, /*width*/ 1, /*shift*/ 4); + UHD_DEFINE_SOFT_REG_FIELD(SW9_CTRL_CH1, /*width*/ 2, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(HB_PREAMP_EN_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW3_CTRL_CH1, /*width*/ 1, /*shift*/ 4); - rf0_reg5_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 5), OPTIMIZED_FLUSH) { + rf0_reg5_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 5), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg5; - class rf0_reg6_t : public uhd::soft_reg32_wo_t { + class rf0_reg6_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW6_CTRL_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW5_CTRL_CH2, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW4_CTRL_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SWPA4_CTRL_CH2, /*width*/ 1, /*shift*/ 4); - - rf0_reg6_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 6), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SW6_CTRL_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW5_CTRL_CH2, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW4_CTRL_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SWPA4_CTRL_CH2, /*width*/ 1, /*shift*/ 4); + + rf0_reg6_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 6), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg6; - class rf0_reg7_t : public uhd::soft_reg32_wo_t { + class rf0_reg7_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SWPA1_CTRL_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SWPA3_CTRL_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW3_CTRL_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW7_CTRL_CH2, /*width*/ 2, /*shift*/ 3); - - rf0_reg7_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 7), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SWPA1_CTRL_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SWPA3_CTRL_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW3_CTRL_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW7_CTRL_CH2, /*width*/ 2, /*shift*/ 3); + + rf0_reg7_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 7), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg7; @@ -299,91 +367,115 @@ public: //---------------------------------------------- // RF CCA: CPLD 3 //---------------------------------------------- - class rf1_reg0_t : public uhd::soft_reg32_wo_t { + class rf1_reg0_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(ATTEN_HB_CH1, /*width*/ 5, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(ATTEN_HB_CH1, /*width*/ 5, /*shift*/ 0); - rf1_reg0_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 0), OPTIMIZED_FLUSH) { + rf1_reg0_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 0), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg0; - class rf1_reg1_t : public uhd::soft_reg32_wo_t { + class rf1_reg1_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW17_CTRL_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(AMP_LO1_EN_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW16_CTRL_CH1, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW15_CTRL_CH1, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(SW14_CTRL_CH1, /*width*/ 1, /*shift*/ 4); - - rf1_reg1_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 1), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SW17_CTRL_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(AMP_LO1_EN_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW16_CTRL_CH1, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW15_CTRL_CH1, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(SW14_CTRL_CH1, /*width*/ 1, /*shift*/ 4); + + rf1_reg1_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 1), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg1; - class rf1_reg2_t : public uhd::soft_reg32_wo_t { + class rf1_reg2_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW12_CTRL_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_EN_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW12_CTRL_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_EN_CH1, /*width*/ 1, /*shift*/ 1); UHD_DEFINE_SOFT_REG_FIELD(HB_PRESEL_PGA_EN_CH2, /*width*/ 1, /*shift*/ 2); - rf1_reg2_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 2), OPTIMIZED_FLUSH) { + rf1_reg2_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 2), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg2; - class rf1_reg3_t : public uhd::soft_reg32_wo_t { + class rf1_reg3_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW23_CTRL, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW22_CTRL_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW10_CTRL_CH1, /*width*/ 2, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW23_CTRL, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW22_CTRL_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW10_CTRL_CH1, /*width*/ 2, /*shift*/ 2); - rf1_reg3_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 3), OPTIMIZED_FLUSH) { + rf1_reg3_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 3), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg3; - class rf1_reg4_t : public uhd::soft_reg32_wo_t { + class rf1_reg4_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(ATTEN_HB_CH2, /*width*/ 5, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(ATTEN_HB_CH2, /*width*/ 5, /*shift*/ 0); - rf1_reg4_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 4), OPTIMIZED_FLUSH) { + rf1_reg4_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 4), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg4; - class rf1_reg5_t : public uhd::soft_reg32_wo_t { + class rf1_reg5_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(AMP_LO1_EN_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW15_CTRL_CH2, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW14_CTRL_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW18_CTRL_CH1, /*width*/ 1, /*shift*/ 4); - - rf1_reg5_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 5), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(AMP_LO1_EN_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW15_CTRL_CH2, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW14_CTRL_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW18_CTRL_CH1, /*width*/ 1, /*shift*/ 4); + + rf1_reg5_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 5), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg5; - class rf1_reg6_t : public uhd::soft_reg32_wo_t { + class rf1_reg6_t : public uhd::soft_reg32_wo_t + { public: UHD_DEFINE_SOFT_REG_FIELD(HB_PRESEL_PGA_EN_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW17_CTRL_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW16_CTRL_CH2, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(PREAMP2_EN_CH2, /*width*/ 1, /*shift*/ 4); + UHD_DEFINE_SOFT_REG_FIELD(SW17_CTRL_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW16_CTRL_CH2, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(PREAMP2_EN_CH2, /*width*/ 1, /*shift*/ 4); - rf1_reg6_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 6), OPTIMIZED_FLUSH) { + rf1_reg6_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 6), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg6; - class rf1_reg7_t : public uhd::soft_reg32_wo_t { + class rf1_reg7_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW22_CTRL_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW10_CTRL_CH2, /*width*/ 2, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW12_CTRL_CH2, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_EN_CH2, /*width*/ 1, /*shift*/ 4); - - rf1_reg7_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 7), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SW22_CTRL_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW10_CTRL_CH2, /*width*/ 2, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW12_CTRL_CH2, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_EN_CH2, /*width*/ 1, /*shift*/ 4); + + rf1_reg7_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 7), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg7; @@ -391,77 +483,99 @@ public: //---------------------------------------------- // RF CCA: CPLD 4 //---------------------------------------------- - class rf2_reg0_t : public uhd::soft_reg32_wo_t { + class rf2_reg0_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(ATTEN_LB_CH1, /*width*/ 5, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(ATTEN_LB_CH1, /*width*/ 5, /*shift*/ 0); - rf2_reg0_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 0), OPTIMIZED_FLUSH) { + rf2_reg0_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 0), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg0; - class rf2_reg2_t : public uhd::soft_reg32_wo_t { + class rf2_reg2_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW11_CTRL_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_EN_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SWPA2_CTRL_CH1, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW11_CTRL_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_EN_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SWPA2_CTRL_CH1, /*width*/ 1, /*shift*/ 2); - rf2_reg2_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 2), OPTIMIZED_FLUSH) { + rf2_reg2_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 2), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg2; - class rf2_reg3_t : public uhd::soft_reg32_wo_t { + class rf2_reg3_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(PREAMP2_EN_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW18_CTRL_CH2, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW8_CTRL_CH1, /*width*/ 2, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(PREAMP2_EN_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW18_CTRL_CH2, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW8_CTRL_CH1, /*width*/ 2, /*shift*/ 2); - rf2_reg3_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 3), OPTIMIZED_FLUSH) { + rf2_reg3_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 3), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg3; - class rf2_reg4_t : public uhd::soft_reg32_wo_t { + class rf2_reg4_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(ATTEN_LB_CH2, /*width*/ 5, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(ATTEN_LB_CH2, /*width*/ 5, /*shift*/ 0); - rf2_reg4_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 4), OPTIMIZED_FLUSH) { + rf2_reg4_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 4), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg4; - class rf2_reg5_t : public uhd::soft_reg32_wo_t { + class rf2_reg5_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SWPA2_CTRL_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SWPA2_CTRL_CH2, /*width*/ 1, /*shift*/ 0); - rf2_reg5_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 5), OPTIMIZED_FLUSH) { + rf2_reg5_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 5), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg5; - class rf2_reg6_t : public uhd::soft_reg32_wo_t { + class rf2_reg6_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(LB_PREAMP_EN_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(LB_PREAMP_EN_CH2, /*width*/ 1, /*shift*/ 0); - rf2_reg6_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 6), OPTIMIZED_FLUSH) { + rf2_reg6_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 6), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg6; - class rf2_reg7_t : public uhd::soft_reg32_wo_t { + class rf2_reg7_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SWPA4_CTRL_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW8_CTRL_CH2, /*width*/ 2, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW11_CTRL_CH2, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_EN_CH2, /*width*/ 1, /*shift*/ 4); - - rf2_reg7_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 7), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SWPA4_CTRL_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW8_CTRL_CH2, /*width*/ 2, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW11_CTRL_CH2, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_EN_CH2, /*width*/ 1, /*shift*/ 4); + + rf2_reg7_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 7), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg7; - twinrx_cpld_regmap() : soft_regmap_t("twinrx_cpld") { + twinrx_cpld_regmap() : soft_regmap_t("twinrx_cpld") + { // IF CCA: CPLD 1 add_to_map(if0_reg0, "if0_reg0"); add_to_map(if0_reg1, "if0_reg1"); @@ -499,6 +613,6 @@ public: } }; -}}}} //namespaces +}}}} // namespace uhd::usrp::dboard::twinrx #endif /* INCLUDED_DBOARD_TWINRX_IO_HPP */ diff --git a/host/lib/usrp/dboard_base.cpp b/host/lib/usrp/dboard_base.cpp index 612392b69..eb9bfe880 100644 --- a/host/lib/usrp/dboard_base.cpp +++ b/host/lib/usrp/dboard_base.cpp @@ -15,83 +15,96 @@ using namespace uhd::usrp; /*********************************************************************** * dboard_base dboard dboard_base class **********************************************************************/ -struct dboard_base::impl{ +struct dboard_base::impl +{ dboard_ctor_args_t args; }; -dboard_base::dboard_base(ctor_args_t args){ - _impl = UHD_PIMPL_MAKE(impl, ()); +dboard_base::dboard_base(ctor_args_t args) +{ + _impl = UHD_PIMPL_MAKE(impl, ()); _impl->args = dboard_ctor_args_t::cast(args); } -std::string dboard_base::get_subdev_name(void){ +std::string dboard_base::get_subdev_name(void) +{ return _impl->args.sd_name; } -dboard_iface::sptr dboard_base::get_iface(void){ +dboard_iface::sptr dboard_base::get_iface(void) +{ return _impl->args.db_iface; } -dboard_id_t dboard_base::get_rx_id(void){ +dboard_id_t dboard_base::get_rx_id(void) +{ return _impl->args.rx_eeprom.id; } -dboard_id_t dboard_base::get_tx_id(void){ +dboard_id_t dboard_base::get_tx_id(void) +{ return _impl->args.tx_eeprom.id; } -dboard_eeprom_t dboard_base::get_rx_eeprom(void){ +dboard_eeprom_t dboard_base::get_rx_eeprom(void) +{ return _impl->args.rx_eeprom; } -dboard_eeprom_t dboard_base::get_tx_eeprom(void){ +dboard_eeprom_t dboard_base::get_tx_eeprom(void) +{ return _impl->args.tx_eeprom; } -property_tree::sptr dboard_base::get_rx_subtree(void){ +property_tree::sptr dboard_base::get_rx_subtree(void) +{ return _impl->args.rx_subtree; } -property_tree::sptr dboard_base::get_tx_subtree(void){ +property_tree::sptr dboard_base::get_tx_subtree(void) +{ return _impl->args.tx_subtree; } /*********************************************************************** * xcvr dboard dboard_base class **********************************************************************/ -xcvr_dboard_base::xcvr_dboard_base(ctor_args_t args) : dboard_base(args){ - if (get_rx_id() == dboard_id_t::none()){ - throw uhd::runtime_error(str(boost::format( - "cannot create xcvr board when the rx id is \"%s\"" - ) % dboard_id_t::none().to_pp_string())); +xcvr_dboard_base::xcvr_dboard_base(ctor_args_t args) : dboard_base(args) +{ + if (get_rx_id() == dboard_id_t::none()) { + throw uhd::runtime_error( + str(boost::format("cannot create xcvr board when the rx id is \"%s\"") + % dboard_id_t::none().to_pp_string())); } - if (get_tx_id() == dboard_id_t::none()){ - throw uhd::runtime_error(str(boost::format( - "cannot create xcvr board when the tx id is \"%s\"" - ) % dboard_id_t::none().to_pp_string())); + if (get_tx_id() == dboard_id_t::none()) { + throw uhd::runtime_error( + str(boost::format("cannot create xcvr board when the tx id is \"%s\"") + % dboard_id_t::none().to_pp_string())); } } /*********************************************************************** * rx dboard dboard_base class **********************************************************************/ -rx_dboard_base::rx_dboard_base(ctor_args_t args) : dboard_base(args){ - if (get_tx_id() != dboard_id_t::none()){ - throw uhd::runtime_error(str(boost::format( - "cannot create rx board when the tx id is \"%s\"" - " -> expected a tx id of \"%s\"" - ) % get_tx_id().to_pp_string() % dboard_id_t::none().to_pp_string())); +rx_dboard_base::rx_dboard_base(ctor_args_t args) : dboard_base(args) +{ + if (get_tx_id() != dboard_id_t::none()) { + throw uhd::runtime_error( + str(boost::format("cannot create rx board when the tx id is \"%s\"" + " -> expected a tx id of \"%s\"") + % get_tx_id().to_pp_string() % dboard_id_t::none().to_pp_string())); } } /*********************************************************************** * tx dboard dboard_base class **********************************************************************/ -tx_dboard_base::tx_dboard_base(ctor_args_t args) : dboard_base(args){ - if (get_rx_id() != dboard_id_t::none()){ - throw uhd::runtime_error(str(boost::format( - "cannot create tx board when the rx id is \"%s\"" - " -> expected a rx id of \"%s\"" - ) % get_rx_id().to_pp_string() % dboard_id_t::none().to_pp_string())); +tx_dboard_base::tx_dboard_base(ctor_args_t args) : dboard_base(args) +{ + if (get_rx_id() != dboard_id_t::none()) { + throw uhd::runtime_error( + str(boost::format("cannot create tx board when the rx id is \"%s\"" + " -> expected a rx id of \"%s\"") + % get_rx_id().to_pp_string() % dboard_id_t::none().to_pp_string())); } } diff --git a/host/lib/usrp/dboard_ctor_args.hpp b/host/lib/usrp/dboard_ctor_args.hpp index a1a6e08d2..ad471df23 100644 --- a/host/lib/usrp/dboard_ctor_args.hpp +++ b/host/lib/usrp/dboard_ctor_args.hpp @@ -9,25 +9,27 @@ #include <uhd/property_tree.hpp> #include <uhd/usrp/dboard_base.hpp> -#include <uhd/usrp/dboard_iface.hpp> #include <uhd/usrp/dboard_eeprom.hpp> +#include <uhd/usrp/dboard_iface.hpp> #include <string> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { - class dboard_ctor_args_t { - public: - std::string sd_name; - dboard_iface::sptr db_iface; - dboard_eeprom_t rx_eeprom, tx_eeprom; - property_tree::sptr rx_subtree, tx_subtree; - dboard_base::sptr rx_container, tx_container; +class dboard_ctor_args_t +{ +public: + std::string sd_name; + dboard_iface::sptr db_iface; + dboard_eeprom_t rx_eeprom, tx_eeprom; + property_tree::sptr rx_subtree, tx_subtree; + dboard_base::sptr rx_container, tx_container; - static const dboard_ctor_args_t& cast(dboard_base::ctor_args_t args) { - return *static_cast<dboard_ctor_args_t*>(args); - } - }; + static const dboard_ctor_args_t& cast(dboard_base::ctor_args_t args) + { + return *static_cast<dboard_ctor_args_t*>(args); + } +}; -}} //namespace +}} // namespace uhd::usrp #endif /* INCLUDED_LIBUHD_USRP_DBOARD_CTOR_ARGS_HPP */ diff --git a/host/lib/usrp/dboard_eeprom.cpp b/host/lib/usrp/dboard_eeprom.cpp index 54a2ea196..7775f5300 100644 --- a/host/lib/usrp/dboard_eeprom.cpp +++ b/host/lib/usrp/dboard_eeprom.cpp @@ -5,9 +5,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include <uhd/exception.hpp> #include <uhd/types/byte_vector.hpp> #include <uhd/usrp/dboard_eeprom.hpp> -#include <uhd/exception.hpp> #include <uhd/utils/log.hpp> #include <boost/format.hpp> #include <boost/lexical_cast.hpp> @@ -31,97 +31,96 @@ using namespace uhd::usrp; // ... // 1f: .. negative of the sum of bytes [0x00, 0x1e] -#define DB_EEPROM_MAGIC 0x00 -#define DB_EEPROM_MAGIC_VALUE 0xDB -#define DB_EEPROM_ID_LSB 0x01 -#define DB_EEPROM_ID_MSB 0x02 -#define DB_EEPROM_REV_LSB 0x03 -#define DB_EEPROM_REV_MSB 0x04 -#define DB_EEPROM_OFFSET_0_LSB 0x05 // offset correction for ADC or DAC 0 -#define DB_EEPROM_OFFSET_0_MSB 0x06 -#define DB_EEPROM_OFFSET_1_LSB 0x07 // offset correction for ADC or DAC 1 -#define DB_EEPROM_OFFSET_1_MSB 0x08 -#define DB_EEPROM_SERIAL 0x09 -#define DB_EEPROM_SERIAL_LEN 0x09 //9 ASCII characters -#define DB_EEPROM_CHKSUM 0x1f - -#define DB_EEPROM_CLEN 0x20 // length of common portion of eeprom - -#define DB_EEPROM_CUSTOM_BASE DB_EEPROM_CLEN // first avail offset for - // daughterboard specific use +#define DB_EEPROM_MAGIC 0x00 +#define DB_EEPROM_MAGIC_VALUE 0xDB +#define DB_EEPROM_ID_LSB 0x01 +#define DB_EEPROM_ID_MSB 0x02 +#define DB_EEPROM_REV_LSB 0x03 +#define DB_EEPROM_REV_MSB 0x04 +#define DB_EEPROM_OFFSET_0_LSB 0x05 // offset correction for ADC or DAC 0 +#define DB_EEPROM_OFFSET_0_MSB 0x06 +#define DB_EEPROM_OFFSET_1_LSB 0x07 // offset correction for ADC or DAC 1 +#define DB_EEPROM_OFFSET_1_MSB 0x08 +#define DB_EEPROM_SERIAL 0x09 +#define DB_EEPROM_SERIAL_LEN 0x09 // 9 ASCII characters +#define DB_EEPROM_CHKSUM 0x1f + +#define DB_EEPROM_CLEN 0x20 // length of common portion of eeprom + +#define DB_EEPROM_CUSTOM_BASE \ + DB_EEPROM_CLEN // first avail offset for + // daughterboard specific use //////////////////////////////////////////////////////////////////////// -//negative sum of bytes excluding checksum byte -static uint8_t checksum(const byte_vector_t &bytes){ +// negative sum of bytes excluding checksum byte +static uint8_t checksum(const byte_vector_t& bytes) +{ int sum = 0; - for (size_t i = 0; i < std::min(bytes.size(), size_t(DB_EEPROM_CHKSUM)); i++){ + for (size_t i = 0; i < std::min(bytes.size(), size_t(DB_EEPROM_CHKSUM)); i++) { sum -= int(bytes.at(i)); } return uint8_t(sum); } -dboard_eeprom_t::dboard_eeprom_t(void){ - id = dboard_id_t::none(); +dboard_eeprom_t::dboard_eeprom_t(void) +{ + id = dboard_id_t::none(); serial = ""; } -void dboard_eeprom_t::load(i2c_iface &iface, uint8_t addr){ +void dboard_eeprom_t::load(i2c_iface& iface, uint8_t addr) +{ byte_vector_t bytes = iface.read_eeprom(addr, 0, DB_EEPROM_CLEN); std::ostringstream ss; - try{ + try { UHD_ASSERT_THROW(bytes.size() >= DB_EEPROM_CLEN); UHD_ASSERT_THROW(bytes[DB_EEPROM_MAGIC] == DB_EEPROM_MAGIC_VALUE); UHD_ASSERT_THROW(bytes[DB_EEPROM_CHKSUM] == checksum(bytes)); - //parse the ids - id = dboard_id_t::from_uint16(0 - | (uint16_t(bytes[DB_EEPROM_ID_LSB]) << 0) - | (uint16_t(bytes[DB_EEPROM_ID_MSB]) << 8) - ); - - //parse the serial - serial = bytes_to_string( - byte_vector_t(&bytes.at(DB_EEPROM_SERIAL), - &bytes.at(DB_EEPROM_SERIAL+DB_EEPROM_SERIAL_LEN)) - ); - - //parse the revision - const uint16_t rev_num = 0 - | (uint16_t(bytes[DB_EEPROM_REV_LSB]) << 0) - | (uint16_t(bytes[DB_EEPROM_REV_MSB]) << 8) - ; - if (rev_num != 0 and rev_num != 0xffff){ + // parse the ids + id = dboard_id_t::from_uint16(0 | (uint16_t(bytes[DB_EEPROM_ID_LSB]) << 0) + | (uint16_t(bytes[DB_EEPROM_ID_MSB]) << 8)); + + // parse the serial + serial = bytes_to_string(byte_vector_t(&bytes.at(DB_EEPROM_SERIAL), + &bytes.at(DB_EEPROM_SERIAL + DB_EEPROM_SERIAL_LEN))); + + // parse the revision + const uint16_t rev_num = 0 | (uint16_t(bytes[DB_EEPROM_REV_LSB]) << 0) + | (uint16_t(bytes[DB_EEPROM_REV_MSB]) << 8); + if (rev_num != 0 and rev_num != 0xffff) { revision = std::to_string(rev_num); } - }catch(const uhd::assertion_error &){ - id = dboard_id_t::none(); + } catch (const uhd::assertion_error&) { + id = dboard_id_t::none(); serial = ""; } } -void dboard_eeprom_t::store(i2c_iface &iface, uint8_t addr) const{ - byte_vector_t bytes(DB_EEPROM_CLEN, 0); //defaults to all zeros +void dboard_eeprom_t::store(i2c_iface& iface, uint8_t addr) const +{ + byte_vector_t bytes(DB_EEPROM_CLEN, 0); // defaults to all zeros bytes[DB_EEPROM_MAGIC] = DB_EEPROM_MAGIC_VALUE; - //load the id bytes + // load the id bytes bytes[DB_EEPROM_ID_LSB] = uint8_t(id.to_uint16() >> 0); bytes[DB_EEPROM_ID_MSB] = uint8_t(id.to_uint16() >> 8); - //load the serial bytes + // load the serial bytes byte_vector_t ser_bytes = string_to_bytes(serial, DB_EEPROM_SERIAL_LEN); std::copy(ser_bytes.begin(), ser_bytes.end(), &bytes.at(DB_EEPROM_SERIAL)); - //load the revision bytes - if (not revision.empty()){ - const uint16_t rev_num = boost::lexical_cast<uint16_t>(revision); + // load the revision bytes + if (not revision.empty()) { + const uint16_t rev_num = boost::lexical_cast<uint16_t>(revision); bytes[DB_EEPROM_REV_LSB] = uint8_t(rev_num >> 0); bytes[DB_EEPROM_REV_MSB] = uint8_t(rev_num >> 8); } - //load the checksum + // load the checksum bytes[DB_EEPROM_CHKSUM] = checksum(bytes); iface.write_eeprom(addr, 0, bytes); diff --git a/host/lib/usrp/dboard_eeprom_c.cpp b/host/lib/usrp/dboard_eeprom_c.cpp index a3ee0a2ed..b23d80689 100644 --- a/host/lib/usrp/dboard_eeprom_c.cpp +++ b/host/lib/usrp/dboard_eeprom_c.cpp @@ -5,115 +5,77 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/usrp/dboard_eeprom.h> #include <uhd/error.h> -#include <boost/format.hpp> - +#include <uhd/usrp/dboard_eeprom.h> #include <string.h> +#include <boost/format.hpp> -uhd_error uhd_dboard_eeprom_make( - uhd_dboard_eeprom_handle* h -){ - UHD_SAFE_C( - *h = new uhd_dboard_eeprom_t; - ) +uhd_error uhd_dboard_eeprom_make(uhd_dboard_eeprom_handle* h) +{ + UHD_SAFE_C(*h = new uhd_dboard_eeprom_t;) } -uhd_error uhd_dboard_eeprom_free( - uhd_dboard_eeprom_handle* h -){ - UHD_SAFE_C( - delete *h; - *h = NULL; - ) +uhd_error uhd_dboard_eeprom_free(uhd_dboard_eeprom_handle* h) +{ + UHD_SAFE_C(delete *h; *h = NULL;) } uhd_error uhd_dboard_eeprom_get_id( - uhd_dboard_eeprom_handle h, - char* id_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string dboard_id_cpp = h->dboard_eeprom_cpp.id.to_string(); - strncpy(id_out, dboard_id_cpp.c_str(), strbuffer_len); - ) + uhd_dboard_eeprom_handle h, char* id_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR( + h, std::string dboard_id_cpp = h->dboard_eeprom_cpp.id.to_string(); + strncpy(id_out, dboard_id_cpp.c_str(), strbuffer_len);) } -uhd_error uhd_dboard_eeprom_set_id( - uhd_dboard_eeprom_handle h, - const char* id -){ - UHD_SAFE_C_SAVE_ERROR(h, - h->dboard_eeprom_cpp.id = uhd::usrp::dboard_id_t::from_string(id); - ) +uhd_error uhd_dboard_eeprom_set_id(uhd_dboard_eeprom_handle h, const char* id) +{ + UHD_SAFE_C_SAVE_ERROR( + h, h->dboard_eeprom_cpp.id = uhd::usrp::dboard_id_t::from_string(id);) } uhd_error uhd_dboard_eeprom_get_serial( - uhd_dboard_eeprom_handle h, - char* id_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string dboard_serial_cpp = h->dboard_eeprom_cpp.serial; - strncpy(id_out, dboard_serial_cpp.c_str(), strbuffer_len); - ) + uhd_dboard_eeprom_handle h, char* id_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR(h, std::string dboard_serial_cpp = h->dboard_eeprom_cpp.serial; + strncpy(id_out, dboard_serial_cpp.c_str(), strbuffer_len);) } -uhd_error uhd_dboard_eeprom_set_serial( - uhd_dboard_eeprom_handle h, - const char* serial -){ - UHD_SAFE_C_SAVE_ERROR(h, - h->dboard_eeprom_cpp.serial = serial; - ) +uhd_error uhd_dboard_eeprom_set_serial(uhd_dboard_eeprom_handle h, const char* serial) +{ + UHD_SAFE_C_SAVE_ERROR(h, h->dboard_eeprom_cpp.serial = serial;) } //! Convert a string into an int. If that doesn't work, craft our own exception // instead of using the Boost exception. We need to put this separate from the // caller function because of macro expansion. -int _convert_rev_with_exception(const std::string &rev_str) +int _convert_rev_with_exception(const std::string& rev_str) { try { return std::stoi(rev_str); - } catch (const std::invalid_argument &) { - throw uhd::lookup_error(str( - boost::format("Error retrieving revision from string `%s`") - % rev_str - )); - } catch (const std::out_of_range &) { - throw uhd::lookup_error(str( - boost::format("Error retrieving revision from string `%s`") - % rev_str - )); + } catch (const std::invalid_argument&) { + throw uhd::lookup_error( + str(boost::format("Error retrieving revision from string `%s`") % rev_str)); + } catch (const std::out_of_range&) { + throw uhd::lookup_error( + str(boost::format("Error retrieving revision from string `%s`") % rev_str)); } } -uhd_error uhd_dboard_eeprom_get_revision( - uhd_dboard_eeprom_handle h, - int* revision_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *revision_out = \ - _convert_rev_with_exception(h->dboard_eeprom_cpp.revision); - ) +uhd_error uhd_dboard_eeprom_get_revision(uhd_dboard_eeprom_handle h, int* revision_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, *revision_out = _convert_rev_with_exception(h->dboard_eeprom_cpp.revision);) } -uhd_error uhd_dboard_eeprom_set_revision( - uhd_dboard_eeprom_handle h, - int revision -){ - UHD_SAFE_C_SAVE_ERROR(h, - h->dboard_eeprom_cpp.revision = std::to_string(revision); - ) +uhd_error uhd_dboard_eeprom_set_revision(uhd_dboard_eeprom_handle h, int revision) +{ + UHD_SAFE_C_SAVE_ERROR(h, h->dboard_eeprom_cpp.revision = std::to_string(revision);) } uhd_error uhd_dboard_eeprom_last_error( - uhd_dboard_eeprom_handle h, - char* error_out, - size_t strbuffer_len -){ - UHD_SAFE_C( - memset(error_out, '\0', strbuffer_len); - strncpy(error_out, h->last_error.c_str(), strbuffer_len); - ) + uhd_dboard_eeprom_handle h, char* error_out, size_t strbuffer_len) +{ + UHD_SAFE_C(memset(error_out, '\0', strbuffer_len); + strncpy(error_out, h->last_error.c_str(), strbuffer_len);) } diff --git a/host/lib/usrp/dboard_id.cpp b/host/lib/usrp/dboard_id.cpp index fa12c2a4c..38a7ae8f7 100644 --- a/host/lib/usrp/dboard_id.cpp +++ b/host/lib/usrp/dboard_id.cpp @@ -6,41 +6,52 @@ // #include <uhd/usrp/dboard_id.hpp> -#include <boost/lexical_cast.hpp> #include <boost/format.hpp> -#include <sstream> +#include <boost/lexical_cast.hpp> #include <iostream> +#include <sstream> using namespace uhd::usrp; -dboard_id_t::dboard_id_t(uint16_t id){ +dboard_id_t::dboard_id_t(uint16_t id) +{ _id = id; } -dboard_id_t dboard_id_t::none(void){ +dboard_id_t dboard_id_t::none(void) +{ return dboard_id_t(); } -dboard_id_t dboard_id_t::from_uint16(uint16_t uint16){ +dboard_id_t dboard_id_t::from_uint16(uint16_t uint16) +{ return dboard_id_t(uint16); } -uint16_t dboard_id_t::to_uint16(void) const{ +uint16_t dboard_id_t::to_uint16(void) const +{ return _id; } -//used with lexical cast to parse a hex string -template <class T> struct to_hex{ +// used with lexical cast to parse a hex string +template <class T> +struct to_hex +{ T value; - operator T() const {return value;} - friend std::istream& operator>>(std::istream& in, to_hex& out){ + operator T() const + { + return value; + } + friend std::istream& operator>>(std::istream& in, to_hex& out) + { in >> std::hex >> out.value; return in; } }; -dboard_id_t dboard_id_t::from_string(const std::string &string){ - if (string.substr(0, 2) == "0x"){ +dboard_id_t dboard_id_t::from_string(const std::string& string) +{ + if (string.substr(0, 2) == "0x") { std::stringstream interpreter(string); to_hex<uint16_t> hh; interpreter >> hh; @@ -49,13 +60,15 @@ dboard_id_t dboard_id_t::from_string(const std::string &string){ return dboard_id_t::from_uint16(boost::lexical_cast<uint16_t>(string)); } -std::string dboard_id_t::to_string(void) const{ +std::string dboard_id_t::to_string(void) const +{ return str(boost::format("0x%04x") % this->to_uint16()); } -//Note: to_pp_string is implemented in the dboard manager -//because it needs access to the dboard registration table +// Note: to_pp_string is implemented in the dboard manager +// because it needs access to the dboard registration table -bool uhd::usrp::operator==(const dboard_id_t &lhs, const dboard_id_t &rhs){ +bool uhd::usrp::operator==(const dboard_id_t& lhs, const dboard_id_t& rhs) +{ return lhs.to_uint16() == rhs.to_uint16(); } diff --git a/host/lib/usrp/dboard_iface.cpp b/host/lib/usrp/dboard_iface.cpp index 3bda643fe..b2ff23ab9 100644 --- a/host/lib/usrp/dboard_iface.cpp +++ b/host/lib/usrp/dboard_iface.cpp @@ -13,11 +13,11 @@ using namespace uhd::usrp; void dboard_iface::sleep(const boost::chrono::nanoseconds& time) { - //nanosleep is not really accurate in userland and it is also not very - //cross-platform. So just sleep for the minimum amount of time in us. - if (time < boost::chrono::microseconds(1)) { - std::this_thread::sleep_for(std::chrono::microseconds(1)); - } else { - std::this_thread::sleep_for(std::chrono::microseconds(time.count())); - } + // nanosleep is not really accurate in userland and it is also not very + // cross-platform. So just sleep for the minimum amount of time in us. + if (time < boost::chrono::microseconds(1)) { + std::this_thread::sleep_for(std::chrono::microseconds(1)); + } else { + std::this_thread::sleep_for(std::chrono::microseconds(time.count())); + } } diff --git a/host/lib/usrp/dboard_iface_python.hpp b/host/lib/usrp/dboard_iface_python.hpp index 96fcc1702..0dfd5866e 100644 --- a/host/lib/usrp/dboard_iface_python.hpp +++ b/host/lib/usrp/dboard_iface_python.hpp @@ -8,9 +8,9 @@ #ifndef INCLUDED_UHD_USRP_DBOARD_IFACE_PYTHON_HPP #define INCLUDED_UHD_USRP_DBOARD_IFACE_PYTHON_HPP +#include "../include/uhdlib/usrp/gpio_defs.hpp" #include <uhd/usrp/dboard_iface.hpp> #include <uhd/usrp/gpio_defs.hpp> -#include "../include/uhdlib/usrp/gpio_defs.hpp" void export_dboard_iface(py::module& m) { @@ -18,74 +18,67 @@ void export_dboard_iface(py::module& m) using special_props_t = uhd::usrp::dboard_iface_special_props_t; using unit_t = dboard_iface::unit_t; - using aux_dac_t = dboard_iface::aux_dac_t; - using aux_adc_t = dboard_iface::aux_adc_t; + using aux_dac_t = dboard_iface::aux_dac_t; + using aux_adc_t = dboard_iface::aux_adc_t; using gpio_atr_reg_t = uhd::usrp::gpio_atr::gpio_atr_reg_t; using gpio_atr_mode_t = uhd::usrp::gpio_atr::gpio_atr_mode_t; py::enum_<gpio_atr_reg_t>(m, "gpio_atr_reg") - .value("ATR_REG_IDLE" , gpio_atr_reg_t::ATR_REG_IDLE ) - .value("ATR_REG_TX_ONLY" , gpio_atr_reg_t::ATR_REG_TX_ONLY ) - .value("ATR_REG_RX_ONLY" , gpio_atr_reg_t::ATR_REG_RX_ONLY ) - .value("ATR_REG_FULL_DUPLEX", gpio_atr_reg_t::ATR_REG_FULL_DUPLEX) - ; + .value("ATR_REG_IDLE", gpio_atr_reg_t::ATR_REG_IDLE) + .value("ATR_REG_TX_ONLY", gpio_atr_reg_t::ATR_REG_TX_ONLY) + .value("ATR_REG_RX_ONLY", gpio_atr_reg_t::ATR_REG_RX_ONLY) + .value("ATR_REG_FULL_DUPLEX", gpio_atr_reg_t::ATR_REG_FULL_DUPLEX); py::enum_<gpio_atr_mode_t>(m, "gpio_atr_mode") - .value("MODE_ATR" , gpio_atr_mode_t::MODE_ATR ) - .value("MODE_GPIO", gpio_atr_mode_t::MODE_GPIO) - ; + .value("MODE_ATR", gpio_atr_mode_t::MODE_ATR) + .value("MODE_GPIO", gpio_atr_mode_t::MODE_GPIO); py::enum_<unit_t>(m, "unit") - .value("UNIT_RX" , unit_t::UNIT_RX ) - .value("UNIT_TX" , unit_t::UNIT_TX ) - .value("UNIT_BOTH", unit_t::UNIT_BOTH) - ; + .value("UNIT_RX", unit_t::UNIT_RX) + .value("UNIT_TX", unit_t::UNIT_TX) + .value("UNIT_BOTH", unit_t::UNIT_BOTH); py::enum_<aux_dac_t>(m, "aux_dac") .value("AUX_DAC_A", aux_dac_t::AUX_DAC_A) .value("AUX_DAC_B", aux_dac_t::AUX_DAC_B) .value("AUX_DAC_C", aux_dac_t::AUX_DAC_C) - .value("AUX_DAC_D", aux_dac_t::AUX_DAC_D) - ; + .value("AUX_DAC_D", aux_dac_t::AUX_DAC_D); py::enum_<aux_adc_t>(m, "aux_adc") .value("AUX_ADC_A", aux_adc_t::AUX_ADC_A) - .value("AUX_ADC_B", aux_adc_t::AUX_ADC_B) - ; + .value("AUX_ADC_B", aux_adc_t::AUX_ADC_B); py::class_<special_props_t>(m, "special_props") // Properties .def_readwrite("soft_clock_divider", &special_props_t::soft_clock_divider) - .def_readwrite("mangle_i2c_addrs" , &special_props_t::mangle_i2c_addrs ) - ; + .def_readwrite("mangle_i2c_addrs", &special_props_t::mangle_i2c_addrs); py::class_<dboard_iface, dboard_iface::sptr>(m, "dboard_iface") // Methods .def("get_special_props", &dboard_iface::get_special_props) - .def("write_aux_dac" , &dboard_iface::write_aux_dac ) - .def("read_aux_adc" , &dboard_iface::read_aux_adc ) - .def("set_pin_ctrl" , &dboard_iface::set_pin_ctrl ) - .def("get_pin_ctrl" , &dboard_iface::get_pin_ctrl ) - .def("set_atr_reg" , &dboard_iface::set_atr_reg ) - .def("get_atr_reg" , &dboard_iface::get_atr_reg ) - .def("set_gpio_ddr" , &dboard_iface::set_gpio_ddr ) - .def("get_gpio_ddr" , &dboard_iface::get_gpio_ddr ) - .def("get_gpio_out" , &dboard_iface::get_gpio_out ) - .def("set_gpio_out" , &dboard_iface::set_gpio_out ) - .def("read_gpio" , &dboard_iface::read_gpio ) - .def("write_spi" , &dboard_iface::write_spi ) - .def("read_write_spi" , &dboard_iface::read_write_spi ) - .def("set_clock_rate" , &dboard_iface::set_clock_rate ) - .def("get_clock_rate" , &dboard_iface::get_clock_rate ) - .def("get_clock_rates" , &dboard_iface::get_clock_rates ) + .def("write_aux_dac", &dboard_iface::write_aux_dac) + .def("read_aux_adc", &dboard_iface::read_aux_adc) + .def("set_pin_ctrl", &dboard_iface::set_pin_ctrl) + .def("get_pin_ctrl", &dboard_iface::get_pin_ctrl) + .def("set_atr_reg", &dboard_iface::set_atr_reg) + .def("get_atr_reg", &dboard_iface::get_atr_reg) + .def("set_gpio_ddr", &dboard_iface::set_gpio_ddr) + .def("get_gpio_ddr", &dboard_iface::get_gpio_ddr) + .def("get_gpio_out", &dboard_iface::get_gpio_out) + .def("set_gpio_out", &dboard_iface::set_gpio_out) + .def("read_gpio", &dboard_iface::read_gpio) + .def("write_spi", &dboard_iface::write_spi) + .def("read_write_spi", &dboard_iface::read_write_spi) + .def("set_clock_rate", &dboard_iface::set_clock_rate) + .def("get_clock_rate", &dboard_iface::get_clock_rate) + .def("get_clock_rates", &dboard_iface::get_clock_rates) .def("set_clock_enabled", &dboard_iface::set_clock_enabled) - .def("get_codec_rate" , &dboard_iface::get_codec_rate ) + .def("get_codec_rate", &dboard_iface::get_codec_rate) .def("set_fe_connection", &dboard_iface::set_fe_connection) - .def("get_command_time" , &dboard_iface::get_command_time ) - .def("set_command_time" , &dboard_iface::set_command_time ) - .def("sleep" , &dboard_iface::sleep ) - ; + .def("get_command_time", &dboard_iface::get_command_time) + .def("set_command_time", &dboard_iface::set_command_time) + .def("sleep", &dboard_iface::sleep); } #endif /* INCLUDED_UHD_USRP_DBOARD_IFACE_PYTHON_HPP */ diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index a4acf2aaf..dc7ca6ac9 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -5,13 +5,12 @@ // #include "dboard_ctor_args.hpp" +#include <uhd/exception.hpp> +#include <uhd/types/dict.hpp> #include <uhd/usrp/dboard_manager.hpp> #include <uhd/utils/log.hpp> -#include <uhd/utils/log.hpp> #include <uhd/utils/safe_call.hpp> #include <uhd/utils/static.hpp> -#include <uhd/exception.hpp> -#include <uhd/types/dict.hpp> #include <boost/format.hpp> #include <functional> #include <tuple> @@ -22,34 +21,45 @@ using namespace uhd::usrp; /*********************************************************************** * dboard key class to use for look-up **********************************************************************/ -class dboard_key_t{ +class dboard_key_t +{ public: - dboard_key_t(const dboard_id_t &id = dboard_id_t::none(), bool restricted = false): - _rx_id(id), _tx_id(id), _xcvr(false), _restricted(restricted) {} + dboard_key_t(const dboard_id_t& id = dboard_id_t::none(), bool restricted = false) + : _rx_id(id), _tx_id(id), _xcvr(false), _restricted(restricted) + { + } - dboard_key_t(const dboard_id_t &rx_id, const dboard_id_t &tx_id, bool restricted = false): - _rx_id(rx_id), _tx_id(tx_id), _xcvr(true), _restricted(restricted) {} + dboard_key_t( + const dboard_id_t& rx_id, const dboard_id_t& tx_id, bool restricted = false) + : _rx_id(rx_id), _tx_id(tx_id), _xcvr(true), _restricted(restricted) + { + } - dboard_id_t xx_id(void) const{ + dboard_id_t xx_id(void) const + { UHD_ASSERT_THROW(not this->is_xcvr()); return this->_rx_id; } - dboard_id_t rx_id(void) const{ + dboard_id_t rx_id(void) const + { UHD_ASSERT_THROW(this->is_xcvr()); return this->_rx_id; } - dboard_id_t tx_id(void) const{ + dboard_id_t tx_id(void) const + { UHD_ASSERT_THROW(this->is_xcvr()); return this->_tx_id; } - bool is_xcvr(void) const{ + bool is_xcvr(void) const + { return this->_xcvr; } - bool is_restricted(void) const{ + bool is_restricted(void) const + { return this->_restricted; } @@ -59,7 +69,8 @@ private: bool _restricted; }; -bool operator==(const dboard_key_t &lhs, const dboard_key_t &rhs){ +bool operator==(const dboard_key_t& lhs, const dboard_key_t& rhs) +{ if (lhs.is_xcvr() and rhs.is_xcvr()) return lhs.rx_id() == rhs.rx_id() and lhs.tx_id() == rhs.tx_id(); if (not lhs.is_xcvr() and not rhs.is_xcvr()) @@ -70,114 +81,132 @@ bool operator==(const dboard_key_t &lhs, const dboard_key_t &rhs){ /*********************************************************************** * storage and registering for dboards **********************************************************************/ -//dboard registry tuple: dboard constructor, canonical name, subdev names, container constructor -typedef std::tuple<dboard_manager::dboard_ctor_t, std::string, std::vector<std::string>, dboard_manager::dboard_ctor_t> args_t; - -//map a dboard id to a dboard constructor +// dboard registry tuple: dboard constructor, canonical name, subdev names, container +// constructor +typedef std::tuple<dboard_manager::dboard_ctor_t, + std::string, + std::vector<std::string>, + dboard_manager::dboard_ctor_t> + args_t; + +// map a dboard id to a dboard constructor typedef uhd::dict<dboard_key_t, args_t> id_to_args_map_t; UHD_SINGLETON_FCN(id_to_args_map_t, get_id_to_args_map) -static void register_dboard_key( - const dboard_key_t &dboard_key, +static void register_dboard_key(const dboard_key_t& dboard_key, dboard_manager::dboard_ctor_t db_subdev_ctor, - const std::string &name, - const std::vector<std::string> &subdev_names, - dboard_manager::dboard_ctor_t db_container_ctor -){ + const std::string& name, + const std::vector<std::string>& subdev_names, + dboard_manager::dboard_ctor_t db_container_ctor) +{ // UHD_LOGGER_TRACE("DBMGR") << "registering: " << name; - if (get_id_to_args_map().has_key(dboard_key)){ - - if (dboard_key.is_xcvr()) throw uhd::key_error(str(boost::format( - "The dboard id pair [%s, %s] is already registered to %s." - ) % dboard_key.rx_id().to_string() % dboard_key.tx_id().to_string() % std::get<1>(get_id_to_args_map()[dboard_key]))); - - else throw uhd::key_error(str(boost::format( - "The dboard id %s is already registered to %s." - ) % dboard_key.xx_id().to_string() % std::get<1>(get_id_to_args_map()[dboard_key]))); + if (get_id_to_args_map().has_key(dboard_key)) { + if (dboard_key.is_xcvr()) + throw uhd::key_error(str( + boost::format("The dboard id pair [%s, %s] is already registered to %s.") + % dboard_key.rx_id().to_string() % dboard_key.tx_id().to_string() + % std::get<1>(get_id_to_args_map()[dboard_key]))); + + else + throw uhd::key_error( + str(boost::format("The dboard id %s is already registered to %s.") + % dboard_key.xx_id().to_string() + % std::get<1>(get_id_to_args_map()[dboard_key]))); } - get_id_to_args_map()[dboard_key] = args_t(db_subdev_ctor, name, subdev_names, db_container_ctor); + get_id_to_args_map()[dboard_key] = + args_t(db_subdev_ctor, name, subdev_names, db_container_ctor); } -void dboard_manager::register_dboard( - const dboard_id_t &dboard_id, +void dboard_manager::register_dboard(const dboard_id_t& dboard_id, dboard_ctor_t db_subdev_ctor, - const std::string &name, - const std::vector<std::string> &subdev_names, - dboard_ctor_t db_container_ctor -){ - register_dboard_key(dboard_key_t(dboard_id), db_subdev_ctor, name, subdev_names, db_container_ctor); + const std::string& name, + const std::vector<std::string>& subdev_names, + dboard_ctor_t db_container_ctor) +{ + register_dboard_key( + dboard_key_t(dboard_id), db_subdev_ctor, name, subdev_names, db_container_ctor); } -void dboard_manager::register_dboard( - const dboard_id_t &rx_dboard_id, - const dboard_id_t &tx_dboard_id, +void dboard_manager::register_dboard(const dboard_id_t& rx_dboard_id, + const dboard_id_t& tx_dboard_id, dboard_ctor_t db_subdev_ctor, - const std::string &name, - const std::vector<std::string> &subdev_names, - dboard_ctor_t db_container_ctor -){ - register_dboard_key(dboard_key_t(rx_dboard_id, tx_dboard_id), db_subdev_ctor, name, subdev_names, db_container_ctor); + const std::string& name, + const std::vector<std::string>& subdev_names, + dboard_ctor_t db_container_ctor) +{ + register_dboard_key(dboard_key_t(rx_dboard_id, tx_dboard_id), + db_subdev_ctor, + name, + subdev_names, + db_container_ctor); } -void dboard_manager::register_dboard_restricted( - const dboard_id_t &dboard_id, +void dboard_manager::register_dboard_restricted(const dboard_id_t& dboard_id, dboard_ctor_t db_subdev_ctor, - const std::string &name, - const std::vector<std::string> &subdev_names, - dboard_ctor_t db_container_ctor -){ - register_dboard_key(dboard_key_t(dboard_id, true), db_subdev_ctor, name, subdev_names, db_container_ctor); + const std::string& name, + const std::vector<std::string>& subdev_names, + dboard_ctor_t db_container_ctor) +{ + register_dboard_key(dboard_key_t(dboard_id, true), + db_subdev_ctor, + name, + subdev_names, + db_container_ctor); } -void dboard_manager::register_dboard_restricted( - const dboard_id_t &rx_dboard_id, - const dboard_id_t &tx_dboard_id, +void dboard_manager::register_dboard_restricted(const dboard_id_t& rx_dboard_id, + const dboard_id_t& tx_dboard_id, dboard_ctor_t db_subdev_ctor, - const std::string &name, - const std::vector<std::string> &subdev_names, - dboard_ctor_t db_container_ctor -){ - register_dboard_key(dboard_key_t(rx_dboard_id, tx_dboard_id, true), db_subdev_ctor, name, subdev_names, db_container_ctor); + const std::string& name, + const std::vector<std::string>& subdev_names, + dboard_ctor_t db_container_ctor) +{ + register_dboard_key(dboard_key_t(rx_dboard_id, tx_dboard_id, true), + db_subdev_ctor, + name, + subdev_names, + db_container_ctor); } -std::string dboard_id_t::to_cname(void) const{ +std::string dboard_id_t::to_cname(void) const +{ std::string cname; - for(const dboard_key_t &key: get_id_to_args_map().keys()){ - if ( - (not key.is_xcvr() and *this == key.xx_id()) or - (key.is_xcvr() and (*this == key.rx_id() or *this == key.tx_id())) - ){ - if (not cname.empty()) cname += ", "; + for (const dboard_key_t& key : get_id_to_args_map().keys()) { + if ((not key.is_xcvr() and *this == key.xx_id()) + or (key.is_xcvr() and (*this == key.rx_id() or *this == key.tx_id()))) { + if (not cname.empty()) + cname += ", "; cname += std::get<1>(get_id_to_args_map()[key]); } } - return (cname.empty())? "Unknown" : cname; + return (cname.empty()) ? "Unknown" : cname; } -std::string dboard_id_t::to_pp_string(void) const{ +std::string dboard_id_t::to_pp_string(void) const +{ return str(boost::format("%s (%s)") % this->to_cname() % this->to_string()); } /*********************************************************************** * dboard manager implementation class **********************************************************************/ -class dboard_manager_impl : public dboard_manager{ - +class dboard_manager_impl : public dboard_manager +{ public: - dboard_manager_impl( - dboard_eeprom_t rx_eeprom, + dboard_manager_impl(dboard_eeprom_t rx_eeprom, dboard_eeprom_t tx_eeprom, dboard_iface::sptr iface, property_tree::sptr subtree, - bool defer_db_init - ); + bool defer_db_init); virtual ~dboard_manager_impl(void); - inline const std::vector<std::string>& get_rx_frontends() const { + inline const std::vector<std::string>& get_rx_frontends() const + { return _rx_frontends; } - inline const std::vector<std::string>& get_tx_frontends() const { + inline const std::vector<std::string>& get_tx_frontends() const + { return _tx_frontends; } @@ -185,15 +214,15 @@ public: private: void init(dboard_eeprom_t, dboard_eeprom_t, property_tree::sptr, bool); - //list of rx and tx dboards in this dboard_manager - //each dboard here is actually a subdevice proxy - //the subdevice proxy is internal to the cpp file + // list of rx and tx dboards in this dboard_manager + // each dboard here is actually a subdevice proxy + // the subdevice proxy is internal to the cpp file uhd::dict<std::string, dboard_base::sptr> _rx_dboards; uhd::dict<std::string, dboard_base::sptr> _tx_dboards; - std::vector<dboard_base::sptr> _rx_containers; - std::vector<dboard_base::sptr> _tx_containers; - std::vector<std::string> _rx_frontends; - std::vector<std::string> _tx_frontends; + std::vector<dboard_base::sptr> _rx_containers; + std::vector<dboard_base::sptr> _tx_containers; + std::vector<std::string> _rx_frontends; + std::vector<std::string> _tx_frontends; dboard_iface::sptr _iface; void set_nice_dboard_if(void); }; @@ -201,150 +230,154 @@ private: /*********************************************************************** * make routine for dboard manager **********************************************************************/ -dboard_manager::sptr dboard_manager::make( - dboard_id_t rx_dboard_id, +dboard_manager::sptr dboard_manager::make(dboard_id_t rx_dboard_id, dboard_id_t tx_dboard_id, dboard_id_t gdboard_id, dboard_iface::sptr iface, property_tree::sptr subtree, - bool defer_db_init -){ + bool defer_db_init) +{ dboard_eeprom_t rx_eeprom; dboard_eeprom_t tx_eeprom; rx_eeprom.id = rx_dboard_id; tx_eeprom.id = (gdboard_id == dboard_id_t::none()) ? tx_dboard_id : gdboard_id; return dboard_manager::sptr( - new dboard_manager_impl( - rx_eeprom, - tx_eeprom, - iface, subtree, defer_db_init - ) - ); + new dboard_manager_impl(rx_eeprom, tx_eeprom, iface, subtree, defer_db_init)); } -dboard_manager::sptr dboard_manager::make( - dboard_eeprom_t rx_eeprom, +dboard_manager::sptr dboard_manager::make(dboard_eeprom_t rx_eeprom, dboard_eeprom_t tx_eeprom, dboard_eeprom_t gdb_eeprom, dboard_iface::sptr iface, property_tree::sptr subtree, - bool defer_db_init -){ - return dboard_manager::sptr( - new dboard_manager_impl( - rx_eeprom, - (gdb_eeprom.id == dboard_id_t::none())? tx_eeprom : gdb_eeprom, - iface, subtree, defer_db_init - ) - ); + bool defer_db_init) +{ + return dboard_manager::sptr(new dboard_manager_impl(rx_eeprom, + (gdb_eeprom.id == dboard_id_t::none()) ? tx_eeprom : gdb_eeprom, + iface, + subtree, + defer_db_init)); } /*********************************************************************** * implementation class methods **********************************************************************/ -dboard_manager_impl::dboard_manager_impl( - dboard_eeprom_t rx_eeprom, +dboard_manager_impl::dboard_manager_impl(dboard_eeprom_t rx_eeprom, dboard_eeprom_t tx_eeprom, dboard_iface::sptr iface, property_tree::sptr subtree, - bool defer_db_init -): - _iface(iface) + bool defer_db_init) + : _iface(iface) { - try{ + try { this->init(rx_eeprom, tx_eeprom, subtree, defer_db_init); - } - catch(const std::exception &e){ - UHD_LOGGER_ERROR("DBMGR") << boost::format( - "The daughterboard manager encountered a recoverable error in init.\n" - "Loading the \"unknown\" daughterboard implementations to continue.\n" - "The daughterboard cannot operate until this error is resolved.\n" - ) << e.what() ; - //clean up the stuff added by the call above - if (subtree->exists("rx_frontends")) subtree->remove("rx_frontends"); - if (subtree->exists("tx_frontends")) subtree->remove("tx_frontends"); - if (subtree->exists("iface")) subtree->remove("iface"); + } catch (const std::exception& e) { + UHD_LOGGER_ERROR("DBMGR") + << boost::format( + "The daughterboard manager encountered a recoverable error in init.\n" + "Loading the \"unknown\" daughterboard implementations to continue.\n" + "The daughterboard cannot operate until this error is resolved.\n") + << e.what(); + // clean up the stuff added by the call above + if (subtree->exists("rx_frontends")) + subtree->remove("rx_frontends"); + if (subtree->exists("tx_frontends")) + subtree->remove("tx_frontends"); + if (subtree->exists("iface")) + subtree->remove("iface"); dboard_eeprom_t dummy_eeprom; dummy_eeprom.id = dboard_id_t::none(); this->init(dummy_eeprom, dummy_eeprom, subtree, false); } } -void dboard_manager_impl::init( - dboard_eeprom_t rx_eeprom, +void dboard_manager_impl::init(dboard_eeprom_t rx_eeprom, dboard_eeprom_t tx_eeprom, property_tree::sptr subtree, - bool defer_db_init -){ - //find the dboard key matches for the dboard ids + bool defer_db_init) +{ + // find the dboard key matches for the dboard ids dboard_key_t rx_dboard_key, tx_dboard_key, xcvr_dboard_key; - for(const dboard_key_t &key: get_id_to_args_map().keys()){ - if (key.is_xcvr()){ - if (rx_eeprom.id == key.rx_id() and tx_eeprom.id == key.tx_id()) xcvr_dboard_key = key; - if (rx_eeprom.id == key.rx_id()) rx_dboard_key = key; //kept to handle warning - if (rx_eeprom.id == key.tx_id()) tx_dboard_key = key; //kept to handle warning - } - else{ - if (rx_eeprom.id == key.xx_id()) rx_dboard_key = key; - if (tx_eeprom.id == key.xx_id()) tx_dboard_key = key; + for (const dboard_key_t& key : get_id_to_args_map().keys()) { + if (key.is_xcvr()) { + if (rx_eeprom.id == key.rx_id() and tx_eeprom.id == key.tx_id()) + xcvr_dboard_key = key; + if (rx_eeprom.id == key.rx_id()) + rx_dboard_key = key; // kept to handle warning + if (rx_eeprom.id == key.tx_id()) + tx_dboard_key = key; // kept to handle warning + } else { + if (rx_eeprom.id == key.xx_id()) + rx_dboard_key = key; + if (tx_eeprom.id == key.xx_id()) + tx_dboard_key = key; } } - //warn for invalid dboard id xcvr combinations - if (not xcvr_dboard_key.is_xcvr() and (rx_dboard_key.is_xcvr() or tx_dboard_key.is_xcvr())){ - UHD_LOGGER_WARNING("DBMGR") << boost::format( - "Unknown transceiver board ID combination.\n" - "Is your daughter-board mounted properly?\n" - "RX dboard ID: %s\n" - "TX dboard ID: %s\n" - ) % rx_eeprom.id.to_pp_string() % tx_eeprom.id.to_pp_string(); + // warn for invalid dboard id xcvr combinations + if (not xcvr_dboard_key.is_xcvr() + and (rx_dboard_key.is_xcvr() or tx_dboard_key.is_xcvr())) { + UHD_LOGGER_WARNING("DBMGR") + << boost::format("Unknown transceiver board ID combination.\n" + "Is your daughter-board mounted properly?\n" + "RX dboard ID: %s\n" + "TX dboard ID: %s\n") + % rx_eeprom.id.to_pp_string() % tx_eeprom.id.to_pp_string(); } - //initialize the gpio pins before creating subdevs + // initialize the gpio pins before creating subdevs set_nice_dboard_if(); - //conditionally register the dboard iface in the tree - if (not (rx_dboard_key.is_restricted() or tx_dboard_key.is_restricted() or xcvr_dboard_key.is_restricted())) { + // conditionally register the dboard iface in the tree + if (not(rx_dboard_key.is_restricted() or tx_dboard_key.is_restricted() + or xcvr_dboard_key.is_restricted())) { subtree->create<dboard_iface::sptr>("iface").set(_iface); } - //dboard constructor args + // dboard constructor args dboard_ctor_args_t db_ctor_args; db_ctor_args.db_iface = _iface; - //make xcvr subdevs - if (xcvr_dboard_key.is_xcvr()){ - - //extract data for the xcvr dboard key - dboard_ctor_t subdev_ctor; std::string name; std::vector<std::string> subdevs; dboard_ctor_t container_ctor; - std::tie(subdev_ctor, name, subdevs, container_ctor) = get_id_to_args_map()[xcvr_dboard_key]; - - //create the container class. - //a container class exists per N subdevs registered in a register_dboard* call - db_ctor_args.sd_name = "common"; - db_ctor_args.rx_eeprom = rx_eeprom; - db_ctor_args.tx_eeprom = tx_eeprom; - db_ctor_args.rx_subtree = subtree->subtree("rx_frontends/" + db_ctor_args.sd_name); - db_ctor_args.tx_subtree = subtree->subtree("tx_frontends/" + db_ctor_args.sd_name); + // make xcvr subdevs + if (xcvr_dboard_key.is_xcvr()) { + // extract data for the xcvr dboard key + dboard_ctor_t subdev_ctor; + std::string name; + std::vector<std::string> subdevs; + dboard_ctor_t container_ctor; + std::tie(subdev_ctor, name, subdevs, container_ctor) = + get_id_to_args_map()[xcvr_dboard_key]; + + // create the container class. + // a container class exists per N subdevs registered in a register_dboard* call + db_ctor_args.sd_name = "common"; + db_ctor_args.rx_eeprom = rx_eeprom; + db_ctor_args.tx_eeprom = tx_eeprom; + db_ctor_args.rx_subtree = + subtree->subtree("rx_frontends/" + db_ctor_args.sd_name); + db_ctor_args.tx_subtree = + subtree->subtree("tx_frontends/" + db_ctor_args.sd_name); if (container_ctor) { db_ctor_args.rx_container = container_ctor(&db_ctor_args); } else { db_ctor_args.rx_container = dboard_base::sptr(); } - db_ctor_args.tx_container = db_ctor_args.rx_container; //Same TX and RX container + db_ctor_args.tx_container = db_ctor_args.rx_container; // Same TX and RX container - //create the xcvr object for each subdevice - for(const std::string &subdev: subdevs){ + // create the xcvr object for each subdevice + for (const std::string& subdev : subdevs) { db_ctor_args.sd_name = subdev; - db_ctor_args.rx_subtree = subtree->subtree("rx_frontends/" + db_ctor_args.sd_name); - db_ctor_args.tx_subtree = subtree->subtree("tx_frontends/" + db_ctor_args.sd_name); + db_ctor_args.rx_subtree = + subtree->subtree("rx_frontends/" + db_ctor_args.sd_name); + db_ctor_args.tx_subtree = + subtree->subtree("tx_frontends/" + db_ctor_args.sd_name); dboard_base::sptr xcvr_dboard = subdev_ctor(&db_ctor_args); - _rx_dboards[subdev] = xcvr_dboard; - _tx_dboards[subdev] = xcvr_dboard; + _rx_dboards[subdev] = xcvr_dboard; + _tx_dboards[subdev] = xcvr_dboard; xcvr_dboard->initialize(); } - //initialize the container after all subdevs have been created + // initialize the container after all subdevs have been created if (container_ctor) { if (defer_db_init) { _rx_containers.push_back(db_ctor_args.rx_container); @@ -353,30 +386,34 @@ void dboard_manager_impl::init( } } - //Populate frontend names in-order. - //We cannot use _xx_dboards.keys() here because of the ordering requirement + // Populate frontend names in-order. + // We cannot use _xx_dboards.keys() here because of the ordering requirement _rx_frontends = subdevs; _tx_frontends = subdevs; } - //make tx and rx subdevs (separate subdevs for rx and tx dboards) - else - { - //force the rx key to the unknown board for bad combinations - if (rx_dboard_key.is_xcvr() or rx_dboard_key.xx_id() == dboard_id_t::none()){ + // make tx and rx subdevs (separate subdevs for rx and tx dboards) + else { + // force the rx key to the unknown board for bad combinations + if (rx_dboard_key.is_xcvr() or rx_dboard_key.xx_id() == dboard_id_t::none()) { rx_dboard_key = dboard_key_t(0xfff1); } - //extract data for the rx dboard key - dboard_ctor_t rx_dboard_ctor; std::string rx_name; std::vector<std::string> rx_subdevs; dboard_ctor_t rx_cont_ctor; - std::tie(rx_dboard_ctor, rx_name, rx_subdevs, rx_cont_ctor) = get_id_to_args_map()[rx_dboard_key]; - - //create the container class. - //a container class exists per N subdevs registered in a register_dboard* call - db_ctor_args.sd_name = "common"; - db_ctor_args.rx_eeprom = rx_eeprom; + // extract data for the rx dboard key + dboard_ctor_t rx_dboard_ctor; + std::string rx_name; + std::vector<std::string> rx_subdevs; + dboard_ctor_t rx_cont_ctor; + std::tie(rx_dboard_ctor, rx_name, rx_subdevs, rx_cont_ctor) = + get_id_to_args_map()[rx_dboard_key]; + + // create the container class. + // a container class exists per N subdevs registered in a register_dboard* call + db_ctor_args.sd_name = "common"; + db_ctor_args.rx_eeprom = rx_eeprom; db_ctor_args.tx_eeprom.id = dboard_id_t::none(); - db_ctor_args.rx_subtree = subtree->subtree("rx_frontends/" + db_ctor_args.sd_name); + db_ctor_args.rx_subtree = + subtree->subtree("rx_frontends/" + db_ctor_args.sd_name); db_ctor_args.tx_subtree = property_tree::sptr(); if (rx_cont_ctor) { db_ctor_args.rx_container = rx_cont_ctor(&db_ctor_args); @@ -384,15 +421,16 @@ void dboard_manager_impl::init( db_ctor_args.rx_container = dboard_base::sptr(); } - //make the rx subdevs - for(const std::string &subdev: rx_subdevs){ + // make the rx subdevs + for (const std::string& subdev : rx_subdevs) { db_ctor_args.sd_name = subdev; - db_ctor_args.rx_subtree = subtree->subtree("rx_frontends/" + db_ctor_args.sd_name); + db_ctor_args.rx_subtree = + subtree->subtree("rx_frontends/" + db_ctor_args.sd_name); _rx_dboards[subdev] = rx_dboard_ctor(&db_ctor_args); _rx_dboards[subdev]->initialize(); } - //initialize the container after all subdevs have been created + // initialize the container after all subdevs have been created if (rx_cont_ctor) { if (defer_db_init) { _rx_containers.push_back(db_ctor_args.rx_container); @@ -401,37 +439,43 @@ void dboard_manager_impl::init( } } - //force the tx key to the unknown board for bad combinations - if (tx_dboard_key.is_xcvr() or tx_dboard_key.xx_id() == dboard_id_t::none()){ + // force the tx key to the unknown board for bad combinations + if (tx_dboard_key.is_xcvr() or tx_dboard_key.xx_id() == dboard_id_t::none()) { tx_dboard_key = dboard_key_t(0xfff0); } - //extract data for the tx dboard key - dboard_ctor_t tx_dboard_ctor; std::string tx_name; std::vector<std::string> tx_subdevs; dboard_ctor_t tx_cont_ctor; - std::tie(tx_dboard_ctor, tx_name, tx_subdevs, tx_cont_ctor) = get_id_to_args_map()[tx_dboard_key]; - - //create the container class. - //a container class exists per N subdevs registered in a register_dboard* call - db_ctor_args.sd_name = "common"; + // extract data for the tx dboard key + dboard_ctor_t tx_dboard_ctor; + std::string tx_name; + std::vector<std::string> tx_subdevs; + dboard_ctor_t tx_cont_ctor; + std::tie(tx_dboard_ctor, tx_name, tx_subdevs, tx_cont_ctor) = + get_id_to_args_map()[tx_dboard_key]; + + // create the container class. + // a container class exists per N subdevs registered in a register_dboard* call + db_ctor_args.sd_name = "common"; db_ctor_args.rx_eeprom.id = dboard_id_t::none(); - db_ctor_args.tx_eeprom = tx_eeprom; - db_ctor_args.rx_subtree = property_tree::sptr(); - db_ctor_args.tx_subtree = subtree->subtree("tx_frontends/" + db_ctor_args.sd_name); + db_ctor_args.tx_eeprom = tx_eeprom; + db_ctor_args.rx_subtree = property_tree::sptr(); + db_ctor_args.tx_subtree = + subtree->subtree("tx_frontends/" + db_ctor_args.sd_name); if (tx_cont_ctor) { db_ctor_args.tx_container = tx_cont_ctor(&db_ctor_args); } else { db_ctor_args.tx_container = dboard_base::sptr(); } - //make the tx subdevs - for(const std::string &subdev: tx_subdevs){ + // make the tx subdevs + for (const std::string& subdev : tx_subdevs) { db_ctor_args.sd_name = subdev; - db_ctor_args.tx_subtree = subtree->subtree("tx_frontends/" + db_ctor_args.sd_name); + db_ctor_args.tx_subtree = + subtree->subtree("tx_frontends/" + db_ctor_args.sd_name); _tx_dboards[subdev] = tx_dboard_ctor(&db_ctor_args); _tx_dboards[subdev]->initialize(); } - //initialize the container after all subdevs have been created + // initialize the container after all subdevs have been created if (tx_cont_ctor) { if (defer_db_init) { _tx_containers.push_back(db_ctor_args.tx_container); @@ -440,39 +484,40 @@ void dboard_manager_impl::init( } } - //Populate frontend names in-order. - //We cannot use _xx_dboards.keys() here because of the ordering requirement + // Populate frontend names in-order. + // We cannot use _xx_dboards.keys() here because of the ordering requirement _rx_frontends = rx_subdevs; _tx_frontends = tx_subdevs; } } -void dboard_manager_impl::initialize_dboards(void) { - for(dboard_base::sptr& _rx_container: _rx_containers) { +void dboard_manager_impl::initialize_dboards(void) +{ + for (dboard_base::sptr& _rx_container : _rx_containers) { _rx_container->initialize(); } - for(dboard_base::sptr& _tx_container: _tx_containers) { + for (dboard_base::sptr& _tx_container : _tx_containers) { _tx_container->initialize(); } } -dboard_manager_impl::~dboard_manager_impl(void){UHD_SAFE_CALL( - set_nice_dboard_if(); -)} +dboard_manager_impl::~dboard_manager_impl(void) +{ + UHD_SAFE_CALL(set_nice_dboard_if();) +} -void dboard_manager_impl::set_nice_dboard_if(void){ - //make a list of possible unit types +void dboard_manager_impl::set_nice_dboard_if(void) +{ + // make a list of possible unit types const std::vector<dboard_iface::unit_t> units{ - dboard_iface::UNIT_RX, - dboard_iface::UNIT_TX - }; - - //set nice settings on each unit - for(dboard_iface::unit_t unit: units){ - _iface->set_gpio_ddr(unit, 0x0000); //all inputs - _iface->set_gpio_out(unit, 0x0000); //all low - _iface->set_pin_ctrl(unit, 0x0000); //all gpio - _iface->set_clock_enabled(unit, false); //clock off + dboard_iface::UNIT_RX, dboard_iface::UNIT_TX}; + + // set nice settings on each unit + for (dboard_iface::unit_t unit : units) { + _iface->set_gpio_ddr(unit, 0x0000); // all inputs + _iface->set_gpio_out(unit, 0x0000); // all low + _iface->set_pin_ctrl(unit, 0x0000); // all gpio + _iface->set_clock_enabled(unit, false); // clock off } } diff --git a/host/lib/usrp/fe_connection.cpp b/host/lib/usrp/fe_connection.cpp index 8e3c0c88b..73c0020f8 100644 --- a/host/lib/usrp/fe_connection.cpp +++ b/host/lib/usrp/fe_connection.cpp @@ -5,35 +5,42 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/usrp/fe_connection.hpp> #include <uhd/exception.hpp> -#include <regex> +#include <uhd/usrp/fe_connection.hpp> #include <uhd/utils/math.hpp> +#include <regex> using namespace uhd::usrp; -fe_connection_t::fe_connection_t( - sampling_t sampling_mode, bool iq_swapped, - bool i_inverted, bool q_inverted, double if_freq -) : _sampling_mode(sampling_mode), _iq_swapped(iq_swapped), - _i_inverted(i_inverted), _q_inverted(q_inverted), _if_freq(if_freq) +fe_connection_t::fe_connection_t(sampling_t sampling_mode, + bool iq_swapped, + bool i_inverted, + bool q_inverted, + double if_freq) + : _sampling_mode(sampling_mode) + , _iq_swapped(iq_swapped) + , _i_inverted(i_inverted) + , _q_inverted(q_inverted) + , _if_freq(if_freq) { } -fe_connection_t::fe_connection_t(const std::string& conn_str, double if_freq) { +fe_connection_t::fe_connection_t(const std::string& conn_str, double if_freq) +{ static const std::regex conn_regex("([IQ])(b?)(([IQ])(b?))?"); std::cmatch matches; if (std::regex_match(conn_str.c_str(), matches, conn_regex)) { if (matches[3].length() == 0) { - //Connection in {I, Q, Ib, Qb} + // Connection in {I, Q, Ib, Qb} _sampling_mode = REAL; - _iq_swapped = (matches[1].str() == "Q"); - _i_inverted = (matches[2].length() != 0); - _q_inverted = false; //IQ is swapped after inversion + _iq_swapped = (matches[1].str() == "Q"); + _i_inverted = (matches[2].length() != 0); + _q_inverted = false; // IQ is swapped after inversion } else { - //Connection in {I(b?)Q(b?), Q(b?)I(b?), I(b?)I(b?), Q(b?)Q(b?)} - _sampling_mode = (matches[1].str() == matches[4].str()) ? HETERODYNE : QUADRATURE; - _iq_swapped = (matches[1].str() == "Q"); + // Connection in {I(b?)Q(b?), Q(b?)I(b?), I(b?)I(b?), Q(b?)Q(b?)} + _sampling_mode = (matches[1].str() == matches[4].str()) ? HETERODYNE + : QUADRATURE; + _iq_swapped = (matches[1].str() == "Q"); size_t i_idx = _iq_swapped ? 5 : 2, q_idx = _iq_swapped ? 2 : 5; _i_inverted = (matches[i_idx].length() != 0); _q_inverted = (matches[q_idx].length() != 0); @@ -48,10 +55,11 @@ fe_connection_t::fe_connection_t(const std::string& conn_str, double if_freq) { } } -bool uhd::usrp::operator==(const fe_connection_t &lhs, const fe_connection_t &rhs){ - return ((lhs.get_sampling_mode() == rhs.get_sampling_mode()) and - (lhs.is_iq_swapped() == rhs.is_iq_swapped()) and - (lhs.is_i_inverted() == rhs.is_i_inverted()) and - (lhs.is_q_inverted() == rhs.is_q_inverted()) and - uhd::math::frequencies_are_equal(lhs.get_if_freq(), rhs.get_if_freq())); +bool uhd::usrp::operator==(const fe_connection_t& lhs, const fe_connection_t& rhs) +{ + return ((lhs.get_sampling_mode() == rhs.get_sampling_mode()) + and (lhs.is_iq_swapped() == rhs.is_iq_swapped()) + and (lhs.is_i_inverted() == rhs.is_i_inverted()) + and (lhs.is_q_inverted() == rhs.is_q_inverted()) + and uhd::math::frequencies_are_equal(lhs.get_if_freq(), rhs.get_if_freq())); } diff --git a/host/lib/usrp/fe_connection_python.hpp b/host/lib/usrp/fe_connection_python.hpp index d1304909e..247781981 100644 --- a/host/lib/usrp/fe_connection_python.hpp +++ b/host/lib/usrp/fe_connection_python.hpp @@ -18,8 +18,7 @@ void export_fe_connection(py::module& m) py::enum_<sampling_t>(m, "sampling") .value("QUADRATURE", sampling_t::QUADRATURE) .value("HETERODYNE", sampling_t::HETERODYNE) - .value("REAL" , sampling_t::REAL ) - ; + .value("REAL", sampling_t::REAL); py::class_<fe_connection_t>(m, "fe_connection") @@ -29,12 +28,11 @@ void export_fe_connection(py::module& m) // Methods .def("get_sampling_mode", &fe_connection_t::get_sampling_mode) - .def("is_iq_swapped" , &fe_connection_t::is_iq_swapped ) - .def("is_i_inverted" , &fe_connection_t::is_i_inverted ) - .def("is_q_inverted" , &fe_connection_t::is_q_inverted ) - .def("get_if_freq" , &fe_connection_t::get_if_freq ) - .def("set_if_freq" , &fe_connection_t::set_if_freq ) - ; + .def("is_iq_swapped", &fe_connection_t::is_iq_swapped) + .def("is_i_inverted", &fe_connection_t::is_i_inverted) + .def("is_q_inverted", &fe_connection_t::is_q_inverted) + .def("get_if_freq", &fe_connection_t::get_if_freq) + .def("set_if_freq", &fe_connection_t::set_if_freq); } #endif /* INCLUDED_UHD_USRP_FE_CONNECTION_PYTHON_HPP */ diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp index 07d7f4ec4..60866b85e 100644 --- a/host/lib/usrp/gps_ctrl.cpp +++ b/host/lib/usrp/gps_ctrl.cpp @@ -5,96 +5,94 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/usrp/gps_ctrl.hpp> - -#include <uhd/utils/log.hpp> #include <uhd/exception.hpp> #include <uhd/types/sensors.hpp> +#include <uhd/usrp/gps_ctrl.hpp> +#include <uhd/utils/log.hpp> +#include <stdint.h> #include <boost/algorithm/string.hpp> -#include <boost/thread/thread.hpp> -#include <boost/tokenizer.hpp> +#include <boost/date_time.hpp> #include <boost/format.hpp> -#include <regex> #include <boost/thread/mutex.hpp> -#include <boost/date_time.hpp> +#include <boost/thread/thread.hpp> +#include <boost/tokenizer.hpp> +#include <chrono> #include <ctime> +#include <regex> #include <string> -#include <tuple> #include <thread> -#include <chrono> -#include <stdint.h> +#include <tuple> using namespace uhd; using namespace boost::posix_time; using namespace boost::algorithm; namespace { - constexpr int GPS_COMM_TIMEOUT_MS = 1300; - constexpr int GPS_NMEA_NORMAL_FRESHNESS = 1000; - constexpr int GPS_SERVO_FRESHNESS = 1000; - constexpr int GPS_LOCK_FRESHNESS = 2500; - constexpr int GPS_TIMEOUT_DELAY_MS = 200; - constexpr int GPSDO_COMMAND_DELAY_MS = 200; -} +constexpr int GPS_COMM_TIMEOUT_MS = 1300; +constexpr int GPS_NMEA_NORMAL_FRESHNESS = 1000; +constexpr int GPS_SERVO_FRESHNESS = 1000; +constexpr int GPS_LOCK_FRESHNESS = 2500; +constexpr int GPS_TIMEOUT_DELAY_MS = 200; +constexpr int GPSDO_COMMAND_DELAY_MS = 200; +} // namespace /*! * A control for GPSDO devices */ -gps_ctrl::~gps_ctrl(void){ +gps_ctrl::~gps_ctrl(void) +{ /* NOP */ } -class gps_ctrl_impl : public gps_ctrl{ +class gps_ctrl_impl : public gps_ctrl +{ private: std::map<std::string, std::tuple<std::string, boost::system_time, bool>> sentences; boost::mutex cache_mutex; boost::system_time _last_cache_update; - std::string get_sentence(const std::string which, const int max_age_ms, const int timeout, const bool wait_for_next = false) + std::string get_sentence(const std::string which, + const int max_age_ms, + const int timeout, + const bool wait_for_next = false) { std::string sentence; - boost::system_time now = boost::get_system_time(); + boost::system_time now = boost::get_system_time(); boost::system_time exit_time = now + milliseconds(timeout); boost::posix_time::time_duration age; - if (wait_for_next) - { + if (wait_for_next) { boost::lock_guard<boost::mutex> lock(cache_mutex); update_cache(); - //mark sentence as touched + // mark sentence as touched if (sentences.find(which) != sentences.end()) std::get<2>(sentences[which]) = true; } - while (1) - { - try - { + while (1) { + try { boost::lock_guard<boost::mutex> lock(cache_mutex); // update cache if older than a millisecond - if (now - _last_cache_update > milliseconds(1)) - { + if (now - _last_cache_update > milliseconds(1)) { update_cache(); } - if (sentences.find(which) == sentences.end()) - { + if (sentences.find(which) == sentences.end()) { age = milliseconds(max_age_ms); } else { age = boost::get_system_time() - std::get<1>(sentences[which]); } - if (age < milliseconds(max_age_ms) and (not (wait_for_next and std::get<2>(sentences[which])))) - { - sentence = std::get<0>(sentences[which]); + if (age < milliseconds(max_age_ms) + and (not(wait_for_next and std::get<2>(sentences[which])))) { + sentence = std::get<0>(sentences[which]); std::get<2>(sentences[which]) = true; } - } catch(std::exception &e) { + } catch (std::exception& e) { UHD_LOGGER_DEBUG("GPS") << "get_sentence: " << e.what(); } - if (not sentence.empty() or now > exit_time) - { + if (not sentence.empty() or now > exit_time) { break; } @@ -102,8 +100,7 @@ private: now = boost::get_system_time(); } - if (sentence.empty()) - { + if (sentence.empty()) { throw uhd::value_error("gps ctrl: No " + which + " message found"); } @@ -112,7 +109,7 @@ private: static bool is_nmea_checksum_ok(std::string nmea) { - if (nmea.length() < 5 || nmea[0] != '$' || nmea[nmea.length()-3] != '*') + if (nmea.length() < 5 || nmea[0] != '$' || nmea[nmea.length() - 3] != '*') return false; std::stringstream ss; @@ -120,310 +117,307 @@ private: uint32_t calculated_crc = 0; // get crc from string - ss << std::hex << nmea.substr(nmea.length()-2, 2); + ss << std::hex << nmea.substr(nmea.length() - 2, 2); ss >> string_crc; // calculate crc - for (size_t i = 1; i < nmea.length()-3; i++) + for (size_t i = 1; i < nmea.length() - 3; i++) calculated_crc ^= nmea[i]; // return comparison return (string_crc == calculated_crc); } - void update_cache() { - if(not gps_detected()) { - return; - } - - const std::list<std::string> keys{"GPGGA", "GPRMC", "SERVO"}; - static const std::regex servo_regex("^\\d\\d-\\d\\d-\\d\\d.*$"); - static const std::regex gp_msg_regex("^\\$GP.*,\\*[0-9A-F]{2}$"); - std::map<std::string,std::string> msgs; - - // Get all GPSDO messages available - // Creating a map here because we only want the latest of each message type - for (std::string msg = _recv(0); not msg.empty(); msg = _recv(0)) + void update_cache() { - // Strip any end of line characters - erase_all(msg, "\r"); - erase_all(msg, "\n"); - - if (msg.empty()) - { - // Ignore empty strings - continue; + if (not gps_detected()) { + return; } - if (msg.length() < 6) - { - UHD_LOGGER_WARNING("GPS") << __FUNCTION__ << ": Short GPSDO string: " << msg ; - continue; - } + const std::list<std::string> keys{"GPGGA", "GPRMC", "SERVO"}; + static const std::regex servo_regex("^\\d\\d-\\d\\d-\\d\\d.*$"); + static const std::regex gp_msg_regex("^\\$GP.*,\\*[0-9A-F]{2}$"); + std::map<std::string, std::string> msgs; + + // Get all GPSDO messages available + // Creating a map here because we only want the latest of each message type + for (std::string msg = _recv(0); not msg.empty(); msg = _recv(0)) { + // Strip any end of line characters + erase_all(msg, "\r"); + erase_all(msg, "\n"); + + if (msg.empty()) { + // Ignore empty strings + continue; + } - // Look for SERVO message - if (std::regex_search(msg, servo_regex, std::regex_constants::match_continuous)) - { - msgs["SERVO"] = msg; - } - else if (std::regex_match(msg, gp_msg_regex) and is_nmea_checksum_ok(msg)) - { - msgs[msg.substr(1,5)] = msg; - } - else - { - UHD_LOGGER_WARNING("GPS") << __FUNCTION__ << ": Malformed GPSDO string: " << msg ; + if (msg.length() < 6) { + UHD_LOGGER_WARNING("GPS") + << __FUNCTION__ << ": Short GPSDO string: " << msg; + continue; + } + + // Look for SERVO message + if (std::regex_search( + msg, servo_regex, std::regex_constants::match_continuous)) { + msgs["SERVO"] = msg; + } else if (std::regex_match(msg, gp_msg_regex) and is_nmea_checksum_ok(msg)) { + msgs[msg.substr(1, 5)] = msg; + } else { + UHD_LOGGER_WARNING("GPS") + << __FUNCTION__ << ": Malformed GPSDO string: " << msg; + } } - } - boost::system_time time = boost::get_system_time(); + boost::system_time time = boost::get_system_time(); - // Update sentences with newly read data - for(std::string key: keys) - { - if (not msgs[key].empty()) - { - sentences[key] = std::make_tuple(msgs[key], time, false); + // Update sentences with newly read data + for (std::string key : keys) { + if (not msgs[key].empty()) { + sentences[key] = std::make_tuple(msgs[key], time, false); + } } - } - _last_cache_update = time; - } - -public: - gps_ctrl_impl(uart_iface::sptr uart) : - _uart(uart), - _gps_type(GPS_TYPE_NONE) - { - - std::string reply; - bool i_heard_some_nmea = false, i_heard_something_weird = false; - - //first we look for an internal GPSDO - _flush(); //get whatever junk is in the rx buffer right now, and throw it away - - _send("*IDN?\r\n"); //request identity from the GPSDO - - //then we loop until we either timeout, or until we get a response that indicates we're a JL device - //maximum response time was measured at ~320ms, so we set the timeout at 650ms - const boost::system_time comm_timeout = boost::get_system_time() + milliseconds(650); - while(boost::get_system_time() < comm_timeout) { - reply = _recv(); - //known devices are JL "FireFly", "GPSTCXO", and "LC_XO" - if(reply.find("FireFly") != std::string::npos - or reply.find("LC_XO") != std::string::npos - or reply.find("GPSTCXO") != std::string::npos) { - _gps_type = GPS_TYPE_INTERNAL_GPSDO; - break; - } else if(reply.substr(0, 3) == "$GP") { - i_heard_some_nmea = true; //but keep looking - } else if(not reply.empty()) { - // wrong baud rate or firmware still initializing - i_heard_something_weird = true; - _send("*IDN?\r\n"); //re-send identity request - } else { - // _recv timed out - _send("*IDN?\r\n"); //re-send identity request - } + _last_cache_update = time; } - if (_gps_type == GPS_TYPE_NONE) +public: + gps_ctrl_impl(uart_iface::sptr uart) : _uart(uart), _gps_type(GPS_TYPE_NONE) { - if(i_heard_some_nmea) { - _gps_type = GPS_TYPE_GENERIC_NMEA; - } else if(i_heard_something_weird) { - UHD_LOGGER_ERROR("GPS") << "GPS invalid reply \"" << reply << "\", assuming none available"; + std::string reply; + bool i_heard_some_nmea = false, i_heard_something_weird = false; + + // first we look for an internal GPSDO + _flush(); // get whatever junk is in the rx buffer right now, and throw it away + + _send("*IDN?\r\n"); // request identity from the GPSDO + + // then we loop until we either timeout, or until we get a response that indicates + // we're a JL device maximum response time was measured at ~320ms, so we set the + // timeout at 650ms + const boost::system_time comm_timeout = + boost::get_system_time() + milliseconds(650); + while (boost::get_system_time() < comm_timeout) { + reply = _recv(); + // known devices are JL "FireFly", "GPSTCXO", and "LC_XO" + if (reply.find("FireFly") != std::string::npos + or reply.find("LC_XO") != std::string::npos + or reply.find("GPSTCXO") != std::string::npos) { + _gps_type = GPS_TYPE_INTERNAL_GPSDO; + break; + } else if (reply.substr(0, 3) == "$GP") { + i_heard_some_nmea = true; // but keep looking + } else if (not reply.empty()) { + // wrong baud rate or firmware still initializing + i_heard_something_weird = true; + _send("*IDN?\r\n"); // re-send identity request + } else { + // _recv timed out + _send("*IDN?\r\n"); // re-send identity request + } } - } - - switch(_gps_type) { - case GPS_TYPE_INTERNAL_GPSDO: - erase_all(reply, "\r"); - erase_all(reply, "\n"); - UHD_LOGGER_INFO("GPS") << "Found an internal GPSDO: " << reply; - init_gpsdo(); - break; - case GPS_TYPE_GENERIC_NMEA: - UHD_LOGGER_INFO("GPS") << "Found a generic NMEA GPS device"; - break; + if (_gps_type == GPS_TYPE_NONE) { + if (i_heard_some_nmea) { + _gps_type = GPS_TYPE_GENERIC_NMEA; + } else if (i_heard_something_weird) { + UHD_LOGGER_ERROR("GPS") + << "GPS invalid reply \"" << reply << "\", assuming none available"; + } + } - case GPS_TYPE_NONE: - default: - UHD_LOGGER_INFO("GPS") << "No GPSDO found"; - break; + switch (_gps_type) { + case GPS_TYPE_INTERNAL_GPSDO: + erase_all(reply, "\r"); + erase_all(reply, "\n"); + UHD_LOGGER_INFO("GPS") << "Found an internal GPSDO: " << reply; + init_gpsdo(); + break; - } + case GPS_TYPE_GENERIC_NMEA: + UHD_LOGGER_INFO("GPS") << "Found a generic NMEA GPS device"; + break; - // initialize cache - update_cache(); - } + case GPS_TYPE_NONE: + default: + UHD_LOGGER_INFO("GPS") << "No GPSDO found"; + break; + } - ~gps_ctrl_impl(void){ - /* NOP */ - } - - //return a list of supported sensors - std::vector<std::string> get_sensors(void) { - std::vector<std::string> ret{ - "gps_gpgga", - "gps_gprmc", - "gps_time", - "gps_locked", - "gps_servo" - }; - return ret; - } - - uhd::sensor_value_t get_sensor(std::string key) { - if(key == "gps_gpgga" - or key == "gps_gprmc") { - return sensor_value_t( - boost::to_upper_copy(key), - get_sentence(boost::to_upper_copy(key.substr(4,8)), GPS_NMEA_NORMAL_FRESHNESS, GPS_TIMEOUT_DELAY_MS), - ""); - } - else if(key == "gps_time") { - return sensor_value_t("GPS epoch time", int(get_epoch_time()), "seconds"); + // initialize cache + update_cache(); } - else if(key == "gps_locked") { - return sensor_value_t("GPS lock status", locked(), "locked", "unlocked"); + + ~gps_ctrl_impl(void) + { + /* NOP */ } - else if(key == "gps_servo") { - return sensor_value_t( - boost::to_upper_copy(key), - get_sentence(boost::to_upper_copy(key.substr(4,8)), GPS_SERVO_FRESHNESS, GPS_TIMEOUT_DELAY_MS), - ""); + + // return a list of supported sensors + std::vector<std::string> get_sensors(void) + { + std::vector<std::string> ret{ + "gps_gpgga", "gps_gprmc", "gps_time", "gps_locked", "gps_servo"}; + return ret; } - else { - throw uhd::value_error("gps ctrl get_sensor unknown key: " + key); + + uhd::sensor_value_t get_sensor(std::string key) + { + if (key == "gps_gpgga" or key == "gps_gprmc") { + return sensor_value_t(boost::to_upper_copy(key), + get_sentence(boost::to_upper_copy(key.substr(4, 8)), + GPS_NMEA_NORMAL_FRESHNESS, + GPS_TIMEOUT_DELAY_MS), + ""); + } else if (key == "gps_time") { + return sensor_value_t("GPS epoch time", int(get_epoch_time()), "seconds"); + } else if (key == "gps_locked") { + return sensor_value_t("GPS lock status", locked(), "locked", "unlocked"); + } else if (key == "gps_servo") { + return sensor_value_t(boost::to_upper_copy(key), + get_sentence(boost::to_upper_copy(key.substr(4, 8)), + GPS_SERVO_FRESHNESS, + GPS_TIMEOUT_DELAY_MS), + ""); + } else { + throw uhd::value_error("gps ctrl get_sensor unknown key: " + key); + } } - } private: - void init_gpsdo(void) { - //issue some setup stuff so it spits out the appropriate data - //none of these should issue replies so we don't bother looking for them - //we have to sleep between commands because the JL device, despite not - //acking, takes considerable time to process each command. - const std::vector<std::string> init_cmds = { - "SYST:COMM:SER:ECHO OFF\r\n", - "SYST:COMM:SER:PRO OFF\r\n", - "GPS:GPGGA 1\r\n", - "GPS:GGAST 0\r\n", - "GPS:GPRMC 1\r\n", - "SERV:TRAC 1\r\n" - }; - - for (const auto& cmd : init_cmds) { - _send(cmd); - std::this_thread::sleep_for( + void init_gpsdo(void) + { + // issue some setup stuff so it spits out the appropriate data + // none of these should issue replies so we don't bother looking for them + // we have to sleep between commands because the JL device, despite not + // acking, takes considerable time to process each command. + const std::vector<std::string> init_cmds = {"SYST:COMM:SER:ECHO OFF\r\n", + "SYST:COMM:SER:PRO OFF\r\n", + "GPS:GPGGA 1\r\n", + "GPS:GGAST 0\r\n", + "GPS:GPRMC 1\r\n", + "SERV:TRAC 1\r\n"}; + + for (const auto& cmd : init_cmds) { + _send(cmd); + std::this_thread::sleep_for( std::chrono::milliseconds(GPSDO_COMMAND_DELAY_MS)); - } - } - - //helper function to retrieve a field from an NMEA sentence - std::string get_token(std::string sentence, size_t offset) { - boost::tokenizer<boost::escaped_list_separator<char> > tok(sentence); - std::vector<std::string> toked; - tok.assign(sentence); //this can throw - toked.assign(tok.begin(), tok.end()); - - if(toked.size() <= offset) { - throw uhd::value_error(str(boost::format("Invalid response \"%s\"") % sentence)); + } } - return toked[offset]; - } - - ptime get_time(void) { - int error_cnt = 0; - ptime gps_time; - while(error_cnt < 2) { - try { - // wait for next GPRMC string - std::string reply = get_sentence("GPRMC", GPS_NMEA_NORMAL_FRESHNESS, GPS_COMM_TIMEOUT_MS, true); - - std::string datestr = get_token(reply, 9); - std::string timestr = get_token(reply, 1); - - if(datestr.size() == 0 or timestr.size() == 0) { - throw uhd::value_error(str(boost::format("Invalid response \"%s\"") % reply)); - } - struct tm raw_date; - raw_date.tm_year = std::stoi(datestr.substr(4, 2)) + 2000 - 1900; // years since 1900 - raw_date.tm_mon = std::stoi(datestr.substr(2, 2)) - 1; // months since january (0-11) - raw_date.tm_mday = std::stoi(datestr.substr(0, 2)); // dom (1-31) - raw_date.tm_hour = std::stoi(timestr.substr(0, 2)); - raw_date.tm_min = std::stoi(timestr.substr(2, 2)); - raw_date.tm_sec = std::stoi(timestr.substr(4,2)); - gps_time = boost::posix_time::ptime_from_tm(raw_date); - - UHD_LOG_TRACE("GPS", "GPS time: " + boost::posix_time::to_simple_string(gps_time)); - return gps_time; - - } catch(std::exception &e) { - UHD_LOGGER_DEBUG("GPS") << "get_time: " << e.what(); - error_cnt++; + // helper function to retrieve a field from an NMEA sentence + std::string get_token(std::string sentence, size_t offset) + { + boost::tokenizer<boost::escaped_list_separator<char>> tok(sentence); + std::vector<std::string> toked; + tok.assign(sentence); // this can throw + toked.assign(tok.begin(), tok.end()); + + if (toked.size() <= offset) { + throw uhd::value_error( + str(boost::format("Invalid response \"%s\"") % sentence)); } + return toked[offset]; } - throw uhd::value_error("get_time: Timeout after no valid message found"); - return gps_time; //keep gcc from complaining - } + ptime get_time(void) + { + int error_cnt = 0; + ptime gps_time; + while (error_cnt < 2) { + try { + // wait for next GPRMC string + std::string reply = get_sentence( + "GPRMC", GPS_NMEA_NORMAL_FRESHNESS, GPS_COMM_TIMEOUT_MS, true); + + std::string datestr = get_token(reply, 9); + std::string timestr = get_token(reply, 1); + + if (datestr.size() == 0 or timestr.size() == 0) { + throw uhd::value_error( + str(boost::format("Invalid response \"%s\"") % reply)); + } + + struct tm raw_date; + raw_date.tm_year = + std::stoi(datestr.substr(4, 2)) + 2000 - 1900; // years since 1900 + raw_date.tm_mon = + std::stoi(datestr.substr(2, 2)) - 1; // months since january (0-11) + raw_date.tm_mday = std::stoi(datestr.substr(0, 2)); // dom (1-31) + raw_date.tm_hour = std::stoi(timestr.substr(0, 2)); + raw_date.tm_min = std::stoi(timestr.substr(2, 2)); + raw_date.tm_sec = std::stoi(timestr.substr(4, 2)); + gps_time = boost::posix_time::ptime_from_tm(raw_date); + + UHD_LOG_TRACE( + "GPS", "GPS time: " + boost::posix_time::to_simple_string(gps_time)); + return gps_time; + + } catch (std::exception& e) { + UHD_LOGGER_DEBUG("GPS") << "get_time: " << e.what(); + error_cnt++; + } + } + throw uhd::value_error("get_time: Timeout after no valid message found"); - int64_t get_epoch_time(void) { - return (get_time() - from_time_t(0)).total_seconds(); - } + return gps_time; // keep gcc from complaining + } - bool gps_detected(void) { - return (_gps_type != GPS_TYPE_NONE); - } + int64_t get_epoch_time(void) + { + return (get_time() - from_time_t(0)).total_seconds(); + } + + bool gps_detected(void) + { + return (_gps_type != GPS_TYPE_NONE); + } - bool locked(void) { - int error_cnt = 0; - while(error_cnt < 3) { - try { - std::string reply = get_sentence("GPGGA", GPS_LOCK_FRESHNESS, GPS_COMM_TIMEOUT_MS); - if(reply.empty()) + bool locked(void) + { + int error_cnt = 0; + while (error_cnt < 3) { + try { + std::string reply = + get_sentence("GPGGA", GPS_LOCK_FRESHNESS, GPS_COMM_TIMEOUT_MS); + if (reply.empty()) + error_cnt++; + else + return (get_token(reply, 6) != "0"); + } catch (std::exception& e) { + UHD_LOGGER_DEBUG("GPS") << "locked: " << e.what(); error_cnt++; - else - return (get_token(reply, 6) != "0"); - } catch(std::exception &e) { - UHD_LOGGER_DEBUG("GPS") << "locked: " << e.what(); - error_cnt++; + } } + throw uhd::value_error("locked(): unable to determine GPS lock status"); } - throw uhd::value_error("locked(): unable to determine GPS lock status"); - } - uart_iface::sptr _uart; + uart_iface::sptr _uart; - void _flush(void){ - while (not _uart->read_uart(0.0).empty()){ - //NOP + void _flush(void) + { + while (not _uart->read_uart(0.0).empty()) { + // NOP + } } - } - std::string _recv(double timeout = GPS_TIMEOUT_DELAY_MS/1000.){ - return _uart->read_uart(timeout); - } - - void _send(const std::string &buf){ - return _uart->write_uart(buf); - } + std::string _recv(double timeout = GPS_TIMEOUT_DELAY_MS / 1000.) + { + return _uart->read_uart(timeout); + } - enum { - GPS_TYPE_INTERNAL_GPSDO, - GPS_TYPE_GENERIC_NMEA, - GPS_TYPE_NONE - } _gps_type; + void _send(const std::string& buf) + { + return _uart->write_uart(buf); + } + enum { GPS_TYPE_INTERNAL_GPSDO, GPS_TYPE_GENERIC_NMEA, GPS_TYPE_NONE } _gps_type; }; /*********************************************************************** * Public make function for the GPS control **********************************************************************/ -gps_ctrl::sptr gps_ctrl::make(uart_iface::sptr uart){ +gps_ctrl::sptr gps_ctrl::make(uart_iface::sptr uart) +{ return sptr(new gps_ctrl_impl(uart)); } diff --git a/host/lib/usrp/mboard_eeprom_c.cpp b/host/lib/usrp/mboard_eeprom_c.cpp index f1cbaaed5..c923ac809 100644 --- a/host/lib/usrp/mboard_eeprom_c.cpp +++ b/host/lib/usrp/mboard_eeprom_c.cpp @@ -5,58 +5,36 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/usrp/mboard_eeprom.h> - #include <uhd/exception.hpp> - +#include <uhd/usrp/mboard_eeprom.h> #include <string.h> -uhd_error uhd_mboard_eeprom_make( - uhd_mboard_eeprom_handle* h -){ - UHD_SAFE_C( - *h = new uhd_mboard_eeprom_t; - ) +uhd_error uhd_mboard_eeprom_make(uhd_mboard_eeprom_handle* h) +{ + UHD_SAFE_C(*h = new uhd_mboard_eeprom_t;) } -uhd_error uhd_mboard_eeprom_free( - uhd_mboard_eeprom_handle* h -){ - UHD_SAFE_C( - delete *h; - *h = NULL; - ) +uhd_error uhd_mboard_eeprom_free(uhd_mboard_eeprom_handle* h) +{ + UHD_SAFE_C(delete *h; *h = NULL;) } uhd_error uhd_mboard_eeprom_get_value( - uhd_mboard_eeprom_handle h, - const char* key, - char* value_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string value_cpp = h->mboard_eeprom_cpp.get(key); - strncpy(value_out, value_cpp.c_str(), strbuffer_len); - ) + uhd_mboard_eeprom_handle h, const char* key, char* value_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR(h, std::string value_cpp = h->mboard_eeprom_cpp.get(key); + strncpy(value_out, value_cpp.c_str(), strbuffer_len);) } uhd_error uhd_mboard_eeprom_set_value( - uhd_mboard_eeprom_handle h, - const char* key, - const char* value -){ - UHD_SAFE_C_SAVE_ERROR(h, - h->mboard_eeprom_cpp[key] = value; - ) + uhd_mboard_eeprom_handle h, const char* key, const char* value) +{ + UHD_SAFE_C_SAVE_ERROR(h, h->mboard_eeprom_cpp[key] = value;) } uhd_error uhd_mboard_eeprom_last_error( - uhd_mboard_eeprom_handle h, - char* error_out, - size_t strbuffer_len -){ - UHD_SAFE_C( - memset(error_out, '\0', strbuffer_len); - strncpy(error_out, h->last_error.c_str(), strbuffer_len); - ) + uhd_mboard_eeprom_handle h, char* error_out, size_t strbuffer_len) +{ + UHD_SAFE_C(memset(error_out, '\0', strbuffer_len); + strncpy(error_out, h->last_error.c_str(), strbuffer_len);) } diff --git a/host/lib/usrp/mpmd/mpmd_find.cpp b/host/lib/usrp/mpmd/mpmd_find.cpp index b5f20559c..501b250b0 100644 --- a/host/lib/usrp/mpmd/mpmd_find.cpp +++ b/host/lib/usrp/mpmd/mpmd_find.cpp @@ -93,7 +93,7 @@ device_addrs_t mpmd_find_with_addr( // Create result to return device_addr_t new_addr; new_addr[MGMT_ADDR_KEY] = recv_addr; - new_addr["type"] = "mpmd"; // hwd will overwrite this + new_addr["type"] = "mpmd"; // hwd will overwrite this // remove ident string and put other informations into device_args dict result.erase(result.begin()); // parse key-value pairs in the discovery string and add them to the @@ -134,8 +134,7 @@ device_addrs_t mpmd_find_with_addrs(const device_addrs_t& hints) device_addrs_t found_devices; found_devices.reserve(hints.size()); for (const auto& hint : hints) { - if (not(hint.has_key(xport::FIRST_ADDR_KEY) - or hint.has_key(MGMT_ADDR_KEY))) { + if (not(hint.has_key(xport::FIRST_ADDR_KEY) or hint.has_key(MGMT_ADDR_KEY))) { UHD_LOG_DEBUG("MPMD FIND", "No address given in hint " << hint.to_string()); continue; } diff --git a/host/lib/usrp/mpmd/mpmd_impl.cpp b/host/lib/usrp/mpmd/mpmd_impl.cpp index cb463b3f4..d685b93b2 100644 --- a/host/lib/usrp/mpmd/mpmd_impl.cpp +++ b/host/lib/usrp/mpmd/mpmd_impl.cpp @@ -10,7 +10,6 @@ #include <uhd/utils/static.hpp> #include <uhd/utils/tasks.hpp> #include <boost/algorithm/string.hpp> -#include <memory> #include <boost/thread.hpp> #include <chrono> #include <future> diff --git a/host/lib/usrp/mpmd/mpmd_impl.hpp b/host/lib/usrp/mpmd/mpmd_impl.hpp index e1dde49b5..06b452724 100644 --- a/host/lib/usrp/mpmd/mpmd_impl.hpp +++ b/host/lib/usrp/mpmd/mpmd_impl.hpp @@ -12,8 +12,8 @@ #include <uhd/types/device_addr.hpp> #include <uhd/types/dict.hpp> #include <uhd/utils/tasks.hpp> -#include <uhdlib/rfnoc/rfnoc_device.hpp> #include <uhdlib/rfnoc/clock_iface.hpp> +#include <uhdlib/rfnoc/rfnoc_device.hpp> #include <uhdlib/usrp/common/mpmd_mb_controller.hpp> #include <uhdlib/utils/rpc.hpp> #include <boost/optional.hpp> @@ -123,7 +123,8 @@ public: * separate thread, and needs some kind of flag to be notified that * something is up. */ - void allow_claim_failure(const bool allow) { + void allow_claim_failure(const bool allow) + { if (allow) { _allow_claim_failure_latch = true; } @@ -173,7 +174,6 @@ private: * really need to know what it does. */ std::atomic<bool> _allow_claim_failure_latch{false}; - }; diff --git a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_liberio.hpp b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_liberio.hpp index 09fb24f8e..03331c576 100644 --- a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_liberio.hpp +++ b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_liberio.hpp @@ -27,15 +27,21 @@ public: mpmd_link_if_ctrl_liberio(const uhd::device_addr_t& mb_args, const mpmd_link_if_mgr::xport_info_list_t& xport_info); - size_t get_num_links() const { return 1; } + size_t get_num_links() const + { + return 1; + } - uhd::transport::both_links_t get_link( - const size_t link_idx, const uhd::transport::link_type_t link_type, + uhd::transport::both_links_t get_link(const size_t link_idx, + const uhd::transport::link_type_t link_type, const uhd::device_addr_t& link_args); size_t get_mtu(const uhd::direction_t) const; - double get_link_rate(const size_t /*link_idx*/) const { return _link_rate; } + double get_link_rate(const size_t /*link_idx*/) const + { + return _link_rate; + } const uhd::rfnoc::chdr::chdr_packet_factory& get_packet_factory() const { @@ -43,7 +49,6 @@ public: } private: - const uhd::device_addr_t _mb_args; const uhd::dict<std::string, std::string> _recv_args; const uhd::dict<std::string, std::string> _send_args; diff --git a/host/lib/usrp/mpmd/mpmd_mb_controller.cpp b/host/lib/usrp/mpmd/mpmd_mb_controller.cpp index 9aa61a5a8..05393b017 100644 --- a/host/lib/usrp/mpmd/mpmd_mb_controller.cpp +++ b/host/lib/usrp/mpmd/mpmd_mb_controller.cpp @@ -10,9 +10,9 @@ using namespace uhd::rfnoc; using namespace uhd; namespace { - //! Default timeout value for tRPC calls that we know can take long (ms) - constexpr size_t MPMD_DEFAULT_LONG_TIMEOUT = 12000; // ms -} +//! Default timeout value for tRPC calls that we know can take long (ms) +constexpr size_t MPMD_DEFAULT_LONG_TIMEOUT = 12000; // ms +} // namespace mpmd_mb_controller::mpmd_mb_controller( uhd::rpc_client::sptr rpcc, uhd::device_addr_t device_info) @@ -108,7 +108,8 @@ std::vector<std::string> mpmd_mb_controller::get_clock_sources() const return _rpc->request_with_token<std::vector<std::string>>("get_clock_sources"); } -void mpmd_mb_controller::set_sync_source(const std::string& clock_source, const std::string& time_source) +void mpmd_mb_controller::set_sync_source( + const std::string& clock_source, const std::string& time_source) { uhd::device_addr_t sync_source; sync_source["clock_source"] = clock_source; @@ -177,8 +178,7 @@ uhd::usrp::mboard_eeprom_t mpmd_mb_controller::get_eeprom() { auto mb_eeprom = _rpc->request_with_token<std::map<std::string, std::string>>("get_mb_eeprom"); - uhd::usrp::mboard_eeprom_t mb_eeprom_dict( - mb_eeprom.cbegin(), mb_eeprom.cend()); + uhd::usrp::mboard_eeprom_t mb_eeprom_dict(mb_eeprom.cbegin(), mb_eeprom.cend()); return mb_eeprom_dict; } diff --git a/host/lib/usrp/mpmd/mpmd_mb_iface.cpp b/host/lib/usrp/mpmd/mpmd_mb_iface.cpp index b474dfdc3..41b664374 100644 --- a/host/lib/usrp/mpmd/mpmd_mb_iface.cpp +++ b/host/lib/usrp/mpmd/mpmd_mb_iface.cpp @@ -26,9 +26,7 @@ static uhd::usrp::io_service_args_t get_default_io_srv_args() mpmd_mboard_impl::mpmd_mb_iface::mpmd_mb_iface( const uhd::device_addr_t& mb_args, uhd::rpc_client::sptr rpc) - : _mb_args(mb_args) - , _rpc(rpc) - , _link_if_mgr(xport::mpmd_link_if_mgr::make(mb_args)) + : _mb_args(mb_args), _rpc(rpc), _link_if_mgr(xport::mpmd_link_if_mgr::make(mb_args)) { _remote_device_id = allocate_device_id(); UHD_LOG_TRACE("MPMD::MB_IFACE", "Assigning device_id " << _remote_device_id); diff --git a/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp b/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp index 4268a90ba..ecf503f28 100644 --- a/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp +++ b/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp @@ -11,8 +11,8 @@ #include <uhd/utils/log.hpp> #include <uhd/utils/safe_call.hpp> #include <chrono> -#include <thread> #include <memory> +#include <thread> namespace { /************************************************************************* @@ -263,7 +263,8 @@ mpmd_mboard_impl::mpmd_mboard_impl( , _claim_rpc(make_mpm_rpc_client(rpc_server_addr, mb_args, MPMD_CLAIMER_RPC_TIMEOUT)) { UHD_LOGGER_TRACE("MPMD") << "Initializing mboard, connecting to RPC server address: " - << rpc_server_addr << " mboard args: " << mb_args.to_string(); + << rpc_server_addr + << " mboard args: " << mb_args.to_string(); _claimer_task = claim_device_and_make_task(); if (mb_args_.has_key(MPMD_MEAS_LATENCY_KEY)) { diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp index 0ea25b099..c91f596cd 100644 --- a/host/lib/usrp/multi_usrp.cpp +++ b/host/lib/usrp/multi_usrp.cpp @@ -44,40 +44,44 @@ uhd::usrp::multi_usrp::sptr make_rfnoc_device( using namespace uhd; using namespace uhd::usrp; -const size_t multi_usrp::ALL_MBOARDS = size_t(~0); -const size_t multi_usrp::ALL_CHANS = size_t(~0); +const size_t multi_usrp::ALL_MBOARDS = size_t(~0); +const size_t multi_usrp::ALL_CHANS = size_t(~0); const std::string multi_usrp::ALL_GAINS = ""; -const std::string multi_usrp::ALL_LOS = "all"; +const std::string multi_usrp::ALL_LOS = "all"; -UHD_INLINE std::string string_vector_to_string(std::vector<std::string> values, std::string delimiter = std::string(" ")) +UHD_INLINE std::string string_vector_to_string( + std::vector<std::string> values, std::string delimiter = std::string(" ")) { std::string out = ""; - for (std::vector<std::string>::iterator iter = values.begin(); iter != values.end(); iter++) - { + for (std::vector<std::string>::iterator iter = values.begin(); iter != values.end(); + iter++) { out += (iter != values.begin() ? delimiter : "") + *iter; } return out; } -#define THROW_GAIN_NAME_ERROR(name,chan,dir) throw uhd::exception::runtime_error( \ - (boost::format("%s: gain \"%s\" not found for channel %d.\nAvailable gains: %s\n") % \ - __FUNCTION__ % name % chan % string_vector_to_string(get_##dir##_gain_names(chan))).str()); +#define THROW_GAIN_NAME_ERROR(name, chan, dir) \ + throw uhd::exception::runtime_error( \ + (boost::format( \ + "%s: gain \"%s\" not found for channel %d.\nAvailable gains: %s\n") \ + % __FUNCTION__ % name % chan \ + % string_vector_to_string(get_##dir##_gain_names(chan))) \ + .str()); /*********************************************************************** * Helper methods **********************************************************************/ static void do_samp_rate_warning_message( - double target_rate, - double actual_rate, - const std::string &xx -){ - static const double max_allowed_error = 1.0; //Sps - if (std::abs(target_rate - actual_rate) > max_allowed_error){ - UHD_LOGGER_WARNING("MULTI_USRP") << boost::format( - "The hardware does not support the requested %s sample rate:\n" - "Target sample rate: %f MSps\n" - "Actual sample rate: %f MSps\n" - ) % xx % (target_rate/1e6) % (actual_rate/1e6); + double target_rate, double actual_rate, const std::string& xx) +{ + static const double max_allowed_error = 1.0; // Sps + if (std::abs(target_rate - actual_rate) > max_allowed_error) { + UHD_LOGGER_WARNING("MULTI_USRP") + << boost::format( + "The hardware does not support the requested %s sample rate:\n" + "Target sample rate: %f MSps\n" + "Actual sample rate: %f MSps\n") + % xx % (target_rate / 1e6) % (actual_rate / 1e6); } } @@ -97,10 +101,12 @@ static void do_samp_rate_warning_message( if (tune_req.rf_freq_policy == tune_request_t::POLICY_MANUAL) return; if (tune_req.dsp_freq_policy == tune_request_t::POLICY_MANUAL) return; - bool requested_freq_success = uhd::math::frequencies_are_equal(target_freq, clipped_target_freq); - bool target_freq_success = uhd::math::frequencies_are_equal(clipped_target_freq, actual_freq); - bool rf_lo_tune_success = uhd::math::frequencies_are_equal(target_rf_freq, actual_rf_freq); - bool dsp_tune_success = uhd::math::frequencies_are_equal(target_dsp_freq, actual_dsp_freq); + bool requested_freq_success = uhd::math::frequencies_are_equal(target_freq, +clipped_target_freq); bool target_freq_success = +uhd::math::frequencies_are_equal(clipped_target_freq, actual_freq); bool +rf_lo_tune_success = uhd::math::frequencies_are_equal(target_rf_freq, actual_rf_freq); + bool dsp_tune_success = uhd::math::frequencies_are_equal(target_dsp_freq, +actual_dsp_freq); if(requested_freq_success and target_freq_success and rf_lo_tune_success and dsp_tune_success) { @@ -134,9 +140,8 @@ static void do_samp_rate_warning_message( if(not requested_freq_success) { boost::format failure_message( - " The requested %s frequency is outside of the system range, and has been clipped:\n" - " Target Frequency: %f MHz\n" - " Clipped Target Frequency: %f MHz\n"); + " The requested %s frequency is outside of the system range, and has been +clipped:\n" " Target Frequency: %f MHz\n" " Clipped Target Frequency: %f MHz\n"); failure_message % xx % (target_freq / 1e6) % (clipped_target_freq / 1e6); results_string += failure_message.str(); @@ -192,39 +197,38 @@ static void do_samp_rate_warning_message( * begins. This prevents the user from tuning past the point where less * than half of the spectrum would be useful. */ static meta_range_t make_overall_tune_range( - const meta_range_t &fe_range, - const meta_range_t &dsp_range, - const double bw -){ + const meta_range_t& fe_range, const meta_range_t& dsp_range, const double bw) +{ meta_range_t range; - for(const range_t &sub_range: fe_range){ - range.push_back(range_t( - sub_range.start() + std::max(dsp_range.start(), -bw/2), - sub_range.stop() + std::min(dsp_range.stop(), bw/2), - dsp_range.step() - )); + for (const range_t& sub_range : fe_range) { + range.push_back(range_t(sub_range.start() + std::max(dsp_range.start(), -bw / 2), + sub_range.stop() + std::min(dsp_range.stop(), bw / 2), + dsp_range.step())); } return range; } - /*********************************************************************** * Gain helper functions **********************************************************************/ -static double get_gain_value(property_tree::sptr subtree){ +static double get_gain_value(property_tree::sptr subtree) +{ return subtree->access<double>("value").get(); } -static void set_gain_value(property_tree::sptr subtree, const double gain){ +static void set_gain_value(property_tree::sptr subtree, const double gain) +{ subtree->access<double>("value").set(gain); } -static meta_range_t get_gain_range(property_tree::sptr subtree){ +static meta_range_t get_gain_range(property_tree::sptr subtree) +{ return subtree->access<meta_range_t>("range").get(); } -static gain_fcns_t make_gain_fcns_from_subtree(property_tree::sptr subtree){ +static gain_fcns_t make_gain_fcns_from_subtree(property_tree::sptr subtree) +{ gain_fcns_t gain_fcns; gain_fcns.get_range = std::bind(&get_gain_range, subtree); gain_fcns.get_value = std::bind(&get_gain_value, subtree); @@ -238,23 +242,21 @@ static gain_fcns_t make_gain_fcns_from_subtree(property_tree::sptr subtree){ static const double RX_SIGN = +1.0; static const double TX_SIGN = -1.0; -static tune_result_t tune_xx_subdev_and_dsp( - const double xx_sign, +static tune_result_t tune_xx_subdev_and_dsp(const double xx_sign, property_tree::sptr dsp_subtree, property_tree::sptr rf_fe_subtree, - const tune_request_t &tune_request -){ + const tune_request_t& tune_request) +{ //------------------------------------------------------------------ //-- calculate the tunable frequency ranges of the system //------------------------------------------------------------------ - freq_range_t tune_range = make_overall_tune_range( - rf_fe_subtree->access<meta_range_t>("freq/range").get(), + freq_range_t tune_range = + make_overall_tune_range(rf_fe_subtree->access<meta_range_t>("freq/range").get(), dsp_subtree->access<meta_range_t>("freq/range").get(), - rf_fe_subtree->access<double>("bandwidth/value").get() - ); + rf_fe_subtree->access<double>("bandwidth/value").get()); freq_range_t dsp_range = dsp_subtree->access<meta_range_t>("freq/range").get(); - freq_range_t rf_range = rf_fe_subtree->access<meta_range_t>("freq/range").get(); + freq_range_t rf_range = rf_fe_subtree->access<meta_range_t>("freq/range").get(); double clipped_requested_freq = tune_range.clip(tune_request.target_freq); @@ -269,19 +271,20 @@ static tune_result_t tune_xx_subdev_and_dsp( * tune_request. This lo_offset is based on the requirements of the FE, and * does not reflect a user-requested lo_offset, which is handled later. */ double lo_offset = 0.0; - if (rf_fe_subtree->exists("use_lo_offset") and - rf_fe_subtree->access<bool>("use_lo_offset").get()){ + if (rf_fe_subtree->exists("use_lo_offset") + and rf_fe_subtree->access<bool>("use_lo_offset").get()) { // If the frontend has lo_offset value and range properties, trust it // for lo_offset if (rf_fe_subtree->exists("lo_offset/value")) { lo_offset = rf_fe_subtree->access<double>("lo_offset/value").get(); } - //If the local oscillator will be in the passband, use an offset. - //But constrain the LO offset by the width of the filter bandwidth. + // If the local oscillator will be in the passband, use an offset. + // But constrain the LO offset by the width of the filter bandwidth. const double rate = dsp_subtree->access<double>("rate/value").get(); - const double bw = rf_fe_subtree->access<double>("bandwidth/value").get(); - if (bw > rate) lo_offset = std::min((bw - rate)/2, rate/2); + const double bw = rf_fe_subtree->access<double>("bandwidth/value").get(); + if (bw > rate) + lo_offset = std::min((bw - rate) / 2, rate / 2); } //------------------------------------------------------------------ @@ -296,7 +299,7 @@ static tune_result_t tune_xx_subdev_and_dsp( //------------------------------------------------------------------ double target_rf_freq = 0.0; - switch (tune_request.rf_freq_policy){ + switch (tune_request.rf_freq_policy) { case tune_request_t::POLICY_AUTO: target_rf_freq = clipped_requested_freq + lo_offset; break; @@ -316,7 +319,7 @@ static tune_result_t tune_xx_subdev_and_dsp( break; case tune_request_t::POLICY_NONE: - break; //does not set + break; // does not set } //------------------------------------------------------------------ @@ -341,7 +344,7 @@ static tune_result_t tune_xx_subdev_and_dsp( * filtered baseband. */ target_dsp_freq = actual_rf_freq - clipped_requested_freq; - //invert the sign on the dsp freq for transmit (spinning up vs down) + // invert the sign on the dsp freq for transmit (spinning up vs down) target_dsp_freq *= xx_sign; break; @@ -355,7 +358,7 @@ static tune_result_t tune_xx_subdev_and_dsp( break; case tune_request_t::POLICY_NONE: - break; //does not set + break; // does not set } //------------------------------------------------------------------ @@ -371,37 +374,38 @@ static tune_result_t tune_xx_subdev_and_dsp( //------------------------------------------------------------------ tune_result_t tune_result; tune_result.clipped_rf_freq = clipped_requested_freq; - tune_result.target_rf_freq = target_rf_freq; - tune_result.actual_rf_freq = actual_rf_freq; + tune_result.target_rf_freq = target_rf_freq; + tune_result.actual_rf_freq = actual_rf_freq; tune_result.target_dsp_freq = target_dsp_freq; tune_result.actual_dsp_freq = actual_dsp_freq; return tune_result; } -static double derive_freq_from_xx_subdev_and_dsp( - const double xx_sign, +static double derive_freq_from_xx_subdev_and_dsp(const double xx_sign, property_tree::sptr dsp_subtree, - property_tree::sptr rf_fe_subtree -){ - //extract actual dsp and IF frequencies - const double actual_rf_freq = rf_fe_subtree->access<double>("freq/value").get(); + property_tree::sptr rf_fe_subtree) +{ + // extract actual dsp and IF frequencies + const double actual_rf_freq = rf_fe_subtree->access<double>("freq/value").get(); const double actual_dsp_freq = dsp_subtree->access<double>("freq/value").get(); - //invert the sign on the dsp freq for transmit + // invert the sign on the dsp freq for transmit return actual_rf_freq - actual_dsp_freq * xx_sign; } /*********************************************************************** * Multi USRP Implementation **********************************************************************/ -class multi_usrp_impl : public multi_usrp{ +class multi_usrp_impl : public multi_usrp +{ public: multi_usrp_impl(device::sptr dev) : _dev(dev) { _tree = _dev->get_tree(); } - device::sptr get_device(void){ + device::sptr get_device(void) + { return _dev; } @@ -410,83 +414,101 @@ public: return _tree; } - dict<std::string, std::string> get_usrp_rx_info(size_t chan){ + dict<std::string, std::string> get_usrp_rx_info(size_t chan) + { mboard_chan_pair mcp = rx_chan_to_mcp(chan); dict<std::string, std::string> usrp_info; const auto mb_eeprom = _tree->access<mboard_eeprom_t>(mb_root(mcp.mboard) / "eeprom").get(); - usrp_info["mboard_id"] = _tree->access<std::string>(mb_root(mcp.mboard) / "name").get(); - usrp_info["mboard_name"] = mb_eeprom.get("name", "n/a"); + usrp_info["mboard_id"] = + _tree->access<std::string>(mb_root(mcp.mboard) / "name").get(); + usrp_info["mboard_name"] = mb_eeprom.get("name", "n/a"); usrp_info["mboard_serial"] = mb_eeprom["serial"]; - usrp_info["rx_subdev_name"] = _tree->access<std::string>(rx_rf_fe_root(chan) / "name").get(); - usrp_info["rx_subdev_spec"] = _tree->access<subdev_spec_t>(mb_root(mcp.mboard) / "rx_subdev_spec").get().to_string(); - usrp_info["rx_antenna"] = _tree->access<std::string>(rx_rf_fe_root(chan) / "antenna" / "value").get(); - if (_tree->exists(rx_rf_fe_root(chan).branch_path().branch_path() / "rx_eeprom")) { + usrp_info["rx_subdev_name"] = + _tree->access<std::string>(rx_rf_fe_root(chan) / "name").get(); + usrp_info["rx_subdev_spec"] = + _tree->access<subdev_spec_t>(mb_root(mcp.mboard) / "rx_subdev_spec") + .get() + .to_string(); + usrp_info["rx_antenna"] = + _tree->access<std::string>(rx_rf_fe_root(chan) / "antenna" / "value").get(); + if (_tree->exists( + rx_rf_fe_root(chan).branch_path().branch_path() / "rx_eeprom")) { const auto db_eeprom = - _tree->access<dboard_eeprom_t>( - rx_rf_fe_root(chan).branch_path().branch_path() - / "rx_eeprom" - ).get(); + _tree + ->access<dboard_eeprom_t>( + rx_rf_fe_root(chan).branch_path().branch_path() / "rx_eeprom") + .get(); usrp_info["rx_serial"] = db_eeprom.serial; - usrp_info["rx_id"] = db_eeprom.id.to_pp_string(); + usrp_info["rx_id"] = db_eeprom.id.to_pp_string(); } const auto rfnoc_path = mb_root(mcp.mboard) / "xbar"; if (_tree->exists(rfnoc_path)) { - const auto spec = get_rx_subdev_spec(mcp.mboard).at(mcp.chan); + const auto spec = get_rx_subdev_spec(mcp.mboard).at(mcp.chan); const auto radio_index = get_radio_index(spec.db_name); - const auto radio_path = rfnoc_path / str(boost::format("Radio_%d") % radio_index); + const auto radio_path = + rfnoc_path / str(boost::format("Radio_%d") % radio_index); const auto eeprom_path = radio_path / "eeprom"; if (_tree->exists(eeprom_path)) { - const auto db_eeprom = _tree->access<eeprom_map_t>(eeprom_path).get(); - usrp_info["rx_serial"] = db_eeprom.count("serial") ? - std::string(db_eeprom.at("serial").begin(), db_eeprom.at("serial").end()) - : "n/a" - ; - usrp_info["rx_id"] = db_eeprom.count("pid") ? - std::string(db_eeprom.at("pid").begin(), db_eeprom.at("pid").end()) - : "n/a" - ; + const auto db_eeprom = _tree->access<eeprom_map_t>(eeprom_path).get(); + usrp_info["rx_serial"] = db_eeprom.count("serial") + ? std::string(db_eeprom.at("serial").begin(), + db_eeprom.at("serial").end()) + : "n/a"; + usrp_info["rx_id"] = db_eeprom.count("pid") + ? std::string(db_eeprom.at("pid").begin(), + db_eeprom.at("pid").end()) + : "n/a"; } } return usrp_info; } - dict<std::string, std::string> get_usrp_tx_info(size_t chan){ + dict<std::string, std::string> get_usrp_tx_info(size_t chan) + { mboard_chan_pair mcp = tx_chan_to_mcp(chan); dict<std::string, std::string> usrp_info; const auto mb_eeprom = _tree->access<mboard_eeprom_t>(mb_root(mcp.mboard) / "eeprom").get(); - usrp_info["mboard_id"] = _tree->access<std::string>(mb_root(mcp.mboard) / "name").get(); - usrp_info["mboard_name"] = mb_eeprom.get("name", "n/a"); + usrp_info["mboard_id"] = + _tree->access<std::string>(mb_root(mcp.mboard) / "name").get(); + usrp_info["mboard_name"] = mb_eeprom.get("name", "n/a"); usrp_info["mboard_serial"] = mb_eeprom["serial"]; - usrp_info["tx_subdev_name"] = _tree->access<std::string>(tx_rf_fe_root(chan) / "name").get(); - usrp_info["tx_subdev_spec"] = _tree->access<subdev_spec_t>(mb_root(mcp.mboard) / "tx_subdev_spec").get().to_string(); - usrp_info["tx_antenna"] = _tree->access<std::string>(tx_rf_fe_root(chan) / "antenna" / "value").get(); - if (_tree->exists(tx_rf_fe_root(chan).branch_path().branch_path() / "tx_eeprom")) { + usrp_info["tx_subdev_name"] = + _tree->access<std::string>(tx_rf_fe_root(chan) / "name").get(); + usrp_info["tx_subdev_spec"] = + _tree->access<subdev_spec_t>(mb_root(mcp.mboard) / "tx_subdev_spec") + .get() + .to_string(); + usrp_info["tx_antenna"] = + _tree->access<std::string>(tx_rf_fe_root(chan) / "antenna" / "value").get(); + if (_tree->exists( + tx_rf_fe_root(chan).branch_path().branch_path() / "tx_eeprom")) { const auto db_eeprom = - _tree->access<dboard_eeprom_t>( - tx_rf_fe_root(chan).branch_path().branch_path() - / "tx_eeprom" - ).get(); + _tree + ->access<dboard_eeprom_t>( + tx_rf_fe_root(chan).branch_path().branch_path() / "tx_eeprom") + .get(); usrp_info["tx_serial"] = db_eeprom.serial; - usrp_info["tx_id"] = db_eeprom.id.to_pp_string(); + usrp_info["tx_id"] = db_eeprom.id.to_pp_string(); } const auto rfnoc_path = mb_root(mcp.mboard) / "xbar"; if (_tree->exists(rfnoc_path)) { - const auto spec = get_tx_subdev_spec(mcp.mboard).at(mcp.chan); + const auto spec = get_tx_subdev_spec(mcp.mboard).at(mcp.chan); const auto radio_index = get_radio_index(spec.db_name); - const auto radio_path = rfnoc_path / str(boost::format("Radio_%d")%radio_index); + const auto radio_path = + rfnoc_path / str(boost::format("Radio_%d") % radio_index); const auto path = radio_path / "eeprom"; - if(_tree->exists(path)) { - const auto db_eeprom = _tree->access<eeprom_map_t>(path).get(); - usrp_info["tx_serial"] = db_eeprom.count("serial") ? - std::string(db_eeprom.at("serial").begin(), db_eeprom.at("serial").end()) - : "n/a" - ; - usrp_info["tx_id"] = db_eeprom.count("pid") ? - std::string(db_eeprom.at("pid").begin(), db_eeprom.at("pid").end()) - : "n/a" - ; + if (_tree->exists(path)) { + const auto db_eeprom = _tree->access<eeprom_map_t>(path).get(); + usrp_info["tx_serial"] = db_eeprom.count("serial") + ? std::string(db_eeprom.at("serial").begin(), + db_eeprom.at("serial").end()) + : "n/a"; + usrp_info["tx_id"] = db_eeprom.count("pid") + ? std::string(db_eeprom.at("pid").begin(), + db_eeprom.at("pid").end()) + : "n/a"; } } return usrp_info; @@ -495,215 +517,212 @@ public: /******************************************************************* * Mboard methods ******************************************************************/ - void set_master_clock_rate(double rate, size_t mboard){ - if (mboard != ALL_MBOARDS){ + void set_master_clock_rate(double rate, size_t mboard) + { + if (mboard != ALL_MBOARDS) { if (_tree->exists(mb_root(mboard) / "auto_tick_rate") - and _tree->access<bool>(mb_root(mboard) / "auto_tick_rate").get()) { + and _tree->access<bool>(mb_root(mboard) / "auto_tick_rate").get()) { _tree->access<bool>(mb_root(mboard) / "auto_tick_rate").set(false); - UHD_LOGGER_INFO("MULTI_USRP") << "Setting master clock rate selection to 'manual'."; + UHD_LOGGER_INFO("MULTI_USRP") + << "Setting master clock rate selection to 'manual'."; } _tree->access<double>(mb_root(mboard) / "tick_rate").set(rate); return; } - for (size_t m = 0; m < get_num_mboards(); m++){ + for (size_t m = 0; m < get_num_mboards(); m++) { set_master_clock_rate(rate, m); } } - double get_master_clock_rate(size_t mboard){ + double get_master_clock_rate(size_t mboard) + { return _tree->access<double>(mb_root(mboard) / "tick_rate").get(); } meta_range_t get_master_clock_rate_range(const size_t mboard) { if (_tree->exists(mb_root(mboard) / "tick_rate/range")) { - return _tree->access<meta_range_t>( - mb_root(mboard) / "tick_rate/range" - ).get(); + return _tree->access<meta_range_t>(mb_root(mboard) / "tick_rate/range").get(); } // The USRP may not have a range defined, in which case we create a // fake range with a single value: const double tick_rate = get_master_clock_rate(mboard); - return meta_range_t( - tick_rate, - tick_rate, - 0 - ); - } - - std::string get_pp_string(void){ - std::string buff = str(boost::format( - "%s USRP:\n" - " Device: %s\n" - ) - % ((get_num_mboards() > 1)? "Multi" : "Single") - % (_tree->access<std::string>("/name").get()) - ); - for (size_t m = 0; m < get_num_mboards(); m++){ - buff += str(boost::format( - " Mboard %d: %s\n" - ) % m - % (_tree->access<std::string>(mb_root(m) / "name").get()) - ); + return meta_range_t(tick_rate, tick_rate, 0); + } + + std::string get_pp_string(void) + { + std::string buff = str(boost::format("%s USRP:\n" + " Device: %s\n") + % ((get_num_mboards() > 1) ? "Multi" : "Single") + % (_tree->access<std::string>("/name").get())); + for (size_t m = 0; m < get_num_mboards(); m++) { + buff += str(boost::format(" Mboard %d: %s\n") % m + % (_tree->access<std::string>(mb_root(m) / "name").get())); } //----------- rx side of life ---------------------------------- - for (size_t m = 0, chan = 0; m < get_num_mboards(); m++){ - for (; chan < (m + 1)*get_rx_subdev_spec(m).size(); chan++){ - buff += str(boost::format( - " RX Channel: %u\n" - " RX DSP: %s\n" - " RX Dboard: %s\n" - " RX Subdev: %s\n" - ) % chan - % rx_dsp_root(chan).leaf() + for (size_t m = 0, chan = 0; m < get_num_mboards(); m++) { + for (; chan < (m + 1) * get_rx_subdev_spec(m).size(); chan++) { + buff += str( + boost::format(" RX Channel: %u\n" + " RX DSP: %s\n" + " RX Dboard: %s\n" + " RX Subdev: %s\n") + % chan % rx_dsp_root(chan).leaf() % rx_rf_fe_root(chan).branch_path().branch_path().leaf() - % (_tree->access<std::string>(rx_rf_fe_root(chan) / "name").get()) - ); + % (_tree->access<std::string>(rx_rf_fe_root(chan) / "name").get())); } } //----------- tx side of life ---------------------------------- - for (size_t m = 0, chan = 0; m < get_num_mboards(); m++){ - for (; chan < (m + 1)*get_tx_subdev_spec(m).size(); chan++){ - buff += str(boost::format( - " TX Channel: %u\n" - " TX DSP: %s\n" - " TX Dboard: %s\n" - " TX Subdev: %s\n" - ) % chan - % tx_dsp_root(chan).leaf() + for (size_t m = 0, chan = 0; m < get_num_mboards(); m++) { + for (; chan < (m + 1) * get_tx_subdev_spec(m).size(); chan++) { + buff += str( + boost::format(" TX Channel: %u\n" + " TX DSP: %s\n" + " TX Dboard: %s\n" + " TX Subdev: %s\n") + % chan % tx_dsp_root(chan).leaf() % tx_rf_fe_root(chan).branch_path().branch_path().leaf() - % (_tree->access<std::string>(tx_rf_fe_root(chan) / "name").get()) - ); + % (_tree->access<std::string>(tx_rf_fe_root(chan) / "name").get())); } } return buff; } - std::string get_mboard_name(size_t mboard){ + std::string get_mboard_name(size_t mboard) + { return _tree->access<std::string>(mb_root(mboard) / "name").get(); } - time_spec_t get_time_now(size_t mboard = 0){ + time_spec_t get_time_now(size_t mboard = 0) + { return _tree->access<time_spec_t>(mb_root(mboard) / "time/now").get(); } - time_spec_t get_time_last_pps(size_t mboard = 0){ + time_spec_t get_time_last_pps(size_t mboard = 0) + { return _tree->access<time_spec_t>(mb_root(mboard) / "time/pps").get(); } - void set_time_now(const time_spec_t &time_spec, size_t mboard){ - if (mboard != ALL_MBOARDS){ + void set_time_now(const time_spec_t& time_spec, size_t mboard) + { + if (mboard != ALL_MBOARDS) { _tree->access<time_spec_t>(mb_root(mboard) / "time/now").set(time_spec); return; } - for (size_t m = 0; m < get_num_mboards(); m++){ + for (size_t m = 0; m < get_num_mboards(); m++) { set_time_now(time_spec, m); } } - void set_time_next_pps(const time_spec_t &time_spec, size_t mboard){ - if (mboard != ALL_MBOARDS){ + void set_time_next_pps(const time_spec_t& time_spec, size_t mboard) + { + if (mboard != ALL_MBOARDS) { _tree->access<time_spec_t>(mb_root(mboard) / "time/pps").set(time_spec); return; } - for (size_t m = 0; m < get_num_mboards(); m++){ + for (size_t m = 0; m < get_num_mboards(); m++) { set_time_next_pps(time_spec, m); } } - void set_time_unknown_pps(const time_spec_t &time_spec){ - UHD_LOGGER_INFO("MULTI_USRP") - << " 1) catch time transition at pps edge"; - auto end_time = std::chrono::steady_clock::now() - + std::chrono::milliseconds(1100); + void set_time_unknown_pps(const time_spec_t& time_spec) + { + UHD_LOGGER_INFO("MULTI_USRP") << " 1) catch time transition at pps edge"; + auto end_time = + std::chrono::steady_clock::now() + std::chrono::milliseconds(1100); time_spec_t time_start_last_pps = get_time_last_pps(); - while (time_start_last_pps == get_time_last_pps()) - { + while (time_start_last_pps == get_time_last_pps()) { if (std::chrono::steady_clock::now() > end_time) { - throw uhd::runtime_error( - "Board 0 may not be getting a PPS signal!\n" - "No PPS detected within the time interval.\n" - "See the application notes for your device.\n" - ); + throw uhd::runtime_error("Board 0 may not be getting a PPS signal!\n" + "No PPS detected within the time interval.\n" + "See the application notes for your device.\n"); } std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - UHD_LOGGER_INFO("MULTI_USRP") - << " 2) set times next pps (synchronously)"; + UHD_LOGGER_INFO("MULTI_USRP") << " 2) set times next pps (synchronously)"; set_time_next_pps(time_spec, ALL_MBOARDS); std::this_thread::sleep_for(std::chrono::seconds(1)); - //verify that the time registers are read to be within a few RTT - for (size_t m = 1; m < get_num_mboards(); m++){ + // verify that the time registers are read to be within a few RTT + for (size_t m = 1; m < get_num_mboards(); m++) { time_spec_t time_0 = this->get_time_now(0); time_spec_t time_i = this->get_time_now(m); - if (time_i < time_0 or (time_i - time_0) > time_spec_t(0.01)){ //10 ms: greater than RTT but not too big - UHD_LOGGER_WARNING("MULTI_USRP") << boost::format( - "Detected time deviation between board %d and board 0.\n" - "Board 0 time is %f seconds.\n" - "Board %d time is %f seconds.\n" - ) % m % time_0.get_real_secs() % m % time_i.get_real_secs(); + if (time_i < time_0 + or (time_i - time_0) + > time_spec_t(0.01)) { // 10 ms: greater than RTT but not too big + UHD_LOGGER_WARNING("MULTI_USRP") + << boost::format( + "Detected time deviation between board %d and board 0.\n" + "Board 0 time is %f seconds.\n" + "Board %d time is %f seconds.\n") + % m % time_0.get_real_secs() % m % time_i.get_real_secs(); } } } - bool get_time_synchronized(void){ - for (size_t m = 1; m < get_num_mboards(); m++){ + bool get_time_synchronized(void) + { + for (size_t m = 1; m < get_num_mboards(); m++) { time_spec_t time_0 = this->get_time_now(0); time_spec_t time_i = this->get_time_now(m); - if (time_i < time_0 or (time_i - time_0) > time_spec_t(0.01)) return false; + if (time_i < time_0 or (time_i - time_0) > time_spec_t(0.01)) + return false; } return true; } - void set_command_time(const time_spec_t &time_spec, size_t mboard){ - if (mboard != ALL_MBOARDS){ - if (not _tree->exists(mb_root(mboard) / "time/cmd")){ - throw uhd::not_implemented_error("timed command feature not implemented on this hardware"); + void set_command_time(const time_spec_t& time_spec, size_t mboard) + { + if (mboard != ALL_MBOARDS) { + if (not _tree->exists(mb_root(mboard) / "time/cmd")) { + throw uhd::not_implemented_error( + "timed command feature not implemented on this hardware"); } _tree->access<time_spec_t>(mb_root(mboard) / "time/cmd").set(time_spec); return; } - for (size_t m = 0; m < get_num_mboards(); m++){ + for (size_t m = 0; m < get_num_mboards(); m++) { set_command_time(time_spec, m); } } - void clear_command_time(size_t mboard){ - if (mboard != ALL_MBOARDS){ - _tree->access<time_spec_t>(mb_root(mboard) / "time/cmd").set(time_spec_t(0.0)); + void clear_command_time(size_t mboard) + { + if (mboard != ALL_MBOARDS) { + _tree->access<time_spec_t>(mb_root(mboard) / "time/cmd") + .set(time_spec_t(0.0)); return; } - for (size_t m = 0; m < get_num_mboards(); m++){ + for (size_t m = 0; m < get_num_mboards(); m++) { clear_command_time(m); } } - void issue_stream_cmd(const stream_cmd_t &stream_cmd, size_t chan){ - if (chan != ALL_CHANS){ + void issue_stream_cmd(const stream_cmd_t& stream_cmd, size_t chan) + { + if (chan != ALL_CHANS) { _tree->access<stream_cmd_t>(rx_dsp_root(chan) / "stream_cmd").set(stream_cmd); return; } - for (size_t c = 0; c < get_rx_num_channels(); c++){ + for (size_t c = 0; c < get_rx_num_channels(); c++) { issue_stream_cmd(stream_cmd, c); } } - void set_time_source(const std::string &source, const size_t mboard){ - if (mboard != ALL_MBOARDS){ - const auto time_source_path = - mb_root(mboard) / "time_source/value"; - const auto sync_source_path = - mb_root(mboard) / "sync_source/value"; + void set_time_source(const std::string& source, const size_t mboard) + { + if (mboard != ALL_MBOARDS) { + const auto time_source_path = mb_root(mboard) / "time_source/value"; + const auto sync_source_path = mb_root(mboard) / "sync_source/value"; if (_tree->exists(time_source_path)) { _tree->access<std::string>(time_source_path).set(source); } else if (_tree->exists(sync_source_path)) { - auto sync_source = - _tree->access<device_addr_t>(sync_source_path).get(); + auto sync_source = _tree->access<device_addr_t>(sync_source_path).get(); sync_source["time_source"] = source; _tree->access<device_addr_t>(sync_source_path).set(sync_source); } else { @@ -711,18 +730,20 @@ public: } return; } - for (size_t m = 0; m < get_num_mboards(); m++){ + for (size_t m = 0; m < get_num_mboards(); m++) { this->set_time_source(source, m); } } - std::string get_time_source(const size_t mboard){ + std::string get_time_source(const size_t mboard) + { const auto time_source_path = mb_root(mboard) / "time_source/value"; if (_tree->exists(time_source_path)) { return _tree->access<std::string>(time_source_path).get(); } else if (_tree->exists(mb_root(mboard) / "sync_source/value")) { - auto sync_source = _tree->access<device_addr_t>( - mb_root(mboard) / "sync_source" / "value").get(); + auto sync_source = + _tree->access<device_addr_t>(mb_root(mboard) / "sync_source" / "value") + .get(); if (sync_source.has_key("time_source")) { return sync_source.get("time_source"); } @@ -730,11 +751,11 @@ public: throw uhd::runtime_error("Cannot query time_source on this device!"); } - std::vector<std::string> get_time_sources(const size_t mboard){ + std::vector<std::string> get_time_sources(const size_t mboard) + { const auto time_source_path = mb_root(mboard) / "time_source/options"; if (_tree->exists(time_source_path)) { - return _tree->access<std::vector<std::string>>(time_source_path) - .get(); + return _tree->access<std::vector<std::string>>(time_source_path).get(); } else if (_tree->exists(mb_root(mboard) / "sync_source/options")) { const auto sync_sources = get_sync_sources(mboard); std::vector<std::string> time_sources; @@ -747,38 +768,37 @@ public: throw uhd::runtime_error("Cannot query time_source on this device!"); } - void set_clock_source(const std::string &source, const size_t mboard){ - if (mboard != ALL_MBOARDS){ - const auto clock_source_path = - mb_root(mboard) / "clock_source/value"; - const auto sync_source_path = - mb_root(mboard) / "sync_source/value"; + void set_clock_source(const std::string& source, const size_t mboard) + { + if (mboard != ALL_MBOARDS) { + const auto clock_source_path = mb_root(mboard) / "clock_source/value"; + const auto sync_source_path = mb_root(mboard) / "sync_source/value"; if (_tree->exists(clock_source_path)) { _tree->access<std::string>(clock_source_path).set(source); } else if (_tree->exists(sync_source_path)) { - auto sync_source = - _tree->access<device_addr_t>(sync_source_path).get(); + auto sync_source = _tree->access<device_addr_t>(sync_source_path).get(); sync_source["clock_source"] = source; _tree->access<device_addr_t>(sync_source_path).set(sync_source); } else { - throw uhd::runtime_error( - "Can't set clock source on this device."); + throw uhd::runtime_error("Can't set clock source on this device."); } return; } - for (size_t m = 0; m < get_num_mboards(); m++){ + for (size_t m = 0; m < get_num_mboards(); m++) { this->set_clock_source(source, m); } } - std::string get_clock_source(const size_t mboard){ + std::string get_clock_source(const size_t mboard) + { const auto clock_source_path = mb_root(mboard) / "clock_source/value"; if (_tree->exists(clock_source_path)) { - return _tree->access<std::string>( - mb_root(mboard) / "clock_source" / "value").get(); + return _tree->access<std::string>(mb_root(mboard) / "clock_source" / "value") + .get(); } else if (_tree->exists(mb_root(mboard) / "sync_source/value")) { - auto sync_source = _tree->access<device_addr_t>( - mb_root(mboard) / "sync_source" / "value").get(); + auto sync_source = + _tree->access<device_addr_t>(mb_root(mboard) / "sync_source" / "value") + .get(); if (sync_source.has_key("clock_source")) { return sync_source.get("clock_source"); } @@ -786,45 +806,38 @@ public: throw uhd::runtime_error("Cannot query clock_source on this device!"); } - void set_sync_source( - const std::string &clock_source, - const std::string &time_source, - const size_t mboard - ) { + void set_sync_source(const std::string& clock_source, + const std::string& time_source, + const size_t mboard) + { device_addr_t sync_args; sync_args["clock_source"] = clock_source; - sync_args["time_source"] = time_source; + sync_args["time_source"] = time_source; set_sync_source(sync_args, mboard); } - void set_sync_source( - const device_addr_t& sync_source, - const size_t mboard - ) { + void set_sync_source(const device_addr_t& sync_source, const size_t mboard) + { if (mboard != ALL_MBOARDS) { - const auto sync_source_path = - mb_root(mboard) / "sync_source/value"; + const auto sync_source_path = mb_root(mboard) / "sync_source/value"; if (_tree->exists(sync_source_path)) { - _tree->access<device_addr_t>(sync_source_path) - .set(sync_source); + _tree->access<device_addr_t>(sync_source_path).set(sync_source); } else if (_tree->exists(mb_root(mboard) / "clock_source/value") - and _tree->exists(mb_root(mboard) / "time_source/value") - and sync_source.has_key("clock_source") - and sync_source.has_key("time_source")) { + and _tree->exists(mb_root(mboard) / "time_source/value") + and sync_source.has_key("clock_source") + and sync_source.has_key("time_source")) { const std::string clock_source = sync_source["clock_source"]; - const std::string time_source = sync_source["time_source"]; + const std::string time_source = sync_source["time_source"]; set_clock_source(clock_source, mboard); set_time_source(time_source, mboard); } else { - throw uhd::runtime_error( - "Can't set sync source on this device."); + throw uhd::runtime_error("Can't set sync source on this device."); } return; } - for (size_t m = 0; m < get_num_mboards(); m++){ + for (size_t m = 0; m < get_num_mboards(); m++) { this->set_sync_source(sync_source, m); } - } device_addr_t get_sync_source(const size_t mboard) @@ -836,10 +849,10 @@ public: // If this path is not there, we fall back to the oldschool method and // convert to a new-fangled sync source dictionary const std::string clock_source = get_clock_source(mboard); - const std::string time_source = get_time_source(mboard); + const std::string time_source = get_time_source(mboard); device_addr_t sync_source; sync_source["clock_source"] = clock_source; - sync_source["time_source"] = time_source; + sync_source["time_source"] = time_source; return sync_source; } @@ -852,13 +865,13 @@ public: // If this path is not there, we fall back to the oldschool method and // convert to a new-fangled sync source dictionary const auto clock_sources = get_clock_sources(mboard); - const auto time_sources = get_time_sources(mboard); + const auto time_sources = get_time_sources(mboard); std::vector<device_addr_t> sync_sources; for (const auto& clock_source : clock_sources) { for (const auto& time_source : time_sources) { device_addr_t sync_source; sync_source["clock_source"] = clock_source; - sync_source["time_source"] = time_source; + sync_source["time_source"] = time_source; sync_sources.push_back(sync_source); } } @@ -866,11 +879,11 @@ public: return sync_sources; } - std::vector<std::string> get_clock_sources(const size_t mboard){ + std::vector<std::string> get_clock_sources(const size_t mboard) + { const auto clock_source_path = mb_root(mboard) / "clock_source/options"; if (_tree->exists(clock_source_path)) { - return _tree->access<std::vector<std::string>>(clock_source_path) - .get(); + return _tree->access<std::vector<std::string>>(clock_source_path).get(); } else if (_tree->exists(mb_root(mboard) / "sync_source/options")) { const auto sync_sources = get_sync_sources(mboard); std::vector<std::string> clock_sources; @@ -885,86 +898,83 @@ public: void set_clock_source_out(const bool enb, const size_t mboard) { - if (mboard != ALL_MBOARDS) - { - if (_tree->exists(mb_root(mboard) / "clock_source" / "output")) - { + if (mboard != ALL_MBOARDS) { + if (_tree->exists(mb_root(mboard) / "clock_source" / "output")) { _tree->access<bool>(mb_root(mboard) / "clock_source" / "output").set(enb); - } - else - { - throw uhd::runtime_error("multi_usrp::set_clock_source_out - not supported on this device"); + } else { + throw uhd::runtime_error( + "multi_usrp::set_clock_source_out - not supported on this device"); } return; } - for (size_t m = 0; m < get_num_mboards(); m++) - { + for (size_t m = 0; m < get_num_mboards(); m++) { this->set_clock_source_out(enb, m); } } void set_time_source_out(const bool enb, const size_t mboard) { - if (mboard != ALL_MBOARDS) - { - if (_tree->exists(mb_root(mboard) / "time_source" / "output")) - { + if (mboard != ALL_MBOARDS) { + if (_tree->exists(mb_root(mboard) / "time_source" / "output")) { _tree->access<bool>(mb_root(mboard) / "time_source" / "output").set(enb); - } - else - { - throw uhd::runtime_error("multi_usrp::set_time_source_out - not supported on this device"); + } else { + throw uhd::runtime_error( + "multi_usrp::set_time_source_out - not supported on this device"); } return; } - for (size_t m = 0; m < get_num_mboards(); m++) - { + for (size_t m = 0; m < get_num_mboards(); m++) { this->set_time_source_out(enb, m); } } - size_t get_num_mboards(void){ + size_t get_num_mboards(void) + { return _tree->list("/mboards").size(); } - sensor_value_t get_mboard_sensor(const std::string &name, size_t mboard){ + sensor_value_t get_mboard_sensor(const std::string& name, size_t mboard) + { return _tree->access<sensor_value_t>(mb_root(mboard) / "sensors" / name).get(); } - std::vector<std::string> get_mboard_sensor_names(size_t mboard){ + std::vector<std::string> get_mboard_sensor_names(size_t mboard) + { if (_tree->exists(mb_root(mboard) / "sensors")) { return _tree->list(mb_root(mboard) / "sensors"); } return {}; } - void set_user_register(const uint8_t addr, const uint32_t data, size_t mboard){ - if (mboard != ALL_MBOARDS){ + void set_user_register(const uint8_t addr, const uint32_t data, size_t mboard) + { + if (mboard != ALL_MBOARDS) { typedef std::pair<uint8_t, uint32_t> user_reg_t; - _tree->access<user_reg_t>(mb_root(mboard) / "user/regs").set(user_reg_t(addr, data)); + _tree->access<user_reg_t>(mb_root(mboard) / "user/regs") + .set(user_reg_t(addr, data)); return; } - for (size_t m = 0; m < get_num_mboards(); m++){ + for (size_t m = 0; m < get_num_mboards(); m++) { set_user_register(addr, data, m); } } wb_iface::sptr get_user_settings_iface(const size_t chan) { - const auto user_settings_path = - rx_rf_fe_root(chan) / "user_settings" / "iface"; + const auto user_settings_path = rx_rf_fe_root(chan) / "user_settings" / "iface"; if (_tree->exists(user_settings_path)) { return _tree->access<wb_iface::sptr>(user_settings_path).get(); } - UHD_LOG_WARNING("MULTI_USRP", - "Attempting to read back non-existent user settings iface!"); + UHD_LOG_WARNING( + "MULTI_USRP", "Attempting to read back non-existent user settings iface!"); return nullptr; } /******************************************************************* * RX methods ******************************************************************/ - rx_streamer::sptr get_rx_stream(const stream_args_t &args) { + rx_streamer::sptr get_rx_stream(const stream_args_t& args) + { _check_link_rate(args, false); stream_args_t args_ = args; if (!args.args.has_key("spp")) { @@ -978,56 +988,65 @@ public: return this->get_device()->get_rx_stream(args_); } - void set_rx_subdev_spec(const subdev_spec_t &spec, size_t mboard){ - if (mboard != ALL_MBOARDS){ + void set_rx_subdev_spec(const subdev_spec_t& spec, size_t mboard) + { + if (mboard != ALL_MBOARDS) { _tree->access<subdev_spec_t>(mb_root(mboard) / "rx_subdev_spec").set(spec); return; } - for (size_t m = 0; m < get_num_mboards(); m++){ + for (size_t m = 0; m < get_num_mboards(); m++) { set_rx_subdev_spec(spec, m); } } subdev_spec_t get_rx_subdev_spec(size_t mboard) { - subdev_spec_t spec = _tree->access<subdev_spec_t>(mb_root(mboard) / "rx_subdev_spec").get(); - if (spec.empty()) - { - try - { - const std::string db_name = _tree->list(mb_root(mboard) / "dboards").at(0); - const std::string fe_name = _tree->list(mb_root(mboard) / "dboards" / db_name / "rx_frontends").at(0); + subdev_spec_t spec = + _tree->access<subdev_spec_t>(mb_root(mboard) / "rx_subdev_spec").get(); + if (spec.empty()) { + try { + const std::string db_name = + _tree->list(mb_root(mboard) / "dboards").at(0); + const std::string fe_name = + _tree->list(mb_root(mboard) / "dboards" / db_name / "rx_frontends") + .at(0); spec.push_back(subdev_spec_pair_t(db_name, fe_name)); - _tree->access<subdev_spec_t>(mb_root(mboard) / "rx_subdev_spec").set(spec); - } - catch(const std::exception &e) - { - throw uhd::index_error(str(boost::format("multi_usrp::get_rx_subdev_spec(%u) failed to make default spec - %s") % mboard % e.what())); + _tree->access<subdev_spec_t>(mb_root(mboard) / "rx_subdev_spec") + .set(spec); + } catch (const std::exception& e) { + throw uhd::index_error( + str(boost::format("multi_usrp::get_rx_subdev_spec(%u) failed to make " + "default spec - %s") + % mboard % e.what())); } - UHD_LOGGER_INFO("MULTI_USRP") << "Selecting default RX front end spec: " << spec.to_pp_string(); + UHD_LOGGER_INFO("MULTI_USRP") + << "Selecting default RX front end spec: " << spec.to_pp_string(); } return spec; } - size_t get_rx_num_channels(void){ + size_t get_rx_num_channels(void) + { size_t sum = 0; - for (size_t m = 0; m < get_num_mboards(); m++){ + for (size_t m = 0; m < get_num_mboards(); m++) { sum += get_rx_subdev_spec(m).size(); } return sum; } - std::string get_rx_subdev_name(size_t chan){ + std::string get_rx_subdev_name(size_t chan) + { return _tree->access<std::string>(rx_rf_fe_root(chan) / "name").get(); } - void set_rx_rate(double rate, size_t chan){ - if (chan != ALL_CHANS){ + void set_rx_rate(double rate, size_t chan) + { + if (chan != ALL_CHANS) { _tree->access<double>(rx_dsp_root(chan) / "rate" / "value").set(rate); do_samp_rate_warning_message(rate, get_rx_rate(chan), "RX"); return; } - for (size_t c = 0; c < get_rx_num_channels(); c++){ + for (size_t c = 0; c < get_rx_num_channels(); c++) { set_rx_rate(rate, c); } } @@ -1037,104 +1056,129 @@ public: _rx_spp[chan] = spp; } - double get_rx_rate(size_t chan){ + double get_rx_rate(size_t chan) + { return _tree->access<double>(rx_dsp_root(chan) / "rate" / "value").get(); } - meta_range_t get_rx_rates(size_t chan){ + meta_range_t get_rx_rates(size_t chan) + { return _tree->access<meta_range_t>(rx_dsp_root(chan) / "rate" / "range").get(); } - tune_result_t set_rx_freq(const tune_request_t &tune_request, size_t chan){ - - // If any mixer is driven by an external LO the daughterboard assumes that no CORDIC correction is - // necessary. Since the LO might be sourced from another daughterboard which would normally apply a - // cordic correction a manual DSP tune policy should be used to ensure identical configurations across - // daughterboards. - if (tune_request.dsp_freq_policy == tune_request.POLICY_AUTO and - tune_request.rf_freq_policy == tune_request.POLICY_AUTO) - { + tune_result_t set_rx_freq(const tune_request_t& tune_request, size_t chan) + { + // If any mixer is driven by an external LO the daughterboard assumes that no + // CORDIC correction is necessary. Since the LO might be sourced from another + // daughterboard which would normally apply a cordic correction a manual DSP tune + // policy should be used to ensure identical configurations across daughterboards. + if (tune_request.dsp_freq_policy == tune_request.POLICY_AUTO + and tune_request.rf_freq_policy == tune_request.POLICY_AUTO) { for (size_t c = 0; c < get_rx_num_channels(); c++) { - const bool external_all_los = _tree->exists(rx_rf_fe_root(chan) / "los" / ALL_LOS) - && get_rx_lo_source(ALL_LOS, c) == "external"; + const bool external_all_los = + _tree->exists(rx_rf_fe_root(chan) / "los" / ALL_LOS) + && get_rx_lo_source(ALL_LOS, c) == "external"; if (external_all_los) { UHD_LOGGER_WARNING("MULTI_USRP") - << "At least one channel is using an external LO." - << "Using a manual DSP frequency policy is recommended to ensure " - << "the same frequency shift on all channels."; + << "At least one channel is using an external LO." + << "Using a manual DSP frequency policy is recommended to ensure " + << "the same frequency shift on all channels."; break; } } } tune_result_t result = tune_xx_subdev_and_dsp(RX_SIGN, - _tree->subtree(rx_dsp_root(chan)), - _tree->subtree(rx_rf_fe_root(chan)), - tune_request); - //do_tune_freq_results_message(tune_request, result, get_rx_freq(chan), "RX"); + _tree->subtree(rx_dsp_root(chan)), + _tree->subtree(rx_rf_fe_root(chan)), + tune_request); + // do_tune_freq_results_message(tune_request, result, get_rx_freq(chan), "RX"); return result; } - double get_rx_freq(size_t chan){ - return derive_freq_from_xx_subdev_and_dsp(RX_SIGN, _tree->subtree(rx_dsp_root(chan)), _tree->subtree(rx_rf_fe_root(chan))); + double get_rx_freq(size_t chan) + { + return derive_freq_from_xx_subdev_and_dsp(RX_SIGN, + _tree->subtree(rx_dsp_root(chan)), + _tree->subtree(rx_rf_fe_root(chan))); } - freq_range_t get_rx_freq_range(size_t chan){ + freq_range_t get_rx_freq_range(size_t chan) + { return make_overall_tune_range( _tree->access<meta_range_t>(rx_rf_fe_root(chan) / "freq" / "range").get(), _tree->access<meta_range_t>(rx_dsp_root(chan) / "freq" / "range").get(), - this->get_rx_bandwidth(chan) - ); + this->get_rx_bandwidth(chan)); } - freq_range_t get_fe_rx_freq_range(size_t chan){ + freq_range_t get_fe_rx_freq_range(size_t chan) + { return _tree->access<meta_range_t>(rx_rf_fe_root(chan) / "freq" / "range").get(); } /************************************************************************** * LO controls *************************************************************************/ - std::vector<std::string> get_rx_lo_names(size_t chan = 0){ + std::vector<std::string> get_rx_lo_names(size_t chan = 0) + { std::vector<std::string> lo_names; if (_tree->exists(rx_rf_fe_root(chan) / "los")) { - for(const std::string &name: _tree->list(rx_rf_fe_root(chan) / "los")) { + for (const std::string& name : _tree->list(rx_rf_fe_root(chan) / "los")) { lo_names.push_back(name); } } return lo_names; } - void set_rx_lo_source(const std::string &src, const std::string &name = ALL_LOS, size_t chan = 0){ + void set_rx_lo_source( + const std::string& src, const std::string& name = ALL_LOS, size_t chan = 0) + { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { if (_tree->exists(rx_rf_fe_root(chan) / "los" / ALL_LOS)) { - //Special value ALL_LOS support atomically sets the source for all LOs - _tree->access<std::string>(rx_rf_fe_root(chan) / "los" / ALL_LOS / "source" / "value").set(src); + // Special value ALL_LOS support atomically sets the source for all + // LOs + _tree + ->access<std::string>( + rx_rf_fe_root(chan) / "los" / ALL_LOS / "source" / "value") + .set(src); } else { - for(const std::string &n: _tree->list(rx_rf_fe_root(chan) / "los")) { + for (const std::string& n : + _tree->list(rx_rf_fe_root(chan) / "los")) { this->set_rx_lo_source(src, n, chan); } } } else { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { - _tree->access<std::string>(rx_rf_fe_root(chan) / "los" / name / "source" / "value").set(src); + _tree + ->access<std::string>( + rx_rf_fe_root(chan) / "los" / name / "source" / "value") + .set(src); } else { throw uhd::runtime_error("Could not find LO stage " + name); } } } else { - throw uhd::runtime_error("This device does not support manual configuration of LOs"); + throw uhd::runtime_error( + "This device does not support manual configuration of LOs"); } } - const std::string get_rx_lo_source(const std::string &name = ALL_LOS, size_t chan = 0){ + const std::string get_rx_lo_source(const std::string& name = ALL_LOS, size_t chan = 0) + { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { - //Special value ALL_LOS support atomically sets the source for all LOs - return _tree->access<std::string>(rx_rf_fe_root(chan) / "los" / ALL_LOS / "source" / "value").get(); + // Special value ALL_LOS support atomically sets the source for all LOs + return _tree + ->access<std::string>( + rx_rf_fe_root(chan) / "los" / ALL_LOS / "source" / "value") + .get(); } else { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { - return _tree->access<std::string>(rx_rf_fe_root(chan) / "los" / name / "source" / "value").get(); + return _tree + ->access<std::string>( + rx_rf_fe_root(chan) / "los" / name / "source" / "value") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } @@ -1145,18 +1189,27 @@ public: } } - std::vector<std::string> get_rx_lo_sources(const std::string &name = ALL_LOS, size_t chan = 0) { + std::vector<std::string> get_rx_lo_sources( + const std::string& name = ALL_LOS, size_t chan = 0) + { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { if (_tree->exists(rx_rf_fe_root(chan) / "los" / ALL_LOS)) { - //Special value ALL_LOS support atomically sets the source for all LOs - return _tree->access< std::vector<std::string> >(rx_rf_fe_root(chan) / "los" / ALL_LOS / "source" / "options").get(); + // Special value ALL_LOS support atomically sets the source for all + // LOs + return _tree + ->access<std::vector<std::string>>( + rx_rf_fe_root(chan) / "los" / ALL_LOS / "source" / "options") + .get(); } else { return std::vector<std::string>(); } } else { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { - return _tree->access< std::vector<std::string> >(rx_rf_fe_root(chan) / "los" / name / "source" / "options").get(); + return _tree + ->access<std::vector<std::string>>( + rx_rf_fe_root(chan) / "los" / name / "source" / "options") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } @@ -1167,37 +1220,49 @@ public: } } - void set_rx_lo_export_enabled(bool enabled, const std::string &name = ALL_LOS, size_t chan = 0){ + void set_rx_lo_export_enabled( + bool enabled, const std::string& name = ALL_LOS, size_t chan = 0) + { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { if (_tree->exists(rx_rf_fe_root(chan) / "los" / ALL_LOS)) { - //Special value ALL_LOS support atomically sets the source for all LOs - _tree->access<bool>(rx_rf_fe_root(chan) / "los" / ALL_LOS / "export").set(enabled); + // Special value ALL_LOS support atomically sets the source for all + // LOs + _tree->access<bool>(rx_rf_fe_root(chan) / "los" / ALL_LOS / "export") + .set(enabled); } else { - for(const std::string &n: _tree->list(rx_rf_fe_root(chan) / "los")) { + for (const std::string& n : + _tree->list(rx_rf_fe_root(chan) / "los")) { this->set_rx_lo_export_enabled(enabled, n, chan); } } } else { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { - _tree->access<bool>(rx_rf_fe_root(chan) / "los" / name / "export").set(enabled); + _tree->access<bool>(rx_rf_fe_root(chan) / "los" / name / "export") + .set(enabled); } else { throw uhd::runtime_error("Could not find LO stage " + name); } } } else { - throw uhd::runtime_error("This device does not support manual configuration of LOs"); + throw uhd::runtime_error( + "This device does not support manual configuration of LOs"); } } - bool get_rx_lo_export_enabled(const std::string &name = ALL_LOS, size_t chan = 0){ + bool get_rx_lo_export_enabled(const std::string& name = ALL_LOS, size_t chan = 0) + { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { - //Special value ALL_LOS support atomically sets the source for all LOs - return _tree->access<bool>(rx_rf_fe_root(chan) / "los" / ALL_LOS / "export").get(); + // Special value ALL_LOS support atomically sets the source for all LOs + return _tree + ->access<bool>(rx_rf_fe_root(chan) / "los" / ALL_LOS / "export") + .get(); } else { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { - return _tree->access<bool>(rx_rf_fe_root(chan) / "los" / name / "export").get(); + return _tree + ->access<bool>(rx_rf_fe_root(chan) / "los" / name / "export") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } @@ -1208,61 +1273,82 @@ public: } } - double set_rx_lo_freq(double freq, const std::string &name = ALL_LOS, size_t chan = 0){ + double set_rx_lo_freq(double freq, const std::string& name = ALL_LOS, size_t chan = 0) + { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { - throw uhd::runtime_error("LO frequency must be set for each stage individually"); + throw uhd::runtime_error( + "LO frequency must be set for each stage individually"); } else { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { - _tree->access<double>(rx_rf_fe_root(chan) / "los" / name / "freq" / "value").set(freq); - return _tree->access<double>(rx_rf_fe_root(chan) / "los" / name / "freq" / "value").get(); + _tree + ->access<double>( + rx_rf_fe_root(chan) / "los" / name / "freq" / "value") + .set(freq); + return _tree + ->access<double>( + rx_rf_fe_root(chan) / "los" / name / "freq" / "value") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } } } else { - throw uhd::runtime_error("This device does not support manual configuration of LOs"); + throw uhd::runtime_error( + "This device does not support manual configuration of LOs"); } } - double get_rx_lo_freq(const std::string &name = ALL_LOS, size_t chan = 0){ + double get_rx_lo_freq(const std::string& name = ALL_LOS, size_t chan = 0) + { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { - throw uhd::runtime_error("LO frequency must be retrieved for each stage individually"); + throw uhd::runtime_error( + "LO frequency must be retrieved for each stage individually"); } else { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { - return _tree->access<double>(rx_rf_fe_root(chan) / "los" / name / "freq" / "value").get(); + return _tree + ->access<double>( + rx_rf_fe_root(chan) / "los" / name / "freq" / "value") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } } } else { // Return actual RF frequency if the daughterboard doesn't expose it's LO(s) - return _tree->access<double>(rx_rf_fe_root(chan) / "freq" /" value").get(); + return _tree->access<double>(rx_rf_fe_root(chan) / "freq" / " value").get(); } } - freq_range_t get_rx_lo_freq_range(const std::string &name = ALL_LOS, size_t chan = 0){ + freq_range_t get_rx_lo_freq_range(const std::string& name = ALL_LOS, size_t chan = 0) + { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { - throw uhd::runtime_error("LO frequency range must be retrieved for each stage individually"); + throw uhd::runtime_error( + "LO frequency range must be retrieved for each stage individually"); } else { if (_tree->exists(rx_rf_fe_root(chan) / "los")) { - return _tree->access<freq_range_t>(rx_rf_fe_root(chan) / "los" / name / "freq" / "range").get(); + return _tree + ->access<freq_range_t>( + rx_rf_fe_root(chan) / "los" / name / "freq" / "range") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } } } else { // Return the actual RF range if the daughterboard doesn't expose it's LO(s) - return _tree->access<meta_range_t>(rx_rf_fe_root(chan) / "freq" / "range").get(); + return _tree->access<meta_range_t>(rx_rf_fe_root(chan) / "freq" / "range") + .get(); } } - std::vector<std::string> get_tx_lo_names(const size_t chan = 0){ + std::vector<std::string> get_tx_lo_names(const size_t chan = 0) + { std::vector<std::string> lo_names; if (_tree->exists(tx_rf_fe_root(chan) / "los")) { - for (const std::string &name : _tree->list(tx_rf_fe_root(chan) / "los")) { + for (const std::string& name : _tree->list(tx_rf_fe_root(chan) / "los")) { lo_names.push_back(name); } } @@ -1270,30 +1356,28 @@ public: } void set_tx_lo_source( - const std::string &src, - const std::string &name = ALL_LOS, - const size_t chan = 0 - ) { + const std::string& src, const std::string& name = ALL_LOS, const size_t chan = 0) + { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { if (_tree->exists(tx_rf_fe_root(chan) / "los" / ALL_LOS)) { // Special value ALL_LOS support atomically sets the source // for all LOs - _tree->access<std::string>( - tx_rf_fe_root(chan) / "los" / ALL_LOS / - "source" / "value" - ).set(src); + _tree + ->access<std::string>( + tx_rf_fe_root(chan) / "los" / ALL_LOS / "source" / "value") + .set(src); } else { - for (const auto &n : _tree->list(tx_rf_fe_root(chan) / "los")) { + for (const auto& n : _tree->list(tx_rf_fe_root(chan) / "los")) { this->set_tx_lo_source(src, n, chan); } } } else { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { - _tree->access<std::string>( - tx_rf_fe_root(chan) / "los" / name / "source" / - "value" - ).set(src); + _tree + ->access<std::string>( + tx_rf_fe_root(chan) / "los" / name / "source" / "value") + .set(src); } else { throw uhd::runtime_error("Could not find LO stage " + name); } @@ -1305,14 +1389,14 @@ public: } const std::string get_tx_lo_source( - const std::string &name = ALL_LOS, - const size_t chan = 0 - ) { + const std::string& name = ALL_LOS, const size_t chan = 0) + { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { - return _tree->access<std::string>( - tx_rf_fe_root(chan) / "los" / name / "source" / "value" - ).get(); + return _tree + ->access<std::string>( + tx_rf_fe_root(chan) / "los" / name / "source" / "value") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } @@ -1324,24 +1408,26 @@ public: } std::vector<std::string> get_tx_lo_sources( - const std::string &name = ALL_LOS, - const size_t chan = 0 - ) { + const std::string& name = ALL_LOS, const size_t chan = 0) + { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { if (_tree->exists(tx_rf_fe_root(chan) / "los" / ALL_LOS)) { // Special value ALL_LOS support atomically sets the source // for all LOs - return _tree->access<std::vector<std::string>>( - tx_rf_fe_root(chan) / "los" / ALL_LOS / - "source" / "options" - ).get(); + return _tree + ->access<std::vector<std::string>>( + tx_rf_fe_root(chan) / "los" / ALL_LOS / "source" / "options") + .get(); } else { return std::vector<std::string>(); } } else { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { - return _tree->access< std::vector<std::string> >(tx_rf_fe_root(chan) / "los" / name / "source" / "options").get(); + return _tree + ->access<std::vector<std::string>>( + tx_rf_fe_root(chan) / "los" / name / "source" / "options") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } @@ -1354,41 +1440,42 @@ public: } void set_tx_lo_export_enabled( - const bool enabled, - const std::string &name = ALL_LOS, - const size_t chan=0 - ) { + const bool enabled, const std::string& name = ALL_LOS, const size_t chan = 0) + { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { if (_tree->exists(tx_rf_fe_root(chan) / "los" / ALL_LOS)) { - //Special value ALL_LOS support atomically sets the source for all LOs - _tree->access<bool>(tx_rf_fe_root(chan) / "los" / ALL_LOS / "export").set(enabled); + // Special value ALL_LOS support atomically sets the source for all + // LOs + _tree->access<bool>(tx_rf_fe_root(chan) / "los" / ALL_LOS / "export") + .set(enabled); } else { - for(const std::string &n: _tree->list(tx_rf_fe_root(chan) / "los")) { + for (const std::string& n : + _tree->list(tx_rf_fe_root(chan) / "los")) { this->set_tx_lo_export_enabled(enabled, n, chan); } } } else { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { - _tree->access<bool>(tx_rf_fe_root(chan) / "los" / name / "export").set(enabled); + _tree->access<bool>(tx_rf_fe_root(chan) / "los" / name / "export") + .set(enabled); } else { throw uhd::runtime_error("Could not find LO stage " + name); } } } else { - throw uhd::runtime_error("This device does not support manual configuration of LOs"); + throw uhd::runtime_error( + "This device does not support manual configuration of LOs"); } } bool get_tx_lo_export_enabled( - const std::string &name = ALL_LOS, - const size_t chan = 0 - ) { + const std::string& name = ALL_LOS, const size_t chan = 0) + { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { - return _tree->access<bool>( - tx_rf_fe_root(chan) / "los" / name / "export" - ).get(); + return _tree->access<bool>(tx_rf_fe_root(chan) / "los" / name / "export") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } @@ -1400,19 +1487,19 @@ public: } double set_tx_lo_freq( - const double freq, - const std::string &name = ALL_LOS, - const size_t chan = 0 - ) { + const double freq, const std::string& name = ALL_LOS, const size_t chan = 0) + { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { throw uhd::runtime_error("LO frequency must be set for each " "stage individually"); } else { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { - return _tree->access<double>( - tx_rf_fe_root(chan) / "los" / name / "freq" / "value" - ).set(freq).get(); + return _tree + ->access<double>( + tx_rf_fe_root(chan) / "los" / name / "freq" / "value") + .set(freq) + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } @@ -1423,17 +1510,18 @@ public: } } - double get_tx_lo_freq( - const std::string &name = ALL_LOS, - const size_t chan = 0 - ) { + double get_tx_lo_freq(const std::string& name = ALL_LOS, const size_t chan = 0) + { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { throw uhd::runtime_error("LO frequency must be retrieved for " "each stage individually"); } else { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { - return _tree->access<double>(tx_rf_fe_root(chan) / "los" / name / "freq" / "value").get(); + return _tree + ->access<double>( + tx_rf_fe_root(chan) / "los" / name / "freq" / "value") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } @@ -1441,25 +1529,23 @@ public: } else { // Return actual RF frequency if the daughterboard doesn't expose // its LO(s) - return _tree->access<double>( - tx_rf_fe_root(chan) / "freq" /" value" - ).get(); + return _tree->access<double>(tx_rf_fe_root(chan) / "freq" / " value").get(); } } freq_range_t get_tx_lo_freq_range( - const std::string &name = ALL_LOS, - const size_t chan = 0 - ) { + const std::string& name = ALL_LOS, const size_t chan = 0) + { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { if (name == ALL_LOS) { throw uhd::runtime_error("LO frequency range must be retrieved " "for each stage individually"); } else { if (_tree->exists(tx_rf_fe_root(chan) / "los")) { - return _tree->access<freq_range_t>( - tx_rf_fe_root(chan) / "los" / name / "freq" / "range" - ).get(); + return _tree + ->access<freq_range_t>( + tx_rf_fe_root(chan) / "los" / name / "freq" / "range") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } @@ -1467,30 +1553,37 @@ public: } else { // Return the actual RF range if the daughterboard doesn't expose // its LO(s) - return _tree->access<meta_range_t>( - tx_rf_fe_root(chan) / "freq" / "range" - ).get(); + return _tree->access<meta_range_t>(tx_rf_fe_root(chan) / "freq" / "range") + .get(); } } /************************************************************************** * Gain control *************************************************************************/ - void set_rx_gain(double gain, const std::string &name, size_t chan){ + void set_rx_gain(double gain, const std::string& name, size_t chan) + { /* Check if any AGC mode is enable and if so warn the user */ if (chan != ALL_CHANS) { if (_tree->exists(rx_rf_fe_root(chan) / "gain" / "agc")) { - bool agc = _tree->access<bool>(rx_rf_fe_root(chan) / "gain" / "agc" / "enable").get(); - if(agc) { - UHD_LOGGER_WARNING("MULTI_USRP") << "AGC enabled for this channel. Setting will be ignored." ; + bool agc = + _tree->access<bool>(rx_rf_fe_root(chan) / "gain" / "agc" / "enable") + .get(); + if (agc) { + UHD_LOGGER_WARNING("MULTI_USRP") + << "AGC enabled for this channel. Setting will be ignored."; } } } else { - for (size_t c = 0; c < get_rx_num_channels(); c++){ + for (size_t c = 0; c < get_rx_num_channels(); c++) { if (_tree->exists(rx_rf_fe_root(c) / "gain" / "agc")) { - bool agc = _tree->access<bool>(rx_rf_fe_root(chan) / "gain" / "agc" / "enable").get(); - if(agc) { - UHD_LOGGER_WARNING("MULTI_USRP") << "AGC enabled for this channel. Setting will be ignored." ; + bool agc = _tree + ->access<bool>( + rx_rf_fe_root(chan) / "gain" / "agc" / "enable") + .get(); + if (agc) { + UHD_LOGGER_WARNING("MULTI_USRP") + << "AGC enabled for this channel. Setting will be ignored."; } } } @@ -1499,20 +1592,26 @@ public: * If device is in AGC mode it will ignore the setting. */ try { return rx_gain_group(chan)->set_value(gain, name); - } catch (uhd::key_error &) { - THROW_GAIN_NAME_ERROR(name,chan,rx); + } catch (uhd::key_error&) { + THROW_GAIN_NAME_ERROR(name, chan, rx); } } - void set_rx_gain_profile(const std::string& profile, const size_t chan){ + void set_rx_gain_profile(const std::string& profile, const size_t chan) + { if (chan != ALL_CHANS) { if (_tree->exists(rx_rf_fe_root(chan) / "gains/all/profile/value")) { - _tree->access<std::string>(rx_rf_fe_root(chan) / "gains/all/profile/value").set(profile); + _tree->access<std::string>( + rx_rf_fe_root(chan) / "gains/all/profile/value") + .set(profile); } } else { - for (size_t c = 0; c < get_rx_num_channels(); c++){ + for (size_t c = 0; c < get_rx_num_channels(); c++) { if (_tree->exists(rx_rf_fe_root(c) / "gains/all/profile/value")) { - _tree->access<std::string>(rx_rf_fe_root(chan) / "gains/all/profile/value").set(profile); + _tree + ->access<std::string>( + rx_rf_fe_root(chan) / "gains/all/profile/value") + .set(profile); } } } @@ -1522,9 +1621,9 @@ public: { if (chan != ALL_CHANS) { if (_tree->exists(rx_rf_fe_root(chan) / "gains/all/profile/value")) { - return _tree->access<std::string>( - rx_rf_fe_root(chan) / "gains/all/profile/value" - ).get(); + return _tree + ->access<std::string>(rx_rf_fe_root(chan) / "gains/all/profile/value") + .get(); } } else { throw uhd::runtime_error("Can't get RX gain profile from " @@ -1537,9 +1636,10 @@ public: { if (chan != ALL_CHANS) { if (_tree->exists(rx_rf_fe_root(chan) / "gains/all/profile/options")) { - return _tree->access<std::vector<std::string>>( - rx_rf_fe_root(chan) / "gains/all/profile/options" - ).get(); + return _tree + ->access<std::vector<std::string>>( + rx_rf_fe_root(chan) / "gains/all/profile/options") + .get(); } } else { throw uhd::runtime_error("Can't get RX gain profile names from " @@ -1556,95 +1656,119 @@ public: } const gain_range_t gain_range = get_rx_gain_range(ALL_GAINS, chan); const double abs_gain = - (gain * (gain_range.stop() - gain_range.start())) - + gain_range.start(); + (gain * (gain_range.stop() - gain_range.start())) + gain_range.start(); set_rx_gain(abs_gain, ALL_GAINS, chan); } void set_rx_agc(bool enable, size_t chan = 0) { - if (chan != ALL_CHANS){ + if (chan != ALL_CHANS) { if (_tree->exists(rx_rf_fe_root(chan) / "gain" / "agc" / "enable")) { - _tree->access<bool>(rx_rf_fe_root(chan) / "gain" / "agc" / "enable").set(enable); + _tree->access<bool>(rx_rf_fe_root(chan) / "gain" / "agc" / "enable") + .set(enable); } else { - UHD_LOGGER_WARNING("MULTI_USRP") << "AGC is not available on this device." ; + UHD_LOGGER_WARNING("MULTI_USRP") + << "AGC is not available on this device."; } return; } - for (size_t c = 0; c < get_rx_num_channels(); c++){ + for (size_t c = 0; c < get_rx_num_channels(); c++) { this->set_rx_agc(enable, c); } - } - double get_rx_gain(const std::string &name, size_t chan){ + double get_rx_gain(const std::string& name, size_t chan) + { try { return rx_gain_group(chan)->get_value(name); - } catch (uhd::key_error &) { - THROW_GAIN_NAME_ERROR(name,chan,rx); + } catch (uhd::key_error&) { + THROW_GAIN_NAME_ERROR(name, chan, rx); } } double get_normalized_rx_gain(size_t chan) { - gain_range_t gain_range = get_rx_gain_range(ALL_GAINS, chan); - double gain_range_width = gain_range.stop() - gain_range.start(); - // In case we have a device without a range of gains: - if (gain_range_width == 0.0) { - return 0; - } - double norm_gain = (get_rx_gain(ALL_GAINS, chan) - gain_range.start()) / gain_range_width; - // Avoid rounding errors: - if (norm_gain > 1.0) return 1.0; - if (norm_gain < 0.0) return 0.0; - return norm_gain; + gain_range_t gain_range = get_rx_gain_range(ALL_GAINS, chan); + double gain_range_width = gain_range.stop() - gain_range.start(); + // In case we have a device without a range of gains: + if (gain_range_width == 0.0) { + return 0; + } + double norm_gain = + (get_rx_gain(ALL_GAINS, chan) - gain_range.start()) / gain_range_width; + // Avoid rounding errors: + if (norm_gain > 1.0) + return 1.0; + if (norm_gain < 0.0) + return 0.0; + return norm_gain; } - gain_range_t get_rx_gain_range(const std::string &name, size_t chan){ + gain_range_t get_rx_gain_range(const std::string& name, size_t chan) + { try { return rx_gain_group(chan)->get_range(name); - } catch (uhd::key_error &) { - THROW_GAIN_NAME_ERROR(name,chan,rx); + } catch (uhd::key_error&) { + THROW_GAIN_NAME_ERROR(name, chan, rx); } } - std::vector<std::string> get_rx_gain_names(size_t chan){ + std::vector<std::string> get_rx_gain_names(size_t chan) + { return rx_gain_group(chan)->get_names(); } - void set_rx_antenna(const std::string &ant, size_t chan){ + void set_rx_antenna(const std::string& ant, size_t chan) + { _tree->access<std::string>(rx_rf_fe_root(chan) / "antenna" / "value").set(ant); } - std::string get_rx_antenna(size_t chan){ - return _tree->access<std::string>(rx_rf_fe_root(chan) / "antenna" / "value").get(); + std::string get_rx_antenna(size_t chan) + { + return _tree->access<std::string>(rx_rf_fe_root(chan) / "antenna" / "value") + .get(); } - std::vector<std::string> get_rx_antennas(size_t chan){ - return _tree->access<std::vector<std::string> >(rx_rf_fe_root(chan) / "antenna" / "options").get(); + std::vector<std::string> get_rx_antennas(size_t chan) + { + return _tree + ->access<std::vector<std::string>>( + rx_rf_fe_root(chan) / "antenna" / "options") + .get(); } - void set_rx_bandwidth(double bandwidth, size_t chan){ + void set_rx_bandwidth(double bandwidth, size_t chan) + { _tree->access<double>(rx_rf_fe_root(chan) / "bandwidth" / "value").set(bandwidth); } - double get_rx_bandwidth(size_t chan){ + double get_rx_bandwidth(size_t chan) + { return _tree->access<double>(rx_rf_fe_root(chan) / "bandwidth" / "value").get(); } - meta_range_t get_rx_bandwidth_range(size_t chan){ - return _tree->access<meta_range_t>(rx_rf_fe_root(chan) / "bandwidth" / "range").get(); + meta_range_t get_rx_bandwidth_range(size_t chan) + { + return _tree->access<meta_range_t>(rx_rf_fe_root(chan) / "bandwidth" / "range") + .get(); } - dboard_iface::sptr get_rx_dboard_iface(size_t chan){ - return _tree->access<dboard_iface::sptr>(rx_rf_fe_root(chan).branch_path().branch_path() / "iface").get(); + dboard_iface::sptr get_rx_dboard_iface(size_t chan) + { + return _tree + ->access<dboard_iface::sptr>( + rx_rf_fe_root(chan).branch_path().branch_path() / "iface") + .get(); } - sensor_value_t get_rx_sensor(const std::string &name, size_t chan){ - return _tree->access<sensor_value_t>(rx_rf_fe_root(chan) / "sensors" / name).get(); + sensor_value_t get_rx_sensor(const std::string& name, size_t chan) + { + return _tree->access<sensor_value_t>(rx_rf_fe_root(chan) / "sensors" / name) + .get(); } - std::vector<std::string> get_rx_sensor_names(size_t chan){ + std::vector<std::string> get_rx_sensor_names(size_t chan) + { std::vector<std::string> sensor_names; if (_tree->exists(rx_rf_fe_root(chan) / "sensors")) { sensor_names = _tree->list(rx_rf_fe_root(chan) / "sensors"); @@ -1652,70 +1776,91 @@ public: return sensor_names; } - void set_rx_dc_offset(const bool enb, size_t chan){ - if (chan != ALL_CHANS){ + void set_rx_dc_offset(const bool enb, size_t chan) + { + if (chan != ALL_CHANS) { if (_tree->exists(rx_fe_root(chan) / "dc_offset" / "enable")) { _tree->access<bool>(rx_fe_root(chan) / "dc_offset" / "enable").set(enb); } else if (_tree->exists(rx_rf_fe_root(chan) / "dc_offset" / "enable")) { - /*For B2xx devices the dc-offset correction is implemented in the rf front-end*/ - _tree->access<bool>(rx_rf_fe_root(chan) / "dc_offset" / "enable").set(enb); + /*For B2xx devices the dc-offset correction is implemented in the rf + * front-end*/ + _tree->access<bool>(rx_rf_fe_root(chan) / "dc_offset" / "enable") + .set(enb); } else { - UHD_LOGGER_WARNING("MULTI_USRP") << "Setting DC offset compensation is not possible on this device." ; + UHD_LOGGER_WARNING("MULTI_USRP") + << "Setting DC offset compensation is not possible on this device."; } return; } - for (size_t c = 0; c < get_rx_num_channels(); c++){ + for (size_t c = 0; c < get_rx_num_channels(); c++) { this->set_rx_dc_offset(enb, c); } } - void set_rx_dc_offset(const std::complex<double> &offset, size_t chan){ - if (chan != ALL_CHANS){ + void set_rx_dc_offset(const std::complex<double>& offset, size_t chan) + { + if (chan != ALL_CHANS) { if (_tree->exists(rx_fe_root(chan) / "dc_offset" / "value")) { - _tree->access<std::complex<double> >(rx_fe_root(chan) / "dc_offset" / "value").set(offset); + _tree + ->access<std::complex<double>>( + rx_fe_root(chan) / "dc_offset" / "value") + .set(offset); } else { - UHD_LOGGER_WARNING("MULTI_USRP") << "Setting DC offset is not possible on this device." ; + UHD_LOGGER_WARNING("MULTI_USRP") + << "Setting DC offset is not possible on this device."; } return; } - for (size_t c = 0; c < get_rx_num_channels(); c++){ + for (size_t c = 0; c < get_rx_num_channels(); c++) { this->set_rx_dc_offset(offset, c); } } - meta_range_t get_rx_dc_offset_range(size_t chan) { + meta_range_t get_rx_dc_offset_range(size_t chan) + { if (_tree->exists(rx_fe_root(chan) / "dc_offset" / "range")) { - return _tree->access<uhd::meta_range_t>(rx_fe_root(chan) / "dc_offset" / "range").get(); + return _tree + ->access<uhd::meta_range_t>(rx_fe_root(chan) / "dc_offset" / "range") + .get(); } else { - UHD_LOGGER_WARNING("MULTI_USRP") << "This device does not support querying the RX DC offset range." ; + UHD_LOGGER_WARNING("MULTI_USRP") + << "This device does not support querying the RX DC offset range."; return meta_range_t(0, 0); } } - void set_rx_iq_balance(const bool enb, size_t chan){ - if (chan != ALL_CHANS){ + void set_rx_iq_balance(const bool enb, size_t chan) + { + if (chan != ALL_CHANS) { if (_tree->exists(rx_rf_fe_root(chan) / "iq_balance" / "enable")) { - _tree->access<bool>(rx_rf_fe_root(chan) / "iq_balance" / "enable").set(enb); + _tree->access<bool>(rx_rf_fe_root(chan) / "iq_balance" / "enable") + .set(enb); } else { - UHD_LOGGER_WARNING("MULTI_USRP") << "Setting IQ imbalance compensation is not possible on this device." ; + UHD_LOGGER_WARNING("MULTI_USRP") << "Setting IQ imbalance compensation " + "is not possible on this device."; } return; } - for (size_t c = 0; c < get_rx_num_channels(); c++){ + for (size_t c = 0; c < get_rx_num_channels(); c++) { this->set_rx_iq_balance(enb, c); } } - void set_rx_iq_balance(const std::complex<double> &offset, size_t chan){ - if (chan != ALL_CHANS){ + void set_rx_iq_balance(const std::complex<double>& offset, size_t chan) + { + if (chan != ALL_CHANS) { if (_tree->exists(rx_fe_root(chan) / "iq_balance" / "value")) { - _tree->access<std::complex<double> >(rx_fe_root(chan) / "iq_balance" / "value").set(offset); + _tree + ->access<std::complex<double>>( + rx_fe_root(chan) / "iq_balance" / "value") + .set(offset); } else { - UHD_LOGGER_WARNING("MULTI_USRP") << "Setting IQ balance is not possible on this device." ; + UHD_LOGGER_WARNING("MULTI_USRP") + << "Setting IQ balance is not possible on this device."; } return; } - for (size_t c = 0; c < get_rx_num_channels(); c++){ + for (size_t c = 0; c < get_rx_num_channels(); c++) { this->set_rx_iq_balance(offset, c); } } @@ -1827,115 +1972,139 @@ public: /******************************************************************* * TX methods ******************************************************************/ - tx_streamer::sptr get_tx_stream(const stream_args_t &args) { + tx_streamer::sptr get_tx_stream(const stream_args_t& args) + { _check_link_rate(args, true); return this->get_device()->get_tx_stream(args); } - void set_tx_subdev_spec(const subdev_spec_t &spec, size_t mboard){ - if (mboard != ALL_MBOARDS){ + void set_tx_subdev_spec(const subdev_spec_t& spec, size_t mboard) + { + if (mboard != ALL_MBOARDS) { _tree->access<subdev_spec_t>(mb_root(mboard) / "tx_subdev_spec").set(spec); return; } - for (size_t m = 0; m < get_num_mboards(); m++){ + for (size_t m = 0; m < get_num_mboards(); m++) { set_tx_subdev_spec(spec, m); } } subdev_spec_t get_tx_subdev_spec(size_t mboard) { - subdev_spec_t spec = _tree->access<subdev_spec_t>(mb_root(mboard) / "tx_subdev_spec").get(); - if (spec.empty()) - { - try - { - const std::string db_name = _tree->list(mb_root(mboard) / "dboards").at(0); - const std::string fe_name = _tree->list(mb_root(mboard) / "dboards" / db_name / "tx_frontends").at(0); + subdev_spec_t spec = + _tree->access<subdev_spec_t>(mb_root(mboard) / "tx_subdev_spec").get(); + if (spec.empty()) { + try { + const std::string db_name = + _tree->list(mb_root(mboard) / "dboards").at(0); + const std::string fe_name = + _tree->list(mb_root(mboard) / "dboards" / db_name / "tx_frontends") + .at(0); spec.push_back(subdev_spec_pair_t(db_name, fe_name)); - _tree->access<subdev_spec_t>(mb_root(mboard) / "tx_subdev_spec").set(spec); + _tree->access<subdev_spec_t>(mb_root(mboard) / "tx_subdev_spec") + .set(spec); + } catch (const std::exception& e) { + throw uhd::index_error( + str(boost::format("multi_usrp::get_tx_subdev_spec(%u) failed to make " + "default spec - %s") + % mboard % e.what())); } - catch(const std::exception &e) - { - throw uhd::index_error(str(boost::format("multi_usrp::get_tx_subdev_spec(%u) failed to make default spec - %s") % mboard % e.what())); - } - UHD_LOGGER_INFO("MULTI_USRP") << "Selecting default TX front end spec: " << spec.to_pp_string(); + UHD_LOGGER_INFO("MULTI_USRP") + << "Selecting default TX front end spec: " << spec.to_pp_string(); } return spec; } - size_t get_tx_num_channels(void){ + size_t get_tx_num_channels(void) + { size_t sum = 0; - for (size_t m = 0; m < get_num_mboards(); m++){ + for (size_t m = 0; m < get_num_mboards(); m++) { sum += get_tx_subdev_spec(m).size(); } return sum; } - std::string get_tx_subdev_name(size_t chan){ + std::string get_tx_subdev_name(size_t chan) + { return _tree->access<std::string>(tx_rf_fe_root(chan) / "name").get(); } - void set_tx_rate(double rate, size_t chan){ - if (chan != ALL_CHANS){ + void set_tx_rate(double rate, size_t chan) + { + if (chan != ALL_CHANS) { _tree->access<double>(tx_dsp_root(chan) / "rate" / "value").set(rate); do_samp_rate_warning_message(rate, get_tx_rate(chan), "TX"); return; } - for (size_t c = 0; c < get_tx_num_channels(); c++){ + for (size_t c = 0; c < get_tx_num_channels(); c++) { set_tx_rate(rate, c); } } - double get_tx_rate(size_t chan){ + double get_tx_rate(size_t chan) + { return _tree->access<double>(tx_dsp_root(chan) / "rate" / "value").get(); } - meta_range_t get_tx_rates(size_t chan){ + meta_range_t get_tx_rates(size_t chan) + { return _tree->access<meta_range_t>(tx_dsp_root(chan) / "rate" / "range").get(); } - tune_result_t set_tx_freq(const tune_request_t &tune_request, size_t chan){ + tune_result_t set_tx_freq(const tune_request_t& tune_request, size_t chan) + { tune_result_t result = tune_xx_subdev_and_dsp(TX_SIGN, - _tree->subtree(tx_dsp_root(chan)), - _tree->subtree(tx_rf_fe_root(chan)), - tune_request); - //do_tune_freq_results_message(tune_request, result, get_tx_freq(chan), "TX"); + _tree->subtree(tx_dsp_root(chan)), + _tree->subtree(tx_rf_fe_root(chan)), + tune_request); + // do_tune_freq_results_message(tune_request, result, get_tx_freq(chan), "TX"); return result; } - double get_tx_freq(size_t chan){ - return derive_freq_from_xx_subdev_and_dsp(TX_SIGN, _tree->subtree(tx_dsp_root(chan)), _tree->subtree(tx_rf_fe_root(chan))); + double get_tx_freq(size_t chan) + { + return derive_freq_from_xx_subdev_and_dsp(TX_SIGN, + _tree->subtree(tx_dsp_root(chan)), + _tree->subtree(tx_rf_fe_root(chan))); } - freq_range_t get_tx_freq_range(size_t chan){ + freq_range_t get_tx_freq_range(size_t chan) + { return make_overall_tune_range( _tree->access<meta_range_t>(tx_rf_fe_root(chan) / "freq" / "range").get(), _tree->access<meta_range_t>(tx_dsp_root(chan) / "freq" / "range").get(), - this->get_tx_bandwidth(chan) - ); + this->get_tx_bandwidth(chan)); } - freq_range_t get_fe_tx_freq_range(size_t chan){ + freq_range_t get_fe_tx_freq_range(size_t chan) + { return _tree->access<meta_range_t>(tx_rf_fe_root(chan) / "freq" / "range").get(); } - void set_tx_gain(double gain, const std::string &name, size_t chan){ + void set_tx_gain(double gain, const std::string& name, size_t chan) + { try { return tx_gain_group(chan)->set_value(gain, name); - } catch (uhd::key_error &) { - THROW_GAIN_NAME_ERROR(name,chan,tx); + } catch (uhd::key_error&) { + THROW_GAIN_NAME_ERROR(name, chan, tx); } } - void set_tx_gain_profile(const std::string& profile, const size_t chan){ + void set_tx_gain_profile(const std::string& profile, const size_t chan) + { if (chan != ALL_CHANS) { if (_tree->exists(tx_rf_fe_root(chan) / "gains/all/profile/value")) { - _tree->access<std::string>(tx_rf_fe_root(chan) / "gains/all/profile/value").set(profile); + _tree->access<std::string>( + tx_rf_fe_root(chan) / "gains/all/profile/value") + .set(profile); } } else { - for (size_t c = 0; c < get_tx_num_channels(); c++){ + for (size_t c = 0; c < get_tx_num_channels(); c++) { if (_tree->exists(tx_rf_fe_root(c) / "gains/all/profile/value")) { - _tree->access<std::string>(tx_rf_fe_root(chan) / "gains/all/profile/value").set(profile); + _tree + ->access<std::string>( + tx_rf_fe_root(chan) / "gains/all/profile/value") + .set(profile); } } } @@ -1945,9 +2114,9 @@ public: { if (chan != ALL_CHANS) { if (_tree->exists(tx_rf_fe_root(chan) / "gains/all/profile/value")) { - return _tree->access<std::string>( - tx_rf_fe_root(chan) / "gains/all/profile/value" - ).get(); + return _tree + ->access<std::string>(tx_rf_fe_root(chan) / "gains/all/profile/value") + .get(); } } else { throw uhd::runtime_error("Can't get TX gain profile from " @@ -1960,9 +2129,10 @@ public: { if (chan != ALL_CHANS) { if (_tree->exists(tx_rf_fe_root(chan) / "gains/all/profile/options")) { - return _tree->access<std::vector<std::string>>( - tx_rf_fe_root(chan) / "gains/all/profile/options" - ).get(); + return _tree + ->access<std::vector<std::string>>( + tx_rf_fe_root(chan) / "gains/all/profile/options") + .get(); } } else { throw uhd::runtime_error("Can't get TX gain profile names from " @@ -1973,83 +2143,108 @@ public: void set_normalized_tx_gain(double gain, size_t chan = 0) { - if (gain > 1.0 || gain < 0.0) { - throw uhd::runtime_error("Normalized gain out of range, must be in [0, 1]."); - } - gain_range_t gain_range = get_tx_gain_range(ALL_GAINS, chan); - double abs_gain = (gain * (gain_range.stop() - gain_range.start())) + gain_range.start(); - set_tx_gain(abs_gain, ALL_GAINS, chan); + if (gain > 1.0 || gain < 0.0) { + throw uhd::runtime_error("Normalized gain out of range, must be in [0, 1]."); + } + gain_range_t gain_range = get_tx_gain_range(ALL_GAINS, chan); + double abs_gain = + (gain * (gain_range.stop() - gain_range.start())) + gain_range.start(); + set_tx_gain(abs_gain, ALL_GAINS, chan); } - double get_tx_gain(const std::string &name, size_t chan){ + double get_tx_gain(const std::string& name, size_t chan) + { try { return tx_gain_group(chan)->get_value(name); - } catch (uhd::key_error &) { - THROW_GAIN_NAME_ERROR(name,chan,tx); + } catch (uhd::key_error&) { + THROW_GAIN_NAME_ERROR(name, chan, tx); } } double get_normalized_tx_gain(size_t chan) { - gain_range_t gain_range = get_tx_gain_range(ALL_GAINS, chan); - double gain_range_width = gain_range.stop() - gain_range.start(); - // In case we have a device without a range of gains: - if (gain_range_width == 0.0) { - return 0.0; - } - double norm_gain = (get_tx_gain(ALL_GAINS, chan) - gain_range.start()) / gain_range_width; - // Avoid rounding errors: - if (norm_gain > 1.0) return 1.0; - if (norm_gain < 0.0) return 0.0; - return norm_gain; - } - - gain_range_t get_tx_gain_range(const std::string &name, size_t chan){ + gain_range_t gain_range = get_tx_gain_range(ALL_GAINS, chan); + double gain_range_width = gain_range.stop() - gain_range.start(); + // In case we have a device without a range of gains: + if (gain_range_width == 0.0) { + return 0.0; + } + double norm_gain = + (get_tx_gain(ALL_GAINS, chan) - gain_range.start()) / gain_range_width; + // Avoid rounding errors: + if (norm_gain > 1.0) + return 1.0; + if (norm_gain < 0.0) + return 0.0; + return norm_gain; + } + + gain_range_t get_tx_gain_range(const std::string& name, size_t chan) + { try { return tx_gain_group(chan)->get_range(name); - } catch (uhd::key_error &) { - THROW_GAIN_NAME_ERROR(name,chan,tx); + } catch (uhd::key_error&) { + THROW_GAIN_NAME_ERROR(name, chan, tx); } } - std::vector<std::string> get_tx_gain_names(size_t chan){ + std::vector<std::string> get_tx_gain_names(size_t chan) + { return tx_gain_group(chan)->get_names(); } - void set_tx_antenna(const std::string &ant, size_t chan){ + void set_tx_antenna(const std::string& ant, size_t chan) + { _tree->access<std::string>(tx_rf_fe_root(chan) / "antenna" / "value").set(ant); } - std::string get_tx_antenna(size_t chan){ - return _tree->access<std::string>(tx_rf_fe_root(chan) / "antenna" / "value").get(); + std::string get_tx_antenna(size_t chan) + { + return _tree->access<std::string>(tx_rf_fe_root(chan) / "antenna" / "value") + .get(); } - std::vector<std::string> get_tx_antennas(size_t chan){ - return _tree->access<std::vector<std::string> >(tx_rf_fe_root(chan) / "antenna" / "options").get(); + std::vector<std::string> get_tx_antennas(size_t chan) + { + return _tree + ->access<std::vector<std::string>>( + tx_rf_fe_root(chan) / "antenna" / "options") + .get(); } - void set_tx_bandwidth(double bandwidth, size_t chan){ + void set_tx_bandwidth(double bandwidth, size_t chan) + { _tree->access<double>(tx_rf_fe_root(chan) / "bandwidth" / "value").set(bandwidth); } - double get_tx_bandwidth(size_t chan){ + double get_tx_bandwidth(size_t chan) + { return _tree->access<double>(tx_rf_fe_root(chan) / "bandwidth" / "value").get(); } - meta_range_t get_tx_bandwidth_range(size_t chan){ - return _tree->access<meta_range_t>(tx_rf_fe_root(chan) / "bandwidth" / "range").get(); + meta_range_t get_tx_bandwidth_range(size_t chan) + { + return _tree->access<meta_range_t>(tx_rf_fe_root(chan) / "bandwidth" / "range") + .get(); } - dboard_iface::sptr get_tx_dboard_iface(size_t chan){ - return _tree->access<dboard_iface::sptr>(tx_rf_fe_root(chan).branch_path().branch_path() / "iface").get(); + dboard_iface::sptr get_tx_dboard_iface(size_t chan) + { + return _tree + ->access<dboard_iface::sptr>( + tx_rf_fe_root(chan).branch_path().branch_path() / "iface") + .get(); } - sensor_value_t get_tx_sensor(const std::string &name, size_t chan){ - return _tree->access<sensor_value_t>(tx_rf_fe_root(chan) / "sensors" / name).get(); + sensor_value_t get_tx_sensor(const std::string& name, size_t chan) + { + return _tree->access<sensor_value_t>(tx_rf_fe_root(chan) / "sensors" / name) + .get(); } - std::vector<std::string> get_tx_sensor_names(size_t chan){ + std::vector<std::string> get_tx_sensor_names(size_t chan) + { std::vector<std::string> sensor_names; if (_tree->exists(rx_rf_fe_root(chan) / "sensors")) { sensor_names = _tree->list(tx_rf_fe_root(chan) / "sensors"); @@ -2057,39 +2252,53 @@ public: return sensor_names; } - void set_tx_dc_offset(const std::complex<double> &offset, size_t chan){ - if (chan != ALL_CHANS){ + void set_tx_dc_offset(const std::complex<double>& offset, size_t chan) + { + if (chan != ALL_CHANS) { if (_tree->exists(tx_fe_root(chan) / "dc_offset" / "value")) { - _tree->access<std::complex<double> >(tx_fe_root(chan) / "dc_offset" / "value").set(offset); + _tree + ->access<std::complex<double>>( + tx_fe_root(chan) / "dc_offset" / "value") + .set(offset); } else { - UHD_LOGGER_WARNING("MULTI_USRP") << "Setting DC offset is not possible on this device." ; + UHD_LOGGER_WARNING("MULTI_USRP") + << "Setting DC offset is not possible on this device."; } return; } - for (size_t c = 0; c < get_tx_num_channels(); c++){ + for (size_t c = 0; c < get_tx_num_channels(); c++) { this->set_tx_dc_offset(offset, c); } } - meta_range_t get_tx_dc_offset_range(size_t chan) { + meta_range_t get_tx_dc_offset_range(size_t chan) + { if (_tree->exists(tx_fe_root(chan) / "dc_offset" / "range")) { - return _tree->access<uhd::meta_range_t>(tx_fe_root(chan) / "dc_offset" / "range").get(); + return _tree + ->access<uhd::meta_range_t>(tx_fe_root(chan) / "dc_offset" / "range") + .get(); } else { - UHD_LOGGER_WARNING("MULTI_USRP") << "This device does not support querying the TX DC offset range." ; + UHD_LOGGER_WARNING("MULTI_USRP") + << "This device does not support querying the TX DC offset range."; return meta_range_t(0, 0); } } - void set_tx_iq_balance(const std::complex<double> &offset, size_t chan){ - if (chan != ALL_CHANS){ + void set_tx_iq_balance(const std::complex<double>& offset, size_t chan) + { + if (chan != ALL_CHANS) { if (_tree->exists(tx_fe_root(chan) / "iq_balance" / "value")) { - _tree->access<std::complex<double> >(tx_fe_root(chan) / "iq_balance" / "value").set(offset); + _tree + ->access<std::complex<double>>( + tx_fe_root(chan) / "iq_balance" / "value") + .set(offset); } else { - UHD_LOGGER_WARNING("MULTI_USRP") << "Setting IQ balance is not possible on this device." ; + UHD_LOGGER_WARNING("MULTI_USRP") + << "Setting IQ balance is not possible on this device."; } return; } - for (size_t c = 0; c < get_tx_num_channels(); c++){ + for (size_t c = 0; c < get_tx_num_channels(); c++) { this->set_tx_iq_balance(offset, c); } } @@ -2100,80 +2309,77 @@ public: std::vector<std::string> get_gpio_banks(const size_t mboard) { std::vector<std::string> banks; - if (_tree->exists(mb_root(mboard) / "gpio")) - { - for(const std::string &name: _tree->list(mb_root(mboard) / "gpio")) - { + if (_tree->exists(mb_root(mboard) / "gpio")) { + for (const std::string& name : _tree->list(mb_root(mboard) / "gpio")) { banks.push_back(name); } } - for(const std::string &name: _tree->list(mb_root(mboard) / "dboards")) - { - banks.push_back("RX"+name); - banks.push_back("TX"+name); + for (const std::string& name : _tree->list(mb_root(mboard) / "dboards")) { + banks.push_back("RX" + name); + banks.push_back("TX" + name); } return banks; } - void set_gpio_attr( - const std::string &bank, - const std::string &attr, + void set_gpio_attr(const std::string& bank, + const std::string& attr, const uint32_t value, const uint32_t mask, - const size_t mboard - ) { + const size_t mboard) + { std::vector<std::string> attr_value; if (_tree->exists(mb_root(mboard) / "gpio" / bank)) { - if (_tree->exists(mb_root(mboard) / "gpio" / bank / attr)){ + if (_tree->exists(mb_root(mboard) / "gpio" / bank / attr)) { const auto attr_type = gpio_atr::gpio_attr_rev_map.at(attr); switch (attr_type) { case gpio_atr::GPIO_SRC: throw uhd::runtime_error( - "Can't set SRC attribute using integer value!" - ); + "Can't set SRC attribute using integer value!"); break; case gpio_atr::GPIO_CTRL: case gpio_atr::GPIO_DDR: { - attr_value = _tree->access<std::vector<std::string>>( - mb_root(mboard) / "gpio" / bank / attr - ).get(); + attr_value = _tree + ->access<std::vector<std::string>>( + mb_root(mboard) / "gpio" / bank / attr) + .get(); UHD_ASSERT_THROW(attr_value.size() <= 32); - std::bitset<32> bit_mask = std::bitset<32>(mask); + std::bitset<32> bit_mask = std::bitset<32>(mask); std::bitset<32> bit_value = std::bitset<32>(value); for (size_t i = 0; i < bit_mask.size(); i++) { if (bit_mask[i] == 1) { - attr_value[i] = gpio_atr::attr_value_map.at(attr_type).at(bit_value[i]); + attr_value[i] = gpio_atr::attr_value_map.at(attr_type).at( + bit_value[i]); } } - _tree->access<std::vector<std::string>>( - mb_root(mboard) / "gpio" / bank / attr - ).set(attr_value); - } - break; - default:{ - const uint32_t current = _tree->access<uint32_t>( - mb_root(mboard) / "gpio" / bank / attr).get(); + _tree + ->access<std::vector<std::string>>( + mb_root(mboard) / "gpio" / bank / attr) + .set(attr_value); + } break; + default: { + const uint32_t current = + _tree->access<uint32_t>( + mb_root(mboard) / "gpio" / bank / attr) + .get(); const uint32_t new_value = (current & ~mask) | (value & mask); - _tree->access<uint32_t>(mb_root(mboard) / "gpio" / bank / attr).set(new_value); - } - break; + _tree->access<uint32_t>(mb_root(mboard) / "gpio" / bank / attr) + .set(new_value); + } break; } return; } else { throw uhd::runtime_error(str( - boost::format("The hardware has no gpio attribute: `%s':\n") - % attr - )); + boost::format("The hardware has no gpio attribute: `%s':\n") % attr)); } } if (bank.size() > 2 and bank[1] == 'X') { - const std::string name = bank.substr(2); - const dboard_iface::unit_t unit = - (bank[0] == 'R') - ? dboard_iface::UNIT_RX - : dboard_iface::UNIT_TX; - auto iface = _tree->access<dboard_iface::sptr>( - mb_root(mboard) / "dboards" / name / "iface").get(); + const std::string name = bank.substr(2); + const dboard_iface::unit_t unit = (bank[0] == 'R') ? dboard_iface::UNIT_RX + : dboard_iface::UNIT_TX; + auto iface = _tree + ->access<dboard_iface::sptr>( + mb_root(mboard) / "dboards" / name / "iface") + .get(); if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_CTRL)) iface->set_pin_ctrl(unit, uint16_t(value), uint16_t(mask)); if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_DDR)) @@ -2181,77 +2387,92 @@ public: if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_OUT)) iface->set_gpio_out(unit, uint16_t(value), uint16_t(mask)); if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_ATR_0X)) - iface->set_atr_reg(unit, gpio_atr::ATR_REG_IDLE, uint16_t(value), uint16_t(mask)); + iface->set_atr_reg( + unit, gpio_atr::ATR_REG_IDLE, uint16_t(value), uint16_t(mask)); if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_ATR_RX)) - iface->set_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY, uint16_t(value), uint16_t(mask)); + iface->set_atr_reg( + unit, gpio_atr::ATR_REG_RX_ONLY, uint16_t(value), uint16_t(mask)); if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_ATR_TX)) - iface->set_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY, uint16_t(value), uint16_t(mask)); + iface->set_atr_reg( + unit, gpio_atr::ATR_REG_TX_ONLY, uint16_t(value), uint16_t(mask)); if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_ATR_XX)) - iface->set_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX, uint16_t(value), uint16_t(mask)); + iface->set_atr_reg( + unit, gpio_atr::ATR_REG_FULL_DUPLEX, uint16_t(value), uint16_t(mask)); if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_SRC)) { - throw uhd::runtime_error("Setting gpio source does not supported in daughter board."); + throw uhd::runtime_error( + "Setting gpio source does not supported in daughter board."); } return; } - throw uhd::runtime_error(str( - boost::format("The hardware has no GPIO bank `%s'") - % bank - )); + throw uhd::runtime_error( + str(boost::format("The hardware has no GPIO bank `%s'") % bank)); } uint32_t get_gpio_attr( - const std::string &bank, - const std::string &attr, - const size_t mboard - ) { + const std::string& bank, const std::string& attr, const size_t mboard) + { std::vector<std::string> str_val; if (_tree->exists(mb_root(mboard) / "gpio" / bank)) { if (_tree->exists(mb_root(mboard) / "gpio" / bank / attr)) { const auto attr_type = gpio_atr::gpio_attr_rev_map.at(attr); - switch (attr_type){ + switch (attr_type) { case gpio_atr::GPIO_SRC: - throw uhd::runtime_error("Can't set SRC attribute using integer value"); + throw uhd::runtime_error( + "Can't set SRC attribute using integer value"); case gpio_atr::GPIO_CTRL: case gpio_atr::GPIO_DDR: { - str_val = _tree->access<std::vector<std::string>>( - mb_root(mboard) / "gpio" / bank / attr).get(); + str_val = _tree + ->access<std::vector<std::string>>( + mb_root(mboard) / "gpio" / bank / attr) + .get(); uint32_t val = 0; - for(size_t i = 0 ; i < str_val.size() ; i++) { - val += usrp::gpio_atr::gpio_attr_value_pair.at(attr).at(str_val[i]) << i; + for (size_t i = 0; i < str_val.size(); i++) { + val += usrp::gpio_atr::gpio_attr_value_pair.at(attr).at( + str_val[i]) + << i; } return val; } default: - return uint32_t(_tree->access<uint32_t>( - mb_root(mboard) / "gpio" / bank / attr).get()); + return uint32_t( + _tree->access<uint32_t>( + mb_root(mboard) / "gpio" / bank / attr) + .get()); } return 0; } else { throw uhd::runtime_error(str( - boost::format("The hardware has no gpio attribute: `%s'") - % attr - )); + boost::format("The hardware has no gpio attribute: `%s'") % attr)); } } if (bank.size() > 2 and bank[1] == 'X') { - const std::string name = bank.substr(2); - const dboard_iface::unit_t unit = (bank[0] == 'R')? dboard_iface::UNIT_RX : dboard_iface::UNIT_TX; - auto iface = _tree->access<dboard_iface::sptr>( - mb_root(mboard) / "dboards" / name / "iface").get(); - if (attr == "CTRL") return iface->get_pin_ctrl(unit); - if (attr == "DDR") return iface->get_gpio_ddr(unit); - if (attr == "OUT") return iface->get_gpio_out(unit); - if (attr == "ATR_0X") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_IDLE); - if (attr == "ATR_RX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY); - if (attr == "ATR_TX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY); - if (attr == "ATR_XX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX); - if (attr == "READBACK") return iface->read_gpio(unit); - } - throw uhd::runtime_error(str( - boost::format("The hardware has no gpio bank `%s'") - % bank - )); + const std::string name = bank.substr(2); + const dboard_iface::unit_t unit = (bank[0] == 'R') ? dboard_iface::UNIT_RX + : dboard_iface::UNIT_TX; + auto iface = _tree + ->access<dboard_iface::sptr>( + mb_root(mboard) / "dboards" / name / "iface") + .get(); + if (attr == "CTRL") + return iface->get_pin_ctrl(unit); + if (attr == "DDR") + return iface->get_gpio_ddr(unit); + if (attr == "OUT") + return iface->get_gpio_out(unit); + if (attr == "ATR_0X") + return iface->get_atr_reg(unit, gpio_atr::ATR_REG_IDLE); + if (attr == "ATR_RX") + return iface->get_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY); + if (attr == "ATR_TX") + return iface->get_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY); + if (attr == "ATR_XX") + return iface->get_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX); + if (attr == "READBACK") + return iface->read_gpio(unit); + } + throw uhd::runtime_error( + str(boost::format("The hardware has no gpio bank `%s'") % bank)); } // The next four methods are only for RFNoC devices @@ -2286,55 +2507,63 @@ private: //! Container for spp values set in set_rx_spp() std::unordered_map<size_t, size_t> _rx_spp; - struct mboard_chan_pair{ + struct mboard_chan_pair + { size_t mboard, chan; - mboard_chan_pair(void): mboard(0), chan(0){} + mboard_chan_pair(void) : mboard(0), chan(0) {} }; - mboard_chan_pair rx_chan_to_mcp(size_t chan){ + mboard_chan_pair rx_chan_to_mcp(size_t chan) + { mboard_chan_pair mcp; mcp.chan = chan; - for (mcp.mboard = 0; mcp.mboard < get_num_mboards(); mcp.mboard++){ + for (mcp.mboard = 0; mcp.mboard < get_num_mboards(); mcp.mboard++) { size_t sss = get_rx_subdev_spec(mcp.mboard).size(); - if (mcp.chan < sss) break; + if (mcp.chan < sss) + break; mcp.chan -= sss; } - if (mcp.mboard >= get_num_mboards()) - { - throw uhd::index_error(str(boost::format("multi_usrp: RX channel %u out of range for configured RX frontends") % chan)); + if (mcp.mboard >= get_num_mboards()) { + throw uhd::index_error(str( + boost::format( + "multi_usrp: RX channel %u out of range for configured RX frontends") + % chan)); } return mcp; } - mboard_chan_pair tx_chan_to_mcp(size_t chan){ + mboard_chan_pair tx_chan_to_mcp(size_t chan) + { mboard_chan_pair mcp; mcp.chan = chan; - for (mcp.mboard = 0; mcp.mboard < get_num_mboards(); mcp.mboard++){ + for (mcp.mboard = 0; mcp.mboard < get_num_mboards(); mcp.mboard++) { size_t sss = get_tx_subdev_spec(mcp.mboard).size(); - if (mcp.chan < sss) break; + if (mcp.chan < sss) + break; mcp.chan -= sss; } - if (mcp.mboard >= get_num_mboards()) - { - throw uhd::index_error(str(boost::format("multi_usrp: TX channel %u out of range for configured TX frontends") % chan)); + if (mcp.mboard >= get_num_mboards()) { + throw uhd::index_error(str( + boost::format( + "multi_usrp: TX channel %u out of range for configured TX frontends") + % chan)); } return mcp; } fs_path mb_root(const size_t mboard) { - try - { + try { const std::string tree_path = "/mboards/" + std::to_string(mboard); if (_tree->exists(tree_path)) { return tree_path; } else { - throw uhd::index_error(str(boost::format("multi_usrp::mb_root(%u) - path not found") % mboard)); + throw uhd::index_error(str( + boost::format("multi_usrp::mb_root(%u) - path not found") % mboard)); } - } - catch(const std::exception &e) - { - throw uhd::index_error(str(boost::format("multi_usrp::mb_root(%u) - %s") % mboard % e.what())); + } catch (const std::exception& e) { + throw uhd::index_error( + str(boost::format("multi_usrp::mb_root(%u) - %s") % mboard % e.what())); } } @@ -2342,23 +2571,28 @@ private: { mboard_chan_pair mcp = rx_chan_to_mcp(chan); if (_tree->exists(mb_root(mcp.mboard) / "rx_chan_dsp_mapping")) { - std::vector<size_t> map = _tree->access<std::vector<size_t> >(mb_root(mcp.mboard) / "rx_chan_dsp_mapping").get(); + std::vector<size_t> map = _tree + ->access<std::vector<size_t>>( + mb_root(mcp.mboard) / "rx_chan_dsp_mapping") + .get(); UHD_ASSERT_THROW(map.size() > mcp.chan); mcp.chan = map[mcp.chan]; } - try - { + try { const std::string tree_path = mb_root(mcp.mboard) / "rx_dsps" / mcp.chan; if (_tree->exists(tree_path)) { return tree_path; } else { - throw uhd::index_error(str(boost::format("multi_usrp::rx_dsp_root(%u) - mcp(%u) - path not found") % chan % mcp.chan)); + throw uhd::index_error( + str(boost::format( + "multi_usrp::rx_dsp_root(%u) - mcp(%u) - path not found") + % chan % mcp.chan)); } - } - catch(const std::exception &e) - { - throw uhd::index_error(str(boost::format("multi_usrp::rx_dsp_root(%u) - mcp(%u) - %s") % chan % mcp.chan % e.what())); + } catch (const std::exception& e) { + throw uhd::index_error( + str(boost::format("multi_usrp::rx_dsp_root(%u) - mcp(%u) - %s") % chan + % mcp.chan % e.what())); } } @@ -2366,50 +2600,53 @@ private: { mboard_chan_pair mcp = tx_chan_to_mcp(chan); if (_tree->exists(mb_root(mcp.mboard) / "tx_chan_dsp_mapping")) { - std::vector<size_t> map = _tree->access<std::vector<size_t> >(mb_root(mcp.mboard) / "tx_chan_dsp_mapping").get(); + std::vector<size_t> map = _tree + ->access<std::vector<size_t>>( + mb_root(mcp.mboard) / "tx_chan_dsp_mapping") + .get(); UHD_ASSERT_THROW(map.size() > mcp.chan); mcp.chan = map[mcp.chan]; } - try - { + try { const std::string tree_path = mb_root(mcp.mboard) / "tx_dsps" / mcp.chan; if (_tree->exists(tree_path)) { return tree_path; } else { - throw uhd::index_error(str(boost::format("multi_usrp::tx_dsp_root(%u) - mcp(%u) - path not found") % chan % mcp.chan)); + throw uhd::index_error( + str(boost::format( + "multi_usrp::tx_dsp_root(%u) - mcp(%u) - path not found") + % chan % mcp.chan)); } - } - catch(const std::exception &e) - { - throw uhd::index_error(str(boost::format("multi_usrp::tx_dsp_root(%u) - mcp(%u) - %s") % chan % mcp.chan % e.what())); + } catch (const std::exception& e) { + throw uhd::index_error( + str(boost::format("multi_usrp::tx_dsp_root(%u) - mcp(%u) - %s") % chan + % mcp.chan % e.what())); } } fs_path rx_fe_root(const size_t chan) { mboard_chan_pair mcp = rx_chan_to_mcp(chan); - try - { + try { const subdev_spec_pair_t spec = get_rx_subdev_spec(mcp.mboard).at(mcp.chan); return mb_root(mcp.mboard) / "rx_frontends" / spec.db_name; - } - catch(const std::exception &e) - { - throw uhd::index_error(str(boost::format("multi_usrp::rx_fe_root(%u) - mcp(%u) - %s") % chan % mcp.chan % e.what())); + } catch (const std::exception& e) { + throw uhd::index_error( + str(boost::format("multi_usrp::rx_fe_root(%u) - mcp(%u) - %s") % chan + % mcp.chan % e.what())); } } fs_path tx_fe_root(const size_t chan) { mboard_chan_pair mcp = tx_chan_to_mcp(chan); - try - { + try { const subdev_spec_pair_t spec = get_tx_subdev_spec(mcp.mboard).at(mcp.chan); return mb_root(mcp.mboard) / "tx_frontends" / spec.db_name; - } - catch(const std::exception &e) - { - throw uhd::index_error(str(boost::format("multi_usrp::tx_fe_root(%u) - mcp(%u) - %s") % chan % mcp.chan % e.what())); + } catch (const std::exception& e) { + throw uhd::index_error( + str(boost::format("multi_usrp::tx_fe_root(%u) - mcp(%u) - %s") % chan + % mcp.chan % e.what())); } } @@ -2422,65 +2659,80 @@ private: } else if (slot_name == "C") { return 2; } else if (slot_name == "D") { - return 3; + return 3; } else { - throw uhd::key_error(str( + throw uhd::key_error(str( boost::format("[multi_usrp]: radio slot name %s out of supported range.") - % slot_name - )); + % slot_name)); } } fs_path rx_rf_fe_root(const size_t chan) { mboard_chan_pair mcp = rx_chan_to_mcp(chan); - try - { + try { const subdev_spec_pair_t spec = get_rx_subdev_spec(mcp.mboard).at(mcp.chan); - return mb_root(mcp.mboard) / "dboards" / spec.db_name / "rx_frontends" / spec.sd_name; - } - catch(const std::exception &e) - { - throw uhd::index_error(str(boost::format("multi_usrp::rx_rf_fe_root(%u) - mcp(%u) - %s") % chan % mcp.chan % e.what())); + return mb_root(mcp.mboard) / "dboards" / spec.db_name / "rx_frontends" + / spec.sd_name; + } catch (const std::exception& e) { + throw uhd::index_error( + str(boost::format("multi_usrp::rx_rf_fe_root(%u) - mcp(%u) - %s") % chan + % mcp.chan % e.what())); } } fs_path tx_rf_fe_root(const size_t chan) { mboard_chan_pair mcp = tx_chan_to_mcp(chan); - try - { + try { const subdev_spec_pair_t spec = get_tx_subdev_spec(mcp.mboard).at(mcp.chan); - return mb_root(mcp.mboard) / "dboards" / spec.db_name / "tx_frontends" / spec.sd_name; - } - catch(const std::exception &e) - { - throw uhd::index_error(str(boost::format("multi_usrp::tx_rf_fe_root(%u) - mcp(%u) - %s") % chan % mcp.chan % e.what())); + return mb_root(mcp.mboard) / "dboards" / spec.db_name / "tx_frontends" + / spec.sd_name; + } catch (const std::exception& e) { + throw uhd::index_error( + str(boost::format("multi_usrp::tx_rf_fe_root(%u) - mcp(%u) - %s") % chan + % mcp.chan % e.what())); } } - gain_group::sptr rx_gain_group(size_t chan){ - mboard_chan_pair mcp = rx_chan_to_mcp(chan); + gain_group::sptr rx_gain_group(size_t chan) + { + mboard_chan_pair mcp = rx_chan_to_mcp(chan); const subdev_spec_pair_t spec = get_rx_subdev_spec(mcp.mboard).at(mcp.chan); - gain_group::sptr gg = gain_group::make(); - for(const std::string &name: _tree->list(mb_root(mcp.mboard) / "rx_codecs" / spec.db_name / "gains")){ - gg->register_fcns("ADC-"+name, make_gain_fcns_from_subtree(_tree->subtree(mb_root(mcp.mboard) / "rx_codecs" / spec.db_name / "gains" / name)), 0 /* low prio */); - } - for(const std::string &name: _tree->list(rx_rf_fe_root(chan) / "gains")){ - gg->register_fcns(name, make_gain_fcns_from_subtree(_tree->subtree(rx_rf_fe_root(chan) / "gains" / name)), 1 /* high prio */); + gain_group::sptr gg = gain_group::make(); + for (const std::string& name : + _tree->list(mb_root(mcp.mboard) / "rx_codecs" / spec.db_name / "gains")) { + gg->register_fcns("ADC-" + name, + make_gain_fcns_from_subtree(_tree->subtree( + mb_root(mcp.mboard) / "rx_codecs" / spec.db_name / "gains" / name)), + 0 /* low prio */); + } + for (const std::string& name : _tree->list(rx_rf_fe_root(chan) / "gains")) { + gg->register_fcns(name, + make_gain_fcns_from_subtree( + _tree->subtree(rx_rf_fe_root(chan) / "gains" / name)), + 1 /* high prio */); } return gg; } - gain_group::sptr tx_gain_group(size_t chan){ - mboard_chan_pair mcp = tx_chan_to_mcp(chan); + gain_group::sptr tx_gain_group(size_t chan) + { + mboard_chan_pair mcp = tx_chan_to_mcp(chan); const subdev_spec_pair_t spec = get_tx_subdev_spec(mcp.mboard).at(mcp.chan); - gain_group::sptr gg = gain_group::make(); - for(const std::string &name: _tree->list(mb_root(mcp.mboard) / "tx_codecs" / spec.db_name / "gains")){ - gg->register_fcns("DAC-"+name, make_gain_fcns_from_subtree(_tree->subtree(mb_root(mcp.mboard) / "tx_codecs" / spec.db_name / "gains" / name)), 1 /* high prio */); - } - for(const std::string &name: _tree->list(tx_rf_fe_root(chan) / "gains")){ - gg->register_fcns(name, make_gain_fcns_from_subtree(_tree->subtree(tx_rf_fe_root(chan) / "gains" / name)), 0 /* low prio */); + gain_group::sptr gg = gain_group::make(); + for (const std::string& name : + _tree->list(mb_root(mcp.mboard) / "tx_codecs" / spec.db_name / "gains")) { + gg->register_fcns("DAC-" + name, + make_gain_fcns_from_subtree(_tree->subtree( + mb_root(mcp.mboard) / "tx_codecs" / spec.db_name / "gains" / name)), + 1 /* high prio */); + } + for (const std::string& name : _tree->list(tx_rf_fe_root(chan) / "gains")) { + gg->register_fcns(name, + make_gain_fcns_from_subtree( + _tree->subtree(tx_rf_fe_root(chan) / "gains" / name)), + 0 /* low prio */); } return gg; } @@ -2488,27 +2740,29 @@ private: //! \param is_tx True for tx // Assumption is that all mboards use the same link // and that the rate sum is evenly distributed among the mboards - bool _check_link_rate(const stream_args_t &args, bool is_tx) { - bool link_rate_is_ok = true; - size_t bytes_per_sample = convert::get_bytes_per_item(args.otw_format.empty() ? "sc16" : args.otw_format); + bool _check_link_rate(const stream_args_t& args, bool is_tx) + { + bool link_rate_is_ok = true; + size_t bytes_per_sample = convert::get_bytes_per_item( + args.otw_format.empty() ? "sc16" : args.otw_format); double max_link_rate = 0; - double sum_rate = 0; - for(const size_t chan: args.channels) { + double sum_rate = 0; + for (const size_t chan : args.channels) { mboard_chan_pair mcp = is_tx ? tx_chan_to_mcp(chan) : rx_chan_to_mcp(chan); if (_tree->exists(mb_root(mcp.mboard) / "link_max_rate")) { - max_link_rate = std::max( - max_link_rate, - _tree->access<double>(mb_root(mcp.mboard) / "link_max_rate").get() - ); + max_link_rate = std::max(max_link_rate, + _tree->access<double>(mb_root(mcp.mboard) / "link_max_rate").get()); } sum_rate += is_tx ? get_tx_rate(chan) : get_rx_rate(chan); } sum_rate /= get_num_mboards(); if (max_link_rate > 0 and (max_link_rate / bytes_per_sample) < sum_rate) { - UHD_LOGGER_WARNING("MULTI_USRP") << boost::format( - "The total sum of rates (%f MSps on %u channels) exceeds the maximum capacity of the connection.\n" - "This can cause %s." - ) % (sum_rate/1e6) % args.channels.size() % (is_tx ? "underruns (U)" : "overflows (O)") ; + UHD_LOGGER_WARNING("MULTI_USRP") + << boost::format("The total sum of rates (%f MSps on %u channels) " + "exceeds the maximum capacity of the connection.\n" + "This can cause %s.") + % (sum_rate / 1e6) % args.channels.size() + % (is_tx ? "underruns (U)" : "overflows (O)"); link_rate_is_ok = false; } @@ -2516,7 +2770,8 @@ private: } }; -multi_usrp::~multi_usrp(void){ +multi_usrp::~multi_usrp(void) +{ /* NOP */ } diff --git a/host/lib/usrp/multi_usrp_python.hpp b/host/lib/usrp/multi_usrp_python.hpp index 8d25e26d4..f4e0a73e1 100644 --- a/host/lib/usrp/multi_usrp_python.hpp +++ b/host/lib/usrp/multi_usrp_python.hpp @@ -13,11 +13,11 @@ void export_multi_usrp(py::module& m) { - using multi_usrp = uhd::usrp::multi_usrp; + using multi_usrp = uhd::usrp::multi_usrp; const auto ALL_MBOARDS = multi_usrp::ALL_MBOARDS; - const auto ALL_CHANS = multi_usrp::ALL_CHANS; - const auto ALL_LOS = multi_usrp::ALL_LOS; + const auto ALL_CHANS = multi_usrp::ALL_CHANS; + const auto ALL_LOS = multi_usrp::ALL_LOS; py::class_<multi_usrp, multi_usrp::sptr>(m, "multi_usrp") diff --git a/host/lib/usrp/subdev_spec.cpp b/host/lib/usrp/subdev_spec.cpp index 70c27d1e1..0d271e832 100644 --- a/host/lib/usrp/subdev_spec.cpp +++ b/host/lib/usrp/subdev_spec.cpp @@ -5,11 +5,11 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/usrp/subdev_spec.hpp> #include <uhd/exception.hpp> +#include <uhd/usrp/subdev_spec.hpp> #include <boost/algorithm/string.hpp> //for split -#include <boost/tokenizer.hpp> #include <boost/format.hpp> +#include <boost/tokenizer.hpp> #include <sstream> #include <vector> @@ -17,61 +17,72 @@ using namespace uhd; using namespace uhd::usrp; #define pair_tokenizer(inp) \ - boost::tokenizer<boost::char_separator<char> > \ - (inp, boost::char_separator<char>(" ")) + boost::tokenizer<boost::char_separator<char>>(inp, boost::char_separator<char>(" ")) subdev_spec_pair_t::subdev_spec_pair_t( - const std::string &db_name, const std::string &sd_name -): - db_name(db_name), - sd_name(sd_name) + const std::string& db_name, const std::string& sd_name) + : db_name(db_name), sd_name(sd_name) { /* NOP */ } -bool usrp::operator==(const subdev_spec_pair_t &lhs, const subdev_spec_pair_t &rhs){ +bool usrp::operator==(const subdev_spec_pair_t& lhs, const subdev_spec_pair_t& rhs) +{ return (lhs.db_name == rhs.db_name) and (lhs.sd_name == rhs.sd_name); } -bool subdev_spec_pair_t::operator==(const subdev_spec_pair_t &other){ +bool subdev_spec_pair_t::operator==(const subdev_spec_pair_t& other) +{ return (other.db_name == db_name) and (other.sd_name == sd_name); } -bool subdev_spec_pair_t::operator!=(const subdev_spec_pair_t &other){ +bool subdev_spec_pair_t::operator!=(const subdev_spec_pair_t& other) +{ return (other.db_name != db_name) or (other.sd_name != sd_name); } -subdev_spec_t::subdev_spec_t(const std::string &markup){ - for(const std::string &pair: pair_tokenizer(markup)){ - if (pair.empty()) continue; - std::vector<std::string> db_sd; boost::split(db_sd, pair, boost::is_any_of(":")); - switch(db_sd.size()){ - case 1: this->push_back(subdev_spec_pair_t("", db_sd.front())); break; - case 2: this->push_back(subdev_spec_pair_t(db_sd.front(), db_sd.back())); break; - default: throw uhd::value_error("invalid subdev-spec markup string: "+markup); +subdev_spec_t::subdev_spec_t(const std::string& markup) +{ + for (const std::string& pair : pair_tokenizer(markup)) { + if (pair.empty()) + continue; + std::vector<std::string> db_sd; + boost::split(db_sd, pair, boost::is_any_of(":")); + switch (db_sd.size()) { + case 1: + this->push_back(subdev_spec_pair_t("", db_sd.front())); + break; + case 2: + this->push_back(subdev_spec_pair_t(db_sd.front(), db_sd.back())); + break; + default: + throw uhd::value_error("invalid subdev-spec markup string: " + markup); } } } -std::string subdev_spec_t::to_pp_string(void) const{ - if (this->size() == 0) return "Empty Subdevice Specification"; +std::string subdev_spec_t::to_pp_string(void) const +{ + if (this->size() == 0) + return "Empty Subdevice Specification"; std::stringstream ss; size_t count = 0; ss << "Subdevice Specification:" << std::endl; - for(const subdev_spec_pair_t &pair: *this){ - ss << boost::format( - " Channel %d: Daughterboard %s, Subdevice %s" - ) % (count++) % pair.db_name % pair.sd_name << std::endl; + for (const subdev_spec_pair_t& pair : *this) { + ss << boost::format(" Channel %d: Daughterboard %s, Subdevice %s") % (count++) + % pair.db_name % pair.sd_name + << std::endl; } return ss.str(); } -std::string subdev_spec_t::to_string(void) const{ +std::string subdev_spec_t::to_string(void) const +{ std::string markup; size_t count = 0; - for(const subdev_spec_pair_t &pair: *this){ - markup += ((count++)? " " : "") + pair.db_name + ":" + pair.sd_name; + for (const subdev_spec_pair_t& pair : *this) { + markup += ((count++) ? " " : "") + pair.db_name + ":" + pair.sd_name; } return markup; } diff --git a/host/lib/usrp/subdev_spec_c.cpp b/host/lib/usrp/subdev_spec_c.cpp index 8142256ac..b002d6d43 100644 --- a/host/lib/usrp/subdev_spec_c.cpp +++ b/host/lib/usrp/subdev_spec_c.cpp @@ -6,134 +6,94 @@ // #include <uhd/usrp/subdev_spec.h> - #include <string.h> -uhd_error uhd_subdev_spec_pair_free( - uhd_subdev_spec_pair_t *subdev_spec_pair -){ - UHD_SAFE_C( - if(subdev_spec_pair->db_name){ - free(subdev_spec_pair->db_name); - subdev_spec_pair->db_name = NULL; - } - if(subdev_spec_pair->sd_name){ - free(subdev_spec_pair->sd_name); - subdev_spec_pair->sd_name = NULL; - } - ) +uhd_error uhd_subdev_spec_pair_free(uhd_subdev_spec_pair_t* subdev_spec_pair) +{ + UHD_SAFE_C(if (subdev_spec_pair->db_name) { + free(subdev_spec_pair->db_name); + subdev_spec_pair->db_name = NULL; + } if (subdev_spec_pair->sd_name) { + free(subdev_spec_pair->sd_name); + subdev_spec_pair->sd_name = NULL; + }) } -uhd_error uhd_subdev_spec_pairs_equal( - const uhd_subdev_spec_pair_t* first, +uhd_error uhd_subdev_spec_pairs_equal(const uhd_subdev_spec_pair_t* first, const uhd_subdev_spec_pair_t* second, - bool *result_out -){ - UHD_SAFE_C( - *result_out = (uhd_subdev_spec_pair_c_to_cpp(first) == - uhd_subdev_spec_pair_c_to_cpp(second)); - ) + bool* result_out) +{ + UHD_SAFE_C(*result_out = (uhd_subdev_spec_pair_c_to_cpp(first) + == uhd_subdev_spec_pair_c_to_cpp(second));) } -uhd_error uhd_subdev_spec_make( - uhd_subdev_spec_handle* h, - const char* markup -){ - UHD_SAFE_C( - (*h) = new uhd_subdev_spec_t; - std::string markup_cpp(markup); - if(!markup_cpp.empty()){ - (*h)->subdev_spec_cpp = uhd::usrp::subdev_spec_t(markup_cpp); - } - ) +uhd_error uhd_subdev_spec_make(uhd_subdev_spec_handle* h, const char* markup) +{ + UHD_SAFE_C((*h) = new uhd_subdev_spec_t; std::string markup_cpp(markup); + if (!markup_cpp.empty()) { + (*h)->subdev_spec_cpp = uhd::usrp::subdev_spec_t(markup_cpp); + }) } -uhd_error uhd_subdev_spec_free( - uhd_subdev_spec_handle* h -){ - UHD_SAFE_C( - delete (*h); - (*h) = NULL; - ) +uhd_error uhd_subdev_spec_free(uhd_subdev_spec_handle* h) +{ + UHD_SAFE_C(delete (*h); (*h) = NULL;) } -uhd_error uhd_subdev_spec_size( - uhd_subdev_spec_handle h, - size_t *size_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *size_out = h->subdev_spec_cpp.size(); - ) +uhd_error uhd_subdev_spec_size(uhd_subdev_spec_handle h, size_t* size_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *size_out = h->subdev_spec_cpp.size();) } -uhd_error uhd_subdev_spec_push_back( - uhd_subdev_spec_handle h, - const char* markup -){ - UHD_SAFE_C_SAVE_ERROR(h, - h->subdev_spec_cpp.push_back(uhd::usrp::subdev_spec_pair_t(markup)); - ) +uhd_error uhd_subdev_spec_push_back(uhd_subdev_spec_handle h, const char* markup) +{ + UHD_SAFE_C_SAVE_ERROR( + h, h->subdev_spec_cpp.push_back(uhd::usrp::subdev_spec_pair_t(markup));) } uhd_error uhd_subdev_spec_at( - uhd_subdev_spec_handle h, - size_t num, - uhd_subdev_spec_pair_t *subdev_spec_pair_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd_subdev_spec_pair_cpp_to_c( - h->subdev_spec_cpp.at(num), - subdev_spec_pair_out - ); - ) + uhd_subdev_spec_handle h, size_t num, uhd_subdev_spec_pair_t* subdev_spec_pair_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, + uhd_subdev_spec_pair_cpp_to_c(h->subdev_spec_cpp.at(num), subdev_spec_pair_out);) } uhd_error uhd_subdev_spec_to_pp_string( - uhd_subdev_spec_handle h, - char* pp_string_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string pp_string_cpp = h->subdev_spec_cpp.to_pp_string(); + uhd_subdev_spec_handle h, char* pp_string_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR( + h, std::string pp_string_cpp = h->subdev_spec_cpp.to_pp_string(); memset(pp_string_out, '\0', strbuffer_len); - strncpy(pp_string_out, pp_string_cpp.c_str(), strbuffer_len); - ) + strncpy(pp_string_out, pp_string_cpp.c_str(), strbuffer_len);) } uhd_error uhd_subdev_spec_to_string( - uhd_subdev_spec_handle h, - char* string_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string string_cpp = h->subdev_spec_cpp.to_string(); - memset(string_out, '\0', strbuffer_len); - strncpy(string_out, string_cpp.c_str(), strbuffer_len); - ) + uhd_subdev_spec_handle h, char* string_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR(h, std::string string_cpp = h->subdev_spec_cpp.to_string(); + memset(string_out, '\0', strbuffer_len); + strncpy(string_out, string_cpp.c_str(), strbuffer_len);) } uhd_error uhd_subdev_spec_last_error( - uhd_subdev_spec_handle h, - char* error_out, - size_t strbuffer_len -){ - UHD_SAFE_C( - memset(error_out, '\0', strbuffer_len); - strncpy(error_out, h->last_error.c_str(), strbuffer_len); - ) + uhd_subdev_spec_handle h, char* error_out, size_t strbuffer_len) +{ + UHD_SAFE_C(memset(error_out, '\0', strbuffer_len); + strncpy(error_out, h->last_error.c_str(), strbuffer_len);) } uhd::usrp::subdev_spec_pair_t uhd_subdev_spec_pair_c_to_cpp( - const uhd_subdev_spec_pair_t *subdev_spec_pair_c -){ - return uhd::usrp::subdev_spec_pair_t(subdev_spec_pair_c->db_name, - subdev_spec_pair_c->sd_name); + const uhd_subdev_spec_pair_t* subdev_spec_pair_c) +{ + return uhd::usrp::subdev_spec_pair_t( + subdev_spec_pair_c->db_name, subdev_spec_pair_c->sd_name); } void uhd_subdev_spec_pair_cpp_to_c( - const uhd::usrp::subdev_spec_pair_t &subdev_spec_pair_cpp, - uhd_subdev_spec_pair_t *subdev_spec_pair_c -){ + const uhd::usrp::subdev_spec_pair_t& subdev_spec_pair_cpp, + uhd_subdev_spec_pair_t* subdev_spec_pair_c) +{ subdev_spec_pair_c->db_name = strdup(subdev_spec_pair_cpp.db_name.c_str()); subdev_spec_pair_c->sd_name = strdup(subdev_spec_pair_cpp.sd_name.c_str()); } diff --git a/host/lib/usrp/subdev_spec_python.hpp b/host/lib/usrp/subdev_spec_python.hpp index 61a517a6f..ddcb86da2 100644 --- a/host/lib/usrp/subdev_spec_python.hpp +++ b/host/lib/usrp/subdev_spec_python.hpp @@ -15,20 +15,18 @@ void export_subdev_spec(py::module& m) using subdev_spec_pair_t = uhd::usrp::subdev_spec_pair_t; using subdev_spec_t = uhd::usrp::subdev_spec_t; - py::class_<subdev_spec_pair_t> (m, "subdev_spec_pair") - .def(py::init<const std::string&, const std::string &>()) + py::class_<subdev_spec_pair_t>(m, "subdev_spec_pair") + .def(py::init<const std::string&, const std::string&>()) // Properties .def_readwrite("db_name", &subdev_spec_pair_t::db_name) - .def_readwrite("sd_name", &subdev_spec_pair_t::sd_name) - ; + .def_readwrite("sd_name", &subdev_spec_pair_t::sd_name); py::class_<subdev_spec_t>(m, "subdev_spec") - .def(py::init<const std::string &>()) + .def(py::init<const std::string&>()) // Methods - .def("__str__", &subdev_spec_t::to_pp_string) - .def("to_string", &subdev_spec_t::to_string) - ; + .def("__str__", &subdev_spec_t::to_pp_string) + .def("to_string", &subdev_spec_t::to_string); } #endif /* INCLUDED_UHD_USRP_SUBDEV_SPEC_PYTHON_HPP */ diff --git a/host/lib/usrp/usrp1/codec_ctrl.cpp b/host/lib/usrp/usrp1/codec_ctrl.cpp index a06ded707..c75b6e03a 100644 --- a/host/lib/usrp/usrp1/codec_ctrl.cpp +++ b/host/lib/usrp/usrp1/codec_ctrl.cpp @@ -7,17 +7,17 @@ #include "codec_ctrl.hpp" #include "ad9862_regs.hpp" -#include <uhd/utils/log.hpp> -#include <uhd/utils/safe_call.hpp> -#include <uhd/types/dict.hpp> #include <uhd/exception.hpp> +#include <uhd/types/dict.hpp> #include <uhd/utils/algorithm.hpp> #include <uhd/utils/byteswap.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/safe_call.hpp> #include <stdint.h> +#include <boost/assign/list_of.hpp> #include <boost/format.hpp> #include <boost/math/special_functions/round.hpp> #include <boost/math/special_functions/sign.hpp> -#include <boost/assign/list_of.hpp> #include <iomanip> #include <tuple> @@ -26,34 +26,36 @@ using namespace uhd; const gain_range_t usrp1_codec_ctrl::tx_pga_gain_range(-20, 0, double(0.1)); const gain_range_t usrp1_codec_ctrl::rx_pga_gain_range(0, 20, 1); -usrp1_codec_ctrl::~usrp1_codec_ctrl(void){ +usrp1_codec_ctrl::~usrp1_codec_ctrl(void) +{ /* NOP */ } /*********************************************************************** * Codec Control Implementation **********************************************************************/ -class usrp1_codec_ctrl_impl : public usrp1_codec_ctrl { +class usrp1_codec_ctrl_impl : public usrp1_codec_ctrl +{ public: - //structors + // structors usrp1_codec_ctrl_impl(spi_iface::sptr iface, int spi_slave); ~usrp1_codec_ctrl_impl(void); - //aux adc and dac control + // aux adc and dac control double read_aux_adc(aux_adc_t which); void write_aux_dac(aux_dac_t which, double volts); - //duc control + // duc control void set_duc_freq(double freq, double); void enable_tx_digital(bool enb); - //pga gain control + // pga gain control void set_tx_pga_gain(double); double get_tx_pga_gain(void); void set_rx_pga_gain(double, char); double get_rx_pga_gain(char); - - //rx adc buffer control + + // rx adc buffer control void bypass_adc_buffers(bool bypass); private: @@ -70,119 +72,136 @@ private: /*********************************************************************** * Codec Control Structors **********************************************************************/ -usrp1_codec_ctrl_impl::usrp1_codec_ctrl_impl(spi_iface::sptr iface, int spi_slave){ - _iface = iface; +usrp1_codec_ctrl_impl::usrp1_codec_ctrl_impl(spi_iface::sptr iface, int spi_slave) +{ + _iface = iface; _spi_slave = spi_slave; - //soft reset + // soft reset _ad9862_regs.soft_reset = 1; this->send_reg(0); - //initialize the codec register settings + // initialize the codec register settings _ad9862_regs.sdio_bidir = ad9862_regs_t::SDIO_BIDIR_SDIO_SDO; - _ad9862_regs.lsb_first = ad9862_regs_t::LSB_FIRST_MSB; + _ad9862_regs.lsb_first = ad9862_regs_t::LSB_FIRST_MSB; _ad9862_regs.soft_reset = 0; - //setup rx side of codec + // setup rx side of codec _ad9862_regs.byp_buffer_a = 1; _ad9862_regs.byp_buffer_b = 1; - _ad9862_regs.buffer_a_pd = 1; - _ad9862_regs.buffer_b_pd = 1; - _ad9862_regs.rx_pga_a = 0; - _ad9862_regs.rx_pga_b = 0; + _ad9862_regs.buffer_a_pd = 1; + _ad9862_regs.buffer_b_pd = 1; + _ad9862_regs.rx_pga_a = 0; + _ad9862_regs.rx_pga_b = 0; _ad9862_regs.rx_twos_comp = 1; - _ad9862_regs.rx_hilbert = ad9862_regs_t::RX_HILBERT_DIS; - - //setup tx side of codec - _ad9862_regs.two_data_paths = ad9862_regs_t::TWO_DATA_PATHS_BOTH; - _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_INTERLEAVED; - _ad9862_regs.tx_pga_gain = 199; - _ad9862_regs.tx_hilbert = ad9862_regs_t::TX_HILBERT_DIS; - _ad9862_regs.interp = ad9862_regs_t::INTERP_4; - _ad9862_regs.tx_twos_comp = 1; - _ad9862_regs.fine_mode = ad9862_regs_t::FINE_MODE_NCO; - _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS; + _ad9862_regs.rx_hilbert = ad9862_regs_t::RX_HILBERT_DIS; + + // setup tx side of codec + _ad9862_regs.two_data_paths = ad9862_regs_t::TWO_DATA_PATHS_BOTH; + _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_INTERLEAVED; + _ad9862_regs.tx_pga_gain = 199; + _ad9862_regs.tx_hilbert = ad9862_regs_t::TX_HILBERT_DIS; + _ad9862_regs.interp = ad9862_regs_t::INTERP_4; + _ad9862_regs.tx_twos_comp = 1; + _ad9862_regs.fine_mode = ad9862_regs_t::FINE_MODE_NCO; + _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS; _ad9862_regs.dac_a_coarse_gain = 0x3; _ad9862_regs.dac_b_coarse_gain = 0x3; - //setup the dll + // setup the dll _ad9862_regs.input_clk_ctrl = ad9862_regs_t::INPUT_CLK_CTRL_EXTERNAL; - _ad9862_regs.dll_mult = ad9862_regs_t::DLL_MULT_2; - _ad9862_regs.dll_mode = ad9862_regs_t::DLL_MODE_FAST; + _ad9862_regs.dll_mult = ad9862_regs_t::DLL_MULT_2; + _ad9862_regs.dll_mode = ad9862_regs_t::DLL_MODE_FAST; - //setup clockout + // setup clockout _ad9862_regs.clkout2_div_factor = ad9862_regs_t::CLKOUT2_DIV_FACTOR_2; - //write the register settings to the codec + // write the register settings to the codec for (uint8_t addr = 0; addr <= 25; addr++) { this->send_reg(addr); } - //always start conversions for aux ADC + // always start conversions for aux ADC _ad9862_regs.start_a = 1; _ad9862_regs.start_b = 1; - //aux adc clock + // aux adc clock _ad9862_regs.clk_4 = ad9862_regs_t::CLK_4_1_4; this->send_reg(34); } -usrp1_codec_ctrl_impl::~usrp1_codec_ctrl_impl(void){UHD_SAFE_CALL( - //set aux dacs to zero - this->write_aux_dac(AUX_DAC_A, 0); - this->write_aux_dac(AUX_DAC_B, 0); - this->write_aux_dac(AUX_DAC_C, 0); - this->write_aux_dac(AUX_DAC_D, 0); - - //power down - _ad9862_regs.all_rx_pd = 1; - this->send_reg(1); - _ad9862_regs.tx_digital_pd = 1; - _ad9862_regs.tx_analog_pd = ad9862_regs_t::TX_ANALOG_PD_BOTH; - this->send_reg(8); -)} +usrp1_codec_ctrl_impl::~usrp1_codec_ctrl_impl(void) +{ + UHD_SAFE_CALL( + // set aux dacs to zero + this->write_aux_dac(AUX_DAC_A, 0); this->write_aux_dac(AUX_DAC_B, 0); + this->write_aux_dac(AUX_DAC_C, 0); + this->write_aux_dac(AUX_DAC_D, 0); + + // power down + _ad9862_regs.all_rx_pd = 1; + this->send_reg(1); + _ad9862_regs.tx_digital_pd = 1; + _ad9862_regs.tx_analog_pd = ad9862_regs_t::TX_ANALOG_PD_BOTH; + this->send_reg(8);) +} /*********************************************************************** * Codec Control Gain Control Methods **********************************************************************/ -static const int mtpgw = 255; //maximum tx pga gain word +static const int mtpgw = 255; // maximum tx pga gain word -void usrp1_codec_ctrl_impl::set_tx_pga_gain(double gain){ - int gain_word = int(mtpgw*(gain - tx_pga_gain_range.start())/(tx_pga_gain_range.stop() - tx_pga_gain_range.start())); +void usrp1_codec_ctrl_impl::set_tx_pga_gain(double gain) +{ + int gain_word = int(mtpgw * (gain - tx_pga_gain_range.start()) + / (tx_pga_gain_range.stop() - tx_pga_gain_range.start())); _ad9862_regs.tx_pga_gain = uhd::clip(gain_word, 0, mtpgw); this->send_reg(16); } -double usrp1_codec_ctrl_impl::get_tx_pga_gain(void){ - return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.stop() - tx_pga_gain_range.start())/mtpgw) + tx_pga_gain_range.start(); +double usrp1_codec_ctrl_impl::get_tx_pga_gain(void) +{ + return (_ad9862_regs.tx_pga_gain + * (tx_pga_gain_range.stop() - tx_pga_gain_range.start()) / mtpgw) + + tx_pga_gain_range.start(); } -static const int mrpgw = 0x14; //maximum rx pga gain word +static const int mrpgw = 0x14; // maximum rx pga gain word -void usrp1_codec_ctrl_impl::set_rx_pga_gain(double gain, char which){ - int gain_word = int(mrpgw*(gain - rx_pga_gain_range.start())/(rx_pga_gain_range.stop() - rx_pga_gain_range.start())); - gain_word = uhd::clip(gain_word, 0, mrpgw); - switch(which){ - case 'A': - _ad9862_regs.rx_pga_a = gain_word; - this->send_reg(2); - return; - case 'B': - _ad9862_regs.rx_pga_b = gain_word; - this->send_reg(3); - return; - default: UHD_THROW_INVALID_CODE_PATH(); +void usrp1_codec_ctrl_impl::set_rx_pga_gain(double gain, char which) +{ + int gain_word = int(mrpgw * (gain - rx_pga_gain_range.start()) + / (rx_pga_gain_range.stop() - rx_pga_gain_range.start())); + gain_word = uhd::clip(gain_word, 0, mrpgw); + switch (which) { + case 'A': + _ad9862_regs.rx_pga_a = gain_word; + this->send_reg(2); + return; + case 'B': + _ad9862_regs.rx_pga_b = gain_word; + this->send_reg(3); + return; + default: + UHD_THROW_INVALID_CODE_PATH(); } } -double usrp1_codec_ctrl_impl::get_rx_pga_gain(char which){ +double usrp1_codec_ctrl_impl::get_rx_pga_gain(char which) +{ int gain_word; - switch(which){ - case 'A': gain_word = _ad9862_regs.rx_pga_a; break; - case 'B': gain_word = _ad9862_regs.rx_pga_b; break; - default: UHD_THROW_INVALID_CODE_PATH(); + switch (which) { + case 'A': + gain_word = _ad9862_regs.rx_pga_a; + break; + case 'B': + gain_word = _ad9862_regs.rx_pga_b; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } - return (gain_word*(rx_pga_gain_range.stop() - rx_pga_gain_range.start())/mrpgw) + rx_pga_gain_range.start(); + return (gain_word * (rx_pga_gain_range.stop() - rx_pga_gain_range.start()) / mrpgw) + + rx_pga_gain_range.start(); } /*********************************************************************** @@ -190,38 +209,43 @@ double usrp1_codec_ctrl_impl::get_rx_pga_gain(char which){ **********************************************************************/ static double aux_adc_to_volts(uint8_t high, uint8_t low) { - return double(((uint16_t(high) << 2) | low)*3.3)/0x3ff; + return double(((uint16_t(high) << 2) | low) * 3.3) / 0x3ff; } -double usrp1_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ - switch(which){ - case AUX_ADC_A1: - _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC1; - this->send_reg(34); //start conversion and select mux - this->recv_reg(28); //read the value (2 bytes, 2 reads) - this->recv_reg(29); - return aux_adc_to_volts(_ad9862_regs.aux_adc_a1_9_2, _ad9862_regs.aux_adc_a1_1_0); - - case AUX_ADC_A2: - _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC2; - this->send_reg(34); //start conversion and select mux - this->recv_reg(26); //read the value (2 bytes, 2 reads) - this->recv_reg(27); - return aux_adc_to_volts(_ad9862_regs.aux_adc_a2_9_2, _ad9862_regs.aux_adc_a2_1_0); - - case AUX_ADC_B1: - _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC1; - this->send_reg(34); //start conversion and select mux - this->recv_reg(32); //read the value (2 bytes, 2 reads) - this->recv_reg(33); - return aux_adc_to_volts(_ad9862_regs.aux_adc_b1_9_2, _ad9862_regs.aux_adc_b1_1_0); - - case AUX_ADC_B2: - _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC2; - this->send_reg(34); //start conversion and select mux - this->recv_reg(30); //read the value (2 bytes, 2 reads) - this->recv_reg(31); - return aux_adc_to_volts(_ad9862_regs.aux_adc_b2_9_2, _ad9862_regs.aux_adc_b2_1_0); +double usrp1_codec_ctrl_impl::read_aux_adc(aux_adc_t which) +{ + switch (which) { + case AUX_ADC_A1: + _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC1; + this->send_reg(34); // start conversion and select mux + this->recv_reg(28); // read the value (2 bytes, 2 reads) + this->recv_reg(29); + return aux_adc_to_volts( + _ad9862_regs.aux_adc_a1_9_2, _ad9862_regs.aux_adc_a1_1_0); + + case AUX_ADC_A2: + _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC2; + this->send_reg(34); // start conversion and select mux + this->recv_reg(26); // read the value (2 bytes, 2 reads) + this->recv_reg(27); + return aux_adc_to_volts( + _ad9862_regs.aux_adc_a2_9_2, _ad9862_regs.aux_adc_a2_1_0); + + case AUX_ADC_B1: + _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC1; + this->send_reg(34); // start conversion and select mux + this->recv_reg(32); // read the value (2 bytes, 2 reads) + this->recv_reg(33); + return aux_adc_to_volts( + _ad9862_regs.aux_adc_b1_9_2, _ad9862_regs.aux_adc_b1_1_0); + + case AUX_ADC_B2: + _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC2; + this->send_reg(34); // start conversion and select mux + this->recv_reg(30); // read the value (2 bytes, 2 reads) + this->recv_reg(31); + return aux_adc_to_volts( + _ad9862_regs.aux_adc_b2_9_2, _ad9862_regs.aux_adc_b2_1_0); } UHD_THROW_INVALID_CODE_PATH(); } @@ -231,32 +255,31 @@ double usrp1_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ **********************************************************************/ void usrp1_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts) { - //special case for aux dac d (aka sigma delta word) + // special case for aux dac d (aka sigma delta word) if (which == AUX_DAC_D) { - uint16_t dac_word = uhd::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff); + uint16_t dac_word = uhd::clip(boost::math::iround(volts * 0xfff / 3.3), 0, 0xfff); _ad9862_regs.sig_delt_11_4 = uint8_t(dac_word >> 4); - _ad9862_regs.sig_delt_3_0 = uint8_t(dac_word & 0xf); + _ad9862_regs.sig_delt_3_0 = uint8_t(dac_word & 0xf); this->send_reg(42); this->send_reg(43); return; } - //calculate the dac word for aux dac a, b, c - uint8_t dac_word = uhd::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff); + // calculate the dac word for aux dac a, b, c + uint8_t dac_word = uhd::clip(boost::math::iround(volts * 0xff / 3.3), 0, 0xff); - //setup a lookup table for the aux dac params (reg ref, reg addr) + // setup a lookup table for the aux dac params (reg ref, reg addr) typedef std::tuple<uint8_t*, uint8_t> dac_params_t; - uhd::dict<aux_dac_t, dac_params_t> aux_dac_to_params = boost::assign::map_list_of - (AUX_DAC_A, dac_params_t(&_ad9862_regs.aux_dac_a, 36)) - (AUX_DAC_B, dac_params_t(&_ad9862_regs.aux_dac_b, 37)) - (AUX_DAC_C, dac_params_t(&_ad9862_regs.aux_dac_c, 38)) - ; + uhd::dict<aux_dac_t, dac_params_t> aux_dac_to_params = + boost::assign::map_list_of(AUX_DAC_A, dac_params_t(&_ad9862_regs.aux_dac_a, 36))( + AUX_DAC_B, dac_params_t(&_ad9862_regs.aux_dac_b, 37))( + AUX_DAC_C, dac_params_t(&_ad9862_regs.aux_dac_c, 38)); - //set the aux dac register + // set the aux dac register UHD_ASSERT_THROW(aux_dac_to_params.has_key(which)); uint8_t *reg_ref, reg_addr; std::tie(reg_ref, reg_addr) = aux_dac_to_params[which]; - *reg_ref = dac_word; + *reg_ref = dac_word; this->send_reg(reg_addr); } @@ -267,76 +290,62 @@ void usrp1_codec_ctrl_impl::send_reg(uint8_t addr) { uint32_t reg = _ad9862_regs.get_write_reg(addr); - UHD_LOGGER_TRACE("USRP1") - << "codec control write reg: 0x" - << std::setw(8) << std::hex << reg - ; - _iface->write_spi(_spi_slave, - spi_config_t::EDGE_RISE, reg, 16); + UHD_LOGGER_TRACE("USRP1") << "codec control write reg: 0x" << std::setw(8) << std::hex + << reg; + _iface->write_spi(_spi_slave, spi_config_t::EDGE_RISE, reg, 16); } void usrp1_codec_ctrl_impl::recv_reg(uint8_t addr) { uint32_t reg = _ad9862_regs.get_read_reg(addr); - UHD_LOGGER_TRACE("USRP1") - << "codec control read reg: 0x" - << std::setw(8) << std::hex << reg - ; + UHD_LOGGER_TRACE("USRP1") << "codec control read reg: 0x" << std::setw(8) << std::hex + << reg; - uint32_t ret = _iface->read_spi(_spi_slave, - spi_config_t::EDGE_RISE, reg, 16); + uint32_t ret = _iface->read_spi(_spi_slave, spi_config_t::EDGE_RISE, reg, 16); - UHD_LOGGER_TRACE("USRP1") - << "codec control read ret: 0x" - << std::setw(8) << std::hex << ret - ; + UHD_LOGGER_TRACE("USRP1") << "codec control read ret: 0x" << std::setw(8) << std::hex + << ret; _ad9862_regs.set_reg(addr, uint16_t(ret)); } /*********************************************************************** - * DUC tuning + * DUC tuning **********************************************************************/ double usrp1_codec_ctrl_impl::coarse_tune(double codec_rate, double freq) { double coarse_freq; - double coarse_freq_1 = codec_rate / 8; - double coarse_freq_2 = codec_rate / 4; + double coarse_freq_1 = codec_rate / 8; + double coarse_freq_2 = codec_rate / 4; double coarse_limit_1 = coarse_freq_1 / 2; double coarse_limit_2 = (coarse_freq_1 + coarse_freq_2) / 2; - double max_freq = coarse_freq_2 + .09375 * codec_rate; - + double max_freq = coarse_freq_2 + .09375 * codec_rate; + if (freq < -max_freq) { return false; - } - else if (freq < -coarse_limit_2) { + } else if (freq < -coarse_limit_2) { _ad9862_regs.neg_coarse_tune = ad9862_regs_t::NEG_COARSE_TUNE_NEG_SHIFT; - _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_FDAC_4; - coarse_freq = -coarse_freq_2; - } - else if (freq < -coarse_limit_1) { + _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_FDAC_4; + coarse_freq = -coarse_freq_2; + } else if (freq < -coarse_limit_1) { _ad9862_regs.neg_coarse_tune = ad9862_regs_t::NEG_COARSE_TUNE_NEG_SHIFT; - _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_FDAC_8; - coarse_freq = -coarse_freq_1; - } - else if (freq < coarse_limit_1) { + _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_FDAC_8; + coarse_freq = -coarse_freq_1; + } else if (freq < coarse_limit_1) { _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS; - coarse_freq = 0; - } - else if (freq < coarse_limit_2) { + coarse_freq = 0; + } else if (freq < coarse_limit_2) { _ad9862_regs.neg_coarse_tune = ad9862_regs_t::NEG_COARSE_TUNE_POS_SHIFT; - _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_FDAC_8; - coarse_freq = coarse_freq_1; - } - else if (freq <= max_freq) { + _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_FDAC_8; + coarse_freq = coarse_freq_1; + } else if (freq <= max_freq) { _ad9862_regs.neg_coarse_tune = ad9862_regs_t::NEG_COARSE_TUNE_POS_SHIFT; - _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_FDAC_4; - coarse_freq = coarse_freq_2; - } - else { - return 0; + _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_FDAC_4; + coarse_freq = coarse_freq_2; + } else { + return 0; } return coarse_freq; @@ -346,23 +355,22 @@ double usrp1_codec_ctrl_impl::fine_tune(double codec_rate, double target_freq) { static const double scale_factor = std::pow(2.0, 24); - uint32_t freq_word = uint32_t( - boost::math::round(std::abs((target_freq / codec_rate) * scale_factor))); + uint32_t freq_word = + uint32_t(boost::math::round(std::abs((target_freq / codec_rate) * scale_factor))); double actual_freq = freq_word * codec_rate / scale_factor; if (target_freq < 0) { _ad9862_regs.neg_fine_tune = ad9862_regs_t::NEG_FINE_TUNE_NEG_SHIFT; - actual_freq = -actual_freq; - } - else { + actual_freq = -actual_freq; + } else { _ad9862_regs.neg_fine_tune = ad9862_regs_t::NEG_FINE_TUNE_POS_SHIFT; - } + } _ad9862_regs.fine_mode = ad9862_regs_t::FINE_MODE_NCO; _ad9862_regs.ftw_23_16 = (freq_word >> 16) & 0xff; - _ad9862_regs.ftw_15_8 = (freq_word >> 8) & 0xff; - _ad9862_regs.ftw_7_0 = (freq_word >> 0) & 0xff; + _ad9862_regs.ftw_15_8 = (freq_word >> 8) & 0xff; + _ad9862_regs.ftw_7_0 = (freq_word >> 0) & 0xff; return actual_freq; } @@ -371,22 +379,20 @@ void usrp1_codec_ctrl_impl::set_duc_freq(double freq, double rate) { double codec_rate = rate * 2; - //correct for outside of rate (wrap around) + // correct for outside of rate (wrap around) freq = std::fmod(freq, rate); - if (std::abs(freq) > rate/2.0) - freq -= boost::math::sign(freq)*rate; + if (std::abs(freq) > rate / 2.0) + freq -= boost::math::sign(freq) * rate; double coarse_freq = coarse_tune(codec_rate, freq); - double fine_freq = fine_tune(codec_rate / 4, freq - coarse_freq); + double fine_freq = fine_tune(codec_rate / 4, freq - coarse_freq); - UHD_LOGGER_DEBUG("USRP1") - << "ad9862 tuning result:" - << " requested: " << freq - << " actual: " << coarse_freq + fine_freq - << " coarse freq: " << coarse_freq - << " fine freq: " << fine_freq - << " codec rate: " << codec_rate - ; + UHD_LOGGER_DEBUG("USRP1") << "ad9862 tuning result:" + << " requested: " << freq + << " actual: " << coarse_freq + fine_freq + << " coarse freq: " << coarse_freq + << " fine freq: " << fine_freq + << " codec rate: " << codec_rate; this->send_reg(20); this->send_reg(21); @@ -394,8 +400,9 @@ void usrp1_codec_ctrl_impl::set_duc_freq(double freq, double rate) this->send_reg(23); } -void usrp1_codec_ctrl_impl::enable_tx_digital(bool enb){ - _ad9862_regs.tx_digital_pd = (enb)? 0 : 1; +void usrp1_codec_ctrl_impl::enable_tx_digital(bool enb) +{ + _ad9862_regs.tx_digital_pd = (enb) ? 0 : 1; this->send_reg(8); } @@ -404,7 +411,8 @@ void usrp1_codec_ctrl_impl::enable_tx_digital(bool enb){ * Disable this for AC-coupled daughterboards (TVRX) * By default it is initialized TRUE. **********************************************************************/ -void usrp1_codec_ctrl_impl::bypass_adc_buffers(bool bypass) { +void usrp1_codec_ctrl_impl::bypass_adc_buffers(bool bypass) +{ _ad9862_regs.byp_buffer_a = bypass; _ad9862_regs.byp_buffer_b = bypass; this->send_reg(2); @@ -413,8 +421,7 @@ void usrp1_codec_ctrl_impl::bypass_adc_buffers(bool bypass) { /*********************************************************************** * Codec Control Make **********************************************************************/ -usrp1_codec_ctrl::sptr usrp1_codec_ctrl::make(spi_iface::sptr iface, - int spi_slave) +usrp1_codec_ctrl::sptr usrp1_codec_ctrl::make(spi_iface::sptr iface, int spi_slave) { return sptr(new usrp1_codec_ctrl_impl(iface, spi_slave)); } diff --git a/host/lib/usrp/usrp1/codec_ctrl.hpp b/host/lib/usrp/usrp1/codec_ctrl.hpp index c03947673..ab0924aa0 100644 --- a/host/lib/usrp/usrp1/codec_ctrl.hpp +++ b/host/lib/usrp/usrp1/codec_ctrl.hpp @@ -8,8 +8,8 @@ #ifndef INCLUDED_USRP1_CODEC_CTRL_HPP #define INCLUDED_USRP1_CODEC_CTRL_HPP -#include <uhd/types/serial.hpp> #include <uhd/types/ranges.hpp> +#include <uhd/types/serial.hpp> #include <uhd/utils/noncopyable.hpp> #include <memory> @@ -18,7 +18,8 @@ * - Init/power down codec. * - Read aux adc, write aux dac. */ -class usrp1_codec_ctrl : uhd::noncopyable{ +class usrp1_codec_ctrl : uhd::noncopyable +{ public: typedef std::shared_ptr<usrp1_codec_ctrl> sptr; @@ -35,7 +36,7 @@ public: static sptr make(uhd::spi_iface::sptr iface, int spi_slave); //! aux adc identifier constants - enum aux_adc_t{ + enum aux_adc_t { AUX_ADC_A2 = 0xA2, AUX_ADC_A1 = 0xA1, AUX_ADC_B2 = 0xB2, @@ -52,12 +53,7 @@ public: virtual double read_aux_adc(aux_adc_t which) = 0; //! aux dac identifier constants - enum aux_dac_t{ - AUX_DAC_A = 0xA, - AUX_DAC_B = 0xB, - AUX_DAC_C = 0xC, - AUX_DAC_D = 0xD - }; + enum aux_dac_t { AUX_DAC_A = 0xA, AUX_DAC_B = 0xB, AUX_DAC_C = 0xC, AUX_DAC_D = 0xD }; /*! * Write an auxiliary dac. diff --git a/host/lib/usrp/usrp1/dboard_iface.cpp b/host/lib/usrp/usrp1/dboard_iface.cpp index 2f295b22b..8ad7a5466 100644 --- a/host/lib/usrp/usrp1/dboard_iface.cpp +++ b/host/lib/usrp/usrp1/dboard_iface.cpp @@ -5,33 +5,33 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include "codec_ctrl.hpp" #include "usrp1_iface.hpp" #include "usrp1_impl.hpp" -#include "codec_ctrl.hpp" -#include <uhd/usrp/dboard_iface.hpp> #include <uhd/types/dict.hpp> +#include <uhd/usrp/dboard_iface.hpp> #include <uhd/utils/assert_has.hpp> #include <boost/assign/list_of.hpp> #include <iostream> -#define FR_OE_0 5 -#define FR_OE_1 6 -#define FR_OE_2 7 -#define FR_OE_3 8 +#define FR_OE_0 5 +#define FR_OE_1 6 +#define FR_OE_2 7 +#define FR_OE_3 8 -#define FR_ATR_MASK_0 20 +#define FR_ATR_MASK_0 20 #define FR_ATR_TXVAL_0 21 #define FR_ATR_RXVAL_0 22 -#define FR_ATR_MASK_1 23 +#define FR_ATR_MASK_1 23 #define FR_ATR_TXVAL_1 24 #define FR_ATR_RXVAL_1 25 -#define FR_ATR_MASK_2 26 +#define FR_ATR_MASK_2 26 #define FR_ATR_TXVAL_2 27 #define FR_ATR_RXVAL_2 28 -#define FR_ATR_MASK_3 29 +#define FR_ATR_MASK_3 29 #define FR_ATR_TXVAL_3 30 #define FR_ATR_RXVAL_3 31 @@ -41,14 +41,14 @@ // i/o registers for pins that go to daughterboards. // top 16 is a mask, low 16 is value -#define FR_IO_0 9 // slot 0 -#define FR_IO_1 10 -#define FR_IO_2 11 -#define FR_IO_3 12 -#define SPI_ENABLE_TX_A 0x10 // select d'board TX A -#define SPI_ENABLE_RX_A 0x20 // select d'board RX A -#define SPI_ENABLE_TX_B 0x40 // select d'board TX B -#define SPI_ENABLE_RX_B 0x80 // select d'board RX B +#define FR_IO_0 9 // slot 0 +#define FR_IO_1 10 +#define FR_IO_2 11 +#define FR_IO_3 12 +#define SPI_ENABLE_TX_A 0x10 // select d'board TX A +#define SPI_ENABLE_RX_A 0x20 // select d'board RX A +#define SPI_ENABLE_TX_B 0x40 // select d'board TX B +#define SPI_ENABLE_RX_B 0x80 // select d'board RX B using namespace uhd; @@ -58,27 +58,27 @@ using namespace boost::assign; static const dboard_id_t tvrx_id(0x0040); -class usrp1_dboard_iface : public dboard_iface { +class usrp1_dboard_iface : public dboard_iface +{ public: - usrp1_dboard_iface(usrp1_iface::sptr iface, - usrp1_codec_ctrl::sptr codec, - usrp1_impl::dboard_slot_t dboard_slot, - const double &master_clock_rate, - const dboard_id_t &rx_dboard_id - ): - _dboard_slot(dboard_slot), - _master_clock_rate(master_clock_rate), - _rx_dboard_id(rx_dboard_id) + usrp1_codec_ctrl::sptr codec, + usrp1_impl::dboard_slot_t dboard_slot, + const double& master_clock_rate, + const dboard_id_t& rx_dboard_id) + : _dboard_slot(dboard_slot) + , _master_clock_rate(master_clock_rate) + , _rx_dboard_id(rx_dboard_id) { _iface = iface; _codec = codec; _dbsrx_classic_div = 1; - //yes this is evil but it's necessary for TVRX to work on USRP1 - if(_rx_dboard_id == tvrx_id) _codec->bypass_adc_buffers(false); - //else _codec->bypass_adc_buffers(false); //don't think this is necessary + // yes this is evil but it's necessary for TVRX to work on USRP1 + if (_rx_dboard_id == tvrx_id) + _codec->bypass_adc_buffers(false); + // else _codec->bypass_adc_buffers(false); //don't think this is necessary } ~usrp1_dboard_iface() @@ -90,7 +90,7 @@ public: { special_props_t props; props.soft_clock_divider = true; - props.mangle_i2c_addrs = (_dboard_slot == usrp1_impl::DBOARD_SLOT_B); + props.mangle_i2c_addrs = (_dboard_slot == usrp1_impl::DBOARD_SLOT_B); return props; } @@ -99,7 +99,8 @@ public: void set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_pin_ctrl(unit_t unit); - void set_atr_reg(unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask = 0xffffffff); + void set_atr_reg( + unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_atr_reg(unit_t unit, atr_reg_t reg); void set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_gpio_ddr(unit_t unit); @@ -115,49 +116,45 @@ public: void set_command_time(const uhd::time_spec_t& t); uhd::time_spec_t get_command_time(void); - void write_i2c(uint16_t, const byte_vector_t &); + void write_i2c(uint16_t, const byte_vector_t&); byte_vector_t read_i2c(uint16_t, size_t); - void write_spi(unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits); + void write_spi( + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits); - uint32_t read_write_spi(unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits); + uint32_t read_write_spi( + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits); void set_clock_rate(unit_t, double); std::vector<double> get_clock_rates(unit_t); double get_clock_rate(unit_t); void set_clock_enabled(unit_t, bool); double get_codec_rate(unit_t); - void set_fe_connection(unit_t unit, const std::string&, const fe_connection_t& fe_conn); + void set_fe_connection( + unit_t unit, const std::string&, const fe_connection_t& fe_conn); private: usrp1_iface::sptr _iface; usrp1_codec_ctrl::sptr _codec; unsigned _dbsrx_classic_div; const usrp1_impl::dboard_slot_t _dboard_slot; - const double &_master_clock_rate; + const double& _master_clock_rate; const dboard_id_t _rx_dboard_id; uhd::dict<unit_t, uint16_t> _pin_ctrl, _gpio_out, _gpio_ddr; - uhd::dict<unit_t, uhd::dict<atr_reg_t, uint16_t> > _atr_regs; + uhd::dict<unit_t, uhd::dict<atr_reg_t, uint16_t>> _atr_regs; }; /*********************************************************************** * Make Function **********************************************************************/ dboard_iface::sptr usrp1_impl::make_dboard_iface(usrp1_iface::sptr iface, - usrp1_codec_ctrl::sptr codec, - usrp1_impl::dboard_slot_t dboard_slot, - const double &master_clock_rate, - const dboard_id_t &rx_dboard_id -){ + usrp1_codec_ctrl::sptr codec, + usrp1_impl::dboard_slot_t dboard_slot, + const double& master_clock_rate, + const dboard_id_t& rx_dboard_id) +{ return dboard_iface::sptr(new usrp1_dboard_iface( - iface, codec, dboard_slot, master_clock_rate, rx_dboard_id - )); + iface, codec, dboard_slot, master_clock_rate, rx_dboard_id)); } /*********************************************************************** @@ -175,16 +172,16 @@ void usrp1_dboard_iface::set_clock_rate(unit_t unit, double rate) { assert_has(this->get_clock_rates(unit), rate, "dboard clock rate"); - if (unit == UNIT_RX && _rx_dboard_id == dbsrx_classic_id){ - _dbsrx_classic_div = size_t(_master_clock_rate/rate); - switch(_dboard_slot){ - case usrp1_impl::DBOARD_SLOT_A: - _iface->poke32(FR_RX_A_REFCLK, (_dbsrx_classic_div & 0x7f) | 0x80); - break; + if (unit == UNIT_RX && _rx_dboard_id == dbsrx_classic_id) { + _dbsrx_classic_div = size_t(_master_clock_rate / rate); + switch (_dboard_slot) { + case usrp1_impl::DBOARD_SLOT_A: + _iface->poke32(FR_RX_A_REFCLK, (_dbsrx_classic_div & 0x7f) | 0x80); + break; - case usrp1_impl::DBOARD_SLOT_B: - _iface->poke32(FR_RX_B_REFCLK, (_dbsrx_classic_div & 0x7f) | 0x80); - break; + case usrp1_impl::DBOARD_SLOT_B: + _iface->poke32(FR_RX_B_REFCLK, (_dbsrx_classic_div & 0x7f) | 0x80); + break; } } } @@ -192,11 +189,10 @@ void usrp1_dboard_iface::set_clock_rate(unit_t unit, double rate) std::vector<double> usrp1_dboard_iface::get_clock_rates(unit_t unit) { std::vector<double> rates; - if (unit == UNIT_RX && _rx_dboard_id == dbsrx_classic_id){ + if (unit == UNIT_RX && _rx_dboard_id == dbsrx_classic_id) { for (size_t div = 1; div <= 127; div++) rates.push_back(_master_clock_rate / div); - } - else{ + } else { rates.push_back(_master_clock_rate); } return rates; @@ -204,18 +200,19 @@ std::vector<double> usrp1_dboard_iface::get_clock_rates(unit_t unit) double usrp1_dboard_iface::get_clock_rate(unit_t unit) { - if (unit == UNIT_RX && _rx_dboard_id == dbsrx_classic_id){ - return _master_clock_rate/_dbsrx_classic_div; + if (unit == UNIT_RX && _rx_dboard_id == dbsrx_classic_id) { + return _master_clock_rate / _dbsrx_classic_div; } return _master_clock_rate; } void usrp1_dboard_iface::set_clock_enabled(unit_t, bool) { - //TODO we can only enable for special case anyway... + // TODO we can only enable for special case anyway... } -double usrp1_dboard_iface::get_codec_rate(unit_t){ +double usrp1_dboard_iface::get_codec_rate(unit_t) +{ return _master_clock_rate; } @@ -223,40 +220,60 @@ double usrp1_dboard_iface::get_codec_rate(unit_t){ * GPIO **********************************************************************/ template <typename T> -static T shadow_it(T &shadow, const T &value, const T &mask){ +static T shadow_it(T& shadow, const T& value, const T& mask) +{ shadow = (shadow & ~mask) | (value & mask); return shadow; } -void usrp1_dboard_iface::set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask){ - _set_pin_ctrl(unit, shadow_it(_pin_ctrl[unit], static_cast<uint16_t>(value), static_cast<uint16_t>(mask))); +void usrp1_dboard_iface::set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask) +{ + _set_pin_ctrl(unit, + shadow_it( + _pin_ctrl[unit], static_cast<uint16_t>(value), static_cast<uint16_t>(mask))); } -uint32_t usrp1_dboard_iface::get_pin_ctrl(unit_t unit){ +uint32_t usrp1_dboard_iface::get_pin_ctrl(unit_t unit) +{ return _pin_ctrl[unit]; } -void usrp1_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask){ - _set_atr_reg(unit, reg, shadow_it(_atr_regs[unit][reg], static_cast<uint16_t>(value), static_cast<uint16_t>(mask))); +void usrp1_dboard_iface::set_atr_reg( + unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask) +{ + _set_atr_reg(unit, + reg, + shadow_it(_atr_regs[unit][reg], + static_cast<uint16_t>(value), + static_cast<uint16_t>(mask))); } -uint32_t usrp1_dboard_iface::get_atr_reg(unit_t unit, atr_reg_t reg){ +uint32_t usrp1_dboard_iface::get_atr_reg(unit_t unit, atr_reg_t reg) +{ return _atr_regs[unit][reg]; } -void usrp1_dboard_iface::set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask){ - _set_gpio_ddr(unit, shadow_it(_gpio_ddr[unit], static_cast<uint16_t>(value), static_cast<uint16_t>(mask))); +void usrp1_dboard_iface::set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask) +{ + _set_gpio_ddr(unit, + shadow_it( + _gpio_ddr[unit], static_cast<uint16_t>(value), static_cast<uint16_t>(mask))); } -uint32_t usrp1_dboard_iface::get_gpio_ddr(unit_t unit){ +uint32_t usrp1_dboard_iface::get_gpio_ddr(unit_t unit) +{ return _gpio_ddr[unit]; } -void usrp1_dboard_iface::set_gpio_out(unit_t unit, uint32_t value, uint32_t mask){ - _set_gpio_out(unit, shadow_it(_gpio_out[unit], static_cast<uint16_t>(value), static_cast<uint16_t>(mask))); +void usrp1_dboard_iface::set_gpio_out(unit_t unit, uint32_t value, uint32_t mask) +{ + _set_gpio_out(unit, + shadow_it( + _gpio_out[unit], static_cast<uint16_t>(value), static_cast<uint16_t>(mask))); } -uint32_t usrp1_dboard_iface::get_gpio_out(unit_t unit){ +uint32_t usrp1_dboard_iface::get_gpio_out(unit_t unit) +{ return _gpio_out[unit]; } @@ -271,110 +288,115 @@ uint32_t usrp1_dboard_iface::read_gpio(unit_t unit) else UHD_THROW_INVALID_CODE_PATH(); - switch(unit) { - case UNIT_RX: - return (uint32_t)((out_value >> 16) & 0x0000ffff); - case UNIT_TX: - return (uint32_t)((out_value >> 0) & 0x0000ffff); - default: UHD_THROW_INVALID_CODE_PATH(); + switch (unit) { + case UNIT_RX: + return (uint32_t)((out_value >> 16) & 0x0000ffff); + case UNIT_TX: + return (uint32_t)((out_value >> 0) & 0x0000ffff); + default: + UHD_THROW_INVALID_CODE_PATH(); } UHD_ASSERT_THROW(false); } void usrp1_dboard_iface::_set_pin_ctrl(unit_t unit, uint16_t value) { - switch(unit) { - case UNIT_RX: - if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) - _iface->poke32(FR_ATR_MASK_1, value); - else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) - _iface->poke32(FR_ATR_MASK_3, value); - break; - case UNIT_TX: - if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) - _iface->poke32(FR_ATR_MASK_0, value); - else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) - _iface->poke32(FR_ATR_MASK_2, value); - break; - default: UHD_THROW_INVALID_CODE_PATH(); + switch (unit) { + case UNIT_RX: + if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) + _iface->poke32(FR_ATR_MASK_1, value); + else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) + _iface->poke32(FR_ATR_MASK_3, value); + break; + case UNIT_TX: + if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) + _iface->poke32(FR_ATR_MASK_0, value); + else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) + _iface->poke32(FR_ATR_MASK_2, value); + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } void usrp1_dboard_iface::_set_gpio_ddr(unit_t unit, uint16_t value) { - switch(unit) { - case UNIT_RX: - if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) - _iface->poke32(FR_OE_1, 0xffff0000 | value); - else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) - _iface->poke32(FR_OE_3, 0xffff0000 | value); - break; - case UNIT_TX: - if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) - _iface->poke32(FR_OE_0, 0xffff0000 | value); - else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) - _iface->poke32(FR_OE_2, 0xffff0000 | value); - break; - default: UHD_THROW_INVALID_CODE_PATH(); - } -} - -void usrp1_dboard_iface::_set_gpio_out(unit_t unit, uint16_t value) -{ - switch(unit) { - case UNIT_RX: - if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) - _iface->poke32(FR_IO_1, 0xffff0000 | value); - else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) - _iface->poke32(FR_IO_3, 0xffff0000 | value); - break; - case UNIT_TX: - if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) - _iface->poke32(FR_IO_0, 0xffff0000 | value); - else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) - _iface->poke32(FR_IO_2, 0xffff0000 | value); - break; - default: UHD_THROW_INVALID_CODE_PATH(); - } -} - -void usrp1_dboard_iface::_set_atr_reg(unit_t unit, - atr_reg_t atr, uint16_t value) -{ - // Ignore unsupported states - if ((atr == ATR_REG_IDLE) || (atr == ATR_REG_TX_ONLY)) - return; - if(atr == ATR_REG_RX_ONLY) { - switch(unit) { + switch (unit) { case UNIT_RX: if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) - _iface->poke32(FR_ATR_RXVAL_1, value); + _iface->poke32(FR_OE_1, 0xffff0000 | value); else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) - _iface->poke32(FR_ATR_RXVAL_3, value); + _iface->poke32(FR_OE_3, 0xffff0000 | value); break; case UNIT_TX: if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) - _iface->poke32(FR_ATR_RXVAL_0, value); + _iface->poke32(FR_OE_0, 0xffff0000 | value); else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) - _iface->poke32(FR_ATR_RXVAL_2, value); + _iface->poke32(FR_OE_2, 0xffff0000 | value); break; - default: UHD_THROW_INVALID_CODE_PATH(); - } - } else if (atr == ATR_REG_FULL_DUPLEX) { - switch(unit) { + default: + UHD_THROW_INVALID_CODE_PATH(); + } +} + +void usrp1_dboard_iface::_set_gpio_out(unit_t unit, uint16_t value) +{ + switch (unit) { case UNIT_RX: if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) - _iface->poke32(FR_ATR_TXVAL_1, value); + _iface->poke32(FR_IO_1, 0xffff0000 | value); else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) - _iface->poke32(FR_ATR_TXVAL_3, value); + _iface->poke32(FR_IO_3, 0xffff0000 | value); break; case UNIT_TX: if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) - _iface->poke32(FR_ATR_TXVAL_0, value); + _iface->poke32(FR_IO_0, 0xffff0000 | value); else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) - _iface->poke32(FR_ATR_TXVAL_2, value); + _iface->poke32(FR_IO_2, 0xffff0000 | value); break; - default: UHD_THROW_INVALID_CODE_PATH(); + default: + UHD_THROW_INVALID_CODE_PATH(); + } +} + +void usrp1_dboard_iface::_set_atr_reg(unit_t unit, atr_reg_t atr, uint16_t value) +{ + // Ignore unsupported states + if ((atr == ATR_REG_IDLE) || (atr == ATR_REG_TX_ONLY)) + return; + if (atr == ATR_REG_RX_ONLY) { + switch (unit) { + case UNIT_RX: + if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) + _iface->poke32(FR_ATR_RXVAL_1, value); + else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) + _iface->poke32(FR_ATR_RXVAL_3, value); + break; + case UNIT_TX: + if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) + _iface->poke32(FR_ATR_RXVAL_0, value); + else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) + _iface->poke32(FR_ATR_RXVAL_2, value); + break; + default: + UHD_THROW_INVALID_CODE_PATH(); + } + } else if (atr == ATR_REG_FULL_DUPLEX) { + switch (unit) { + case UNIT_RX: + if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) + _iface->poke32(FR_ATR_TXVAL_1, value); + else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) + _iface->poke32(FR_ATR_TXVAL_3, value); + break; + case UNIT_TX: + if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A) + _iface->poke32(FR_ATR_TXVAL_0, value); + else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B) + _iface->poke32(FR_ATR_TXVAL_2, value); + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } } @@ -387,59 +409,52 @@ void usrp1_dboard_iface::_set_atr_reg(unit_t unit, * \param slot the side (A or B) the dboard is attached * \return the slave device number */ -static uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit, - usrp1_impl::dboard_slot_t slot) +static uint32_t unit_to_otw_spi_dev( + dboard_iface::unit_t unit, usrp1_impl::dboard_slot_t slot) { - switch(unit) { - case dboard_iface::UNIT_TX: - if (slot == usrp1_impl::DBOARD_SLOT_A) - return SPI_ENABLE_TX_A; - else if (slot == usrp1_impl::DBOARD_SLOT_B) - return SPI_ENABLE_TX_B; - else - break; - case dboard_iface::UNIT_RX: - if (slot == usrp1_impl::DBOARD_SLOT_A) - return SPI_ENABLE_RX_A; - else if (slot == usrp1_impl::DBOARD_SLOT_B) - return SPI_ENABLE_RX_B; - else + switch (unit) { + case dboard_iface::UNIT_TX: + if (slot == usrp1_impl::DBOARD_SLOT_A) + return SPI_ENABLE_TX_A; + else if (slot == usrp1_impl::DBOARD_SLOT_B) + return SPI_ENABLE_TX_B; + else + break; + case dboard_iface::UNIT_RX: + if (slot == usrp1_impl::DBOARD_SLOT_A) + return SPI_ENABLE_RX_A; + else if (slot == usrp1_impl::DBOARD_SLOT_B) + return SPI_ENABLE_RX_B; + else + break; + default: break; - default: - break; } UHD_THROW_INVALID_CODE_PATH(); } -void usrp1_dboard_iface::write_spi(unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits) +void usrp1_dboard_iface::write_spi( + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits) { - _iface->write_spi(unit_to_otw_spi_dev(unit, _dboard_slot), - config, data, num_bits); + _iface->write_spi(unit_to_otw_spi_dev(unit, _dboard_slot), config, data, num_bits); } -uint32_t usrp1_dboard_iface::read_write_spi(unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits) +uint32_t usrp1_dboard_iface::read_write_spi( + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits) { - return _iface->read_spi(unit_to_otw_spi_dev(unit, _dboard_slot), - config, data, num_bits); + return _iface->read_spi( + unit_to_otw_spi_dev(unit, _dboard_slot), config, data, num_bits); } /*********************************************************************** * I2C **********************************************************************/ -void usrp1_dboard_iface::write_i2c(uint16_t addr, - const byte_vector_t &bytes) +void usrp1_dboard_iface::write_i2c(uint16_t addr, const byte_vector_t& bytes) { return _iface->write_i2c(addr, bytes); } -byte_vector_t usrp1_dboard_iface::read_i2c(uint16_t addr, - size_t num_bytes) +byte_vector_t usrp1_dboard_iface::read_i2c(uint16_t addr, size_t num_bytes) { return _iface->read_i2c(addr, num_bytes); } @@ -447,31 +462,26 @@ byte_vector_t usrp1_dboard_iface::read_i2c(uint16_t addr, /*********************************************************************** * Aux DAX/ADC **********************************************************************/ -void usrp1_dboard_iface::write_aux_dac(dboard_iface::unit_t, - aux_dac_t which, double value) +void usrp1_dboard_iface::write_aux_dac( + dboard_iface::unit_t, aux_dac_t which, double value) { - //same aux dacs for each unit - static const uhd::dict<aux_dac_t, usrp1_codec_ctrl::aux_dac_t> - which_to_aux_dac = map_list_of - (AUX_DAC_A, usrp1_codec_ctrl::AUX_DAC_A) - (AUX_DAC_B, usrp1_codec_ctrl::AUX_DAC_B) - (AUX_DAC_C, usrp1_codec_ctrl::AUX_DAC_C) - (AUX_DAC_D, usrp1_codec_ctrl::AUX_DAC_D); + // same aux dacs for each unit + static const uhd::dict<aux_dac_t, usrp1_codec_ctrl::aux_dac_t> which_to_aux_dac = + map_list_of(AUX_DAC_A, usrp1_codec_ctrl::AUX_DAC_A)(AUX_DAC_B, + usrp1_codec_ctrl::AUX_DAC_B)(AUX_DAC_C, usrp1_codec_ctrl::AUX_DAC_C)( + AUX_DAC_D, usrp1_codec_ctrl::AUX_DAC_D); _codec->write_aux_dac(which_to_aux_dac[which], value); } -double usrp1_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, - aux_adc_t which) +double usrp1_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, aux_adc_t which) { - static const - uhd::dict<unit_t, uhd::dict<aux_adc_t, usrp1_codec_ctrl::aux_adc_t> > - unit_to_which_to_aux_adc = map_list_of(UNIT_RX, map_list_of - (AUX_ADC_A, usrp1_codec_ctrl::AUX_ADC_A1) - (AUX_ADC_B, usrp1_codec_ctrl::AUX_ADC_B1)) - (UNIT_TX, map_list_of - (AUX_ADC_A, usrp1_codec_ctrl::AUX_ADC_A2) - (AUX_ADC_B, usrp1_codec_ctrl::AUX_ADC_B2)); + static const uhd::dict<unit_t, uhd::dict<aux_adc_t, usrp1_codec_ctrl::aux_adc_t>> + unit_to_which_to_aux_adc = map_list_of(UNIT_RX, + map_list_of(AUX_ADC_A, usrp1_codec_ctrl::AUX_ADC_A1)( + AUX_ADC_B, usrp1_codec_ctrl::AUX_ADC_B1))(UNIT_TX, + map_list_of(AUX_ADC_A, usrp1_codec_ctrl::AUX_ADC_A2)( + AUX_ADC_B, usrp1_codec_ctrl::AUX_ADC_B2)); return _codec->read_aux_adc(unit_to_which_to_aux_adc[unit][which]); } @@ -490,8 +500,9 @@ uhd::time_spec_t usrp1_dboard_iface::get_command_time() throw uhd::not_implemented_error("timed command support not implemented"); } -void usrp1_dboard_iface::set_fe_connection(unit_t, const std::string&, const fe_connection_t&) +void usrp1_dboard_iface::set_fe_connection( + unit_t, const std::string&, const fe_connection_t&) { - throw uhd::not_implemented_error("fe connection configuration support not implemented"); + throw uhd::not_implemented_error( + "fe connection configuration support not implemented"); } - diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp index 4eb1a5c50..4788c3d9e 100644 --- a/host/lib/usrp/usrp1/io_impl.cpp +++ b/host/lib/usrp/usrp1/io_impl.cpp @@ -28,23 +28,23 @@ #define bmFR_RX_FORMAT_SHIFT_SHIFT 0 #define bmFR_RX_FORMAT_WIDTH_SHIFT 4 -#define bmFR_TX_FORMAT_16_IQ 0 -#define bmFR_RX_FORMAT_WANT_Q (0x1 << 9) -#define FR_RX_FREQ_0 34 -#define FR_RX_FREQ_1 35 -#define FR_RX_FREQ_2 36 -#define FR_RX_FREQ_3 37 -#define FR_INTERP_RATE 32 -#define FR_DECIM_RATE 33 -#define FR_RX_MUX 38 -#define FR_TX_MUX 39 -#define FR_TX_FORMAT 48 -#define FR_RX_FORMAT 49 -#define FR_TX_SAMPLE_RATE_DIV 0 -#define FR_RX_SAMPLE_RATE_DIV 1 -#define GS_TX_UNDERRUN 0 -#define GS_RX_OVERRUN 1 -#define VRQ_GET_STATUS 0x80 +#define bmFR_TX_FORMAT_16_IQ 0 +#define bmFR_RX_FORMAT_WANT_Q (0x1 << 9) +#define FR_RX_FREQ_0 34 +#define FR_RX_FREQ_1 35 +#define FR_RX_FREQ_2 36 +#define FR_RX_FREQ_3 37 +#define FR_INTERP_RATE 32 +#define FR_DECIM_RATE 33 +#define FR_RX_MUX 38 +#define FR_TX_MUX 39 +#define FR_TX_FORMAT 48 +#define FR_RX_FORMAT 49 +#define FR_TX_SAMPLE_RATE_DIV 0 +#define FR_RX_SAMPLE_RATE_DIV 1 +#define GS_TX_UNDERRUN 0 +#define GS_RX_OVERRUN 1 +#define VRQ_GET_STATUS 0x80 using namespace uhd; using namespace uhd::usrp; @@ -55,18 +55,20 @@ static const size_t alignment_padding = 512; /*********************************************************************** * Helper struct to associate an offset with a buffer **********************************************************************/ -struct offset_send_buffer{ - offset_send_buffer(void):offset(0){ +struct offset_send_buffer +{ + offset_send_buffer(void) : offset(0) + { /* NOP */ } - offset_send_buffer(managed_send_buffer::sptr buff, size_t offset = 0): - buff(buff), offset(offset) + offset_send_buffer(managed_send_buffer::sptr buff, size_t offset = 0) + : buff(buff), offset(offset) { /* NOP */ } - //member variables + // member variables managed_send_buffer::sptr buff; size_t offset; /* in bytes */ }; @@ -74,29 +76,28 @@ struct offset_send_buffer{ /*********************************************************************** * Reusable managed send buffer to handle aligned commits **********************************************************************/ -class offset_managed_send_buffer : public managed_send_buffer{ +class offset_managed_send_buffer : public managed_send_buffer +{ public: - typedef std::function<void(offset_send_buffer&, offset_send_buffer&, size_t)> commit_cb_type; - offset_managed_send_buffer(const commit_cb_type &commit_cb): - _commit_cb(commit_cb) + typedef std::function<void(offset_send_buffer&, offset_send_buffer&, size_t)> + commit_cb_type; + offset_managed_send_buffer(const commit_cb_type& commit_cb) : _commit_cb(commit_cb) { /* NOP */ } - void release(void){ + void release(void) + { this->_commit_cb(_curr_buff, _next_buff, size()); } - sptr get_new( - offset_send_buffer &curr_buff, - offset_send_buffer &next_buff - ){ + sptr get_new(offset_send_buffer& curr_buff, offset_send_buffer& next_buff) + { _curr_buff = curr_buff; _next_buff = next_buff; return make(this, - _curr_buff.buff->cast<char *>() + _curr_buff.offset, - _curr_buff.buff->size() - _curr_buff.offset - ); + _curr_buff.buff->cast<char*>() + _curr_buff.offset, + _curr_buff.buff->size() - _curr_buff.offset); } private: @@ -107,66 +108,71 @@ private: /*********************************************************************** * BS VRT packer/unpacker functions (since samples don't have headers) **********************************************************************/ -static void usrp1_bs_vrt_packer( - uint32_t *, - vrt::if_packet_info_t &if_packet_info -){ +static void usrp1_bs_vrt_packer(uint32_t*, vrt::if_packet_info_t& if_packet_info) +{ if_packet_info.num_header_words32 = 0; if_packet_info.num_packet_words32 = if_packet_info.num_payload_words32; } -static void usrp1_bs_vrt_unpacker( - const uint32_t *, - vrt::if_packet_info_t &if_packet_info -){ - if_packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; +static void usrp1_bs_vrt_unpacker(const uint32_t*, vrt::if_packet_info_t& if_packet_info) +{ + if_packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; if_packet_info.num_payload_words32 = if_packet_info.num_packet_words32; - if_packet_info.num_payload_bytes = if_packet_info.num_packet_words32*sizeof(uint32_t); + if_packet_info.num_payload_bytes = + if_packet_info.num_packet_words32 * sizeof(uint32_t); if_packet_info.num_header_words32 = 0; - if_packet_info.packet_count = 0; - if_packet_info.sob = false; - if_packet_info.eob = false; - if_packet_info.has_sid = false; - if_packet_info.has_cid = false; - if_packet_info.has_tsi = false; - if_packet_info.has_tsf = false; - if_packet_info.has_tlr = false; + if_packet_info.packet_count = 0; + if_packet_info.sob = false; + if_packet_info.eob = false; + if_packet_info.has_sid = false; + if_packet_info.has_cid = false; + if_packet_info.has_tsi = false; + if_packet_info.has_tsf = false; + if_packet_info.has_tlr = false; } /*********************************************************************** * IO Implementation Details **********************************************************************/ -struct usrp1_impl::io_impl{ - io_impl(zero_copy_if::sptr data_transport): - data_transport(data_transport), - curr_buff(offset_send_buffer(data_transport->get_send_buff())), - omsb(std::bind(&usrp1_impl::io_impl::commit_send_buff, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)), - vandal_loop_exit(false) +struct usrp1_impl::io_impl +{ + io_impl(zero_copy_if::sptr data_transport) + : data_transport(data_transport) + , curr_buff(offset_send_buffer(data_transport->get_send_buff())) + , omsb(std::bind(&usrp1_impl::io_impl::commit_send_buff, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3)) + , vandal_loop_exit(false) { /* NOP */ } - ~io_impl(void){ + ~io_impl(void) + { vandal_loop_exit = true; UHD_SAFE_CALL(flush_send_buff();) } zero_copy_if::sptr data_transport; - //wrapper around the actual send buffer interface - //all of this to ensure only aligned lengths are committed - //NOTE: you must commit before getting a new buffer - //since the vrt packet handler obeys this, we are ok + // wrapper around the actual send buffer interface + // all of this to ensure only aligned lengths are committed + // NOTE: you must commit before getting a new buffer + // since the vrt packet handler obeys this, we are ok offset_send_buffer curr_buff; offset_managed_send_buffer omsb; void commit_send_buff(offset_send_buffer&, offset_send_buffer&, size_t); void flush_send_buff(void); - managed_send_buffer::sptr get_send_buff(double timeout){ - //try to get a new managed buffer with timeout + managed_send_buffer::sptr get_send_buff(double timeout) + { + // try to get a new managed buffer with timeout offset_send_buffer next_buff(data_transport->get_send_buff(timeout)); - if (not next_buff.buff.get()) return managed_send_buffer::sptr(); /* propagate timeout here */ + if (not next_buff.buff.get()) + return managed_send_buffer::sptr(); /* propagate timeout here */ - //make a new managed buffer with the offset buffs + // make a new managed buffer with the offset buffs return omsb.get_new(curr_buff, next_buff); } @@ -181,48 +187,46 @@ struct usrp1_impl::io_impl{ * Commit the current buffer at multiples of alignment. */ void usrp1_impl::io_impl::commit_send_buff( - offset_send_buffer &curr, - offset_send_buffer &next, - size_t num_bytes -){ - //total number of bytes now in the current buffer + offset_send_buffer& curr, offset_send_buffer& next, size_t num_bytes) +{ + // total number of bytes now in the current buffer size_t bytes_in_curr_buffer = curr.offset + num_bytes; - //calculate how many to commit and remainder + // calculate how many to commit and remainder size_t num_bytes_remaining = bytes_in_curr_buffer % alignment_padding; size_t num_bytes_to_commit = bytes_in_curr_buffer - num_bytes_remaining; - //copy the remainder into the next buffer - std::memcpy( - next.buff->cast<char *>() + next.offset, - curr.buff->cast<char *>() + num_bytes_to_commit, - num_bytes_remaining - ); + // copy the remainder into the next buffer + std::memcpy(next.buff->cast<char*>() + next.offset, + curr.buff->cast<char*>() + num_bytes_to_commit, + num_bytes_remaining); - //update the offset into the next buffer + // update the offset into the next buffer next.offset += num_bytes_remaining; - //commit the current buffer + // commit the current buffer curr.buff->commit(num_bytes_to_commit); - //store the next buffer for the next call + // store the next buffer for the next call curr_buff = next; } /*! * Flush the current buffer by padding out to alignment and committing. */ -void usrp1_impl::io_impl::flush_send_buff(void){ - //calculate the number of bytes to alignment - size_t bytes_to_pad = (-1*curr_buff.offset)%alignment_padding; +void usrp1_impl::io_impl::flush_send_buff(void) +{ + // calculate the number of bytes to alignment + size_t bytes_to_pad = (-1 * curr_buff.offset) % alignment_padding; - //send at least alignment_padding to guarantee zeros are sent - if (bytes_to_pad == 0) bytes_to_pad = alignment_padding; + // send at least alignment_padding to guarantee zeros are sent + if (bytes_to_pad == 0) + bytes_to_pad = alignment_padding; - //get the buffer, clear, and commit (really current buffer) + // get the buffer, clear, and commit (really current buffer) managed_send_buffer::sptr buff = this->get_send_buff(.1); - if (buff.get() != NULL){ - std::memset(buff->cast<void *>(), 0, bytes_to_pad); + if (buff.get() != NULL) { + std::memset(buff->cast<void*>(), 0, bytes_to_pad); buff->commit(bytes_to_pad); } } @@ -230,34 +234,36 @@ void usrp1_impl::io_impl::flush_send_buff(void){ /*********************************************************************** * Initialize internals within this file **********************************************************************/ -void usrp1_impl::io_init(void){ - +void usrp1_impl::io_init(void) +{ _io_impl = UHD_PIMPL_MAKE(io_impl, (_data_transport)); - //init as disabled, then call the real function (uses restore) + // init as disabled, then call the real function (uses restore) this->enable_rx(false); this->enable_tx(false); rx_stream_on_off(false); tx_stream_on_off(false); _io_impl->flush_send_buff(); - //create a new vandal thread to poll xerflow conditions + // create a new vandal thread to poll xerflow conditions _io_impl->vandal_task = task::make(std::bind( - &usrp1_impl::vandal_conquest_loop, this, std::ref(_io_impl->vandal_loop_exit) - )); + &usrp1_impl::vandal_conquest_loop, this, std::ref(_io_impl->vandal_loop_exit))); } -void usrp1_impl::rx_stream_on_off(bool enb){ +void usrp1_impl::rx_stream_on_off(bool enb) +{ this->restore_rx(enb); - //drain any junk in the receive transport after stop streaming command - while(not enb and _data_transport->get_recv_buff().get() != NULL){ + // drain any junk in the receive transport after stop streaming command + while (not enb and _data_transport->get_recv_buff().get() != NULL) { /* NOP */ } } -void usrp1_impl::tx_stream_on_off(bool enb){ +void usrp1_impl::tx_stream_on_off(bool enb) +{ _io_impl->last_send_time = boost::get_system_time(); - if (_tx_enabled and not enb) _io_impl->flush_send_buff(); + if (_tx_enabled and not enb) + _io_impl->flush_send_buff(); this->restore_tx(enb); } @@ -267,91 +273,97 @@ void usrp1_impl::tx_stream_on_off(bool enb){ * On an overflow, interleave an inline message into recv and print. * This procedure creates "soft" inline and async user messages. */ -void usrp1_impl::vandal_conquest_loop(std::atomic<bool> &exit_loop){ - - //initialize the async metadata +void usrp1_impl::vandal_conquest_loop(std::atomic<bool>& exit_loop) +{ + // initialize the async metadata async_metadata_t async_metadata; - async_metadata.channel = 0; + async_metadata.channel = 0; async_metadata.has_time_spec = true; - async_metadata.event_code = async_metadata_t::EVENT_CODE_UNDERFLOW; + async_metadata.event_code = async_metadata_t::EVENT_CODE_UNDERFLOW; - //initialize the inline metadata + // initialize the inline metadata rx_metadata_t inline_metadata; inline_metadata.has_time_spec = true; - inline_metadata.error_code = rx_metadata_t::ERROR_CODE_OVERFLOW; - - //start the polling loop... - try{ while (not exit_loop){ - uint8_t underflow = 0, overflow = 0; - - //shutoff transmit if it has been too long since send() was called - if (_tx_enabled and (boost::get_system_time() - _io_impl->last_send_time) > boost::posix_time::milliseconds(100)){ - this->tx_stream_on_off(false); - } - - //always poll regardless of enabled so we can clear the conditions - _fx2_ctrl->usrp_control_read( - VRQ_GET_STATUS, 0, GS_TX_UNDERRUN, &underflow, sizeof(underflow) - ); - _fx2_ctrl->usrp_control_read( - VRQ_GET_STATUS, 0, GS_RX_OVERRUN, &overflow, sizeof(overflow) - ); - - //handle message generation for xerflow conditions - if (_tx_enabled and underflow){ - async_metadata.time_spec = _soft_time_ctrl->get_time(); - _soft_time_ctrl->get_async_queue().push_with_pop_on_full(async_metadata); - UHD_LOG_FASTPATH("U") - } - if (_rx_enabled and overflow){ - inline_metadata.time_spec = _soft_time_ctrl->get_time(); - _soft_time_ctrl->get_inline_queue().push_with_pop_on_full(inline_metadata); - UHD_LOG_FASTPATH("O") + inline_metadata.error_code = rx_metadata_t::ERROR_CODE_OVERFLOW; + + // start the polling loop... + try { + while (not exit_loop) { + uint8_t underflow = 0, overflow = 0; + + // shutoff transmit if it has been too long since send() was called + if (_tx_enabled + and (boost::get_system_time() - _io_impl->last_send_time) + > boost::posix_time::milliseconds(100)) { + this->tx_stream_on_off(false); + } + + // always poll regardless of enabled so we can clear the conditions + _fx2_ctrl->usrp_control_read( + VRQ_GET_STATUS, 0, GS_TX_UNDERRUN, &underflow, sizeof(underflow)); + _fx2_ctrl->usrp_control_read( + VRQ_GET_STATUS, 0, GS_RX_OVERRUN, &overflow, sizeof(overflow)); + + // handle message generation for xerflow conditions + if (_tx_enabled and underflow) { + async_metadata.time_spec = _soft_time_ctrl->get_time(); + _soft_time_ctrl->get_async_queue().push_with_pop_on_full(async_metadata); + UHD_LOG_FASTPATH("U") + } + if (_rx_enabled and overflow) { + inline_metadata.time_spec = _soft_time_ctrl->get_time(); + _soft_time_ctrl->get_inline_queue().push_with_pop_on_full( + inline_metadata); + UHD_LOG_FASTPATH("O") + } + + std::this_thread::sleep_for(std::chrono::milliseconds(50)); } - - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - }} - catch(const std::exception &e){ - UHD_LOGGER_ERROR("USRP1") << "The vandal caught an unexpected exception " << e.what() ; + } catch (const std::exception& e) { + UHD_LOGGER_ERROR("USRP1") + << "The vandal caught an unexpected exception " << e.what(); } } /*********************************************************************** * RX streamer wrapper that talks to soft time control **********************************************************************/ -class usrp1_recv_packet_streamer : public sph::recv_packet_handler, public rx_streamer{ +class usrp1_recv_packet_streamer : public sph::recv_packet_handler, public rx_streamer +{ public: - usrp1_recv_packet_streamer(const size_t max_num_samps, soft_time_ctrl::sptr stc){ + usrp1_recv_packet_streamer(const size_t max_num_samps, soft_time_ctrl::sptr stc) + { _max_num_samps = max_num_samps; - _stc = stc; + _stc = stc; } - size_t get_num_channels(void) const{ + size_t get_num_channels(void) const + { return this->size(); } - size_t get_max_num_samps(void) const{ + size_t get_max_num_samps(void) const + { return _max_num_samps; } - size_t recv( - const rx_streamer::buffs_type &buffs, + size_t recv(const rx_streamer::buffs_type& buffs, const size_t nsamps_per_buff, - uhd::rx_metadata_t &metadata, + uhd::rx_metadata_t& metadata, const double timeout, - const bool one_packet - ){ - //interleave a "soft" inline message into the receive stream: - if (_stc->get_inline_queue().pop_with_haste(metadata)) return 0; + const bool one_packet) + { + // interleave a "soft" inline message into the receive stream: + if (_stc->get_inline_queue().pop_with_haste(metadata)) + return 0; size_t num_samps_recvd = sph::recv_packet_handler::recv( - buffs, nsamps_per_buff, metadata, timeout, one_packet - ); + buffs, nsamps_per_buff, metadata, timeout, one_packet); return _stc->recv_post(metadata, num_samps_recvd); } - void issue_stream_cmd(const stream_cmd_t &stream_cmd) + void issue_stream_cmd(const stream_cmd_t& stream_cmd) { _stc->issue_stream_cmd(stream_cmd); } @@ -364,45 +376,49 @@ private: /*********************************************************************** * TX streamer wrapper that talks to soft time control **********************************************************************/ -class usrp1_send_packet_streamer : public sph::send_packet_handler, public tx_streamer{ +class usrp1_send_packet_streamer : public sph::send_packet_handler, public tx_streamer +{ public: - usrp1_send_packet_streamer(const size_t max_num_samps, soft_time_ctrl::sptr stc, std::function<void(bool)> tx_enb_fcn){ + usrp1_send_packet_streamer(const size_t max_num_samps, + soft_time_ctrl::sptr stc, + std::function<void(bool)> tx_enb_fcn) + { _max_num_samps = max_num_samps; this->set_max_samples_per_packet(_max_num_samps); - _stc = stc; + _stc = stc; _tx_enb_fcn = tx_enb_fcn; } - size_t get_num_channels(void) const{ + size_t get_num_channels(void) const + { return this->size(); } - size_t get_max_num_samps(void) const{ + size_t get_max_num_samps(void) const + { return _max_num_samps; } - size_t send( - const tx_streamer::buffs_type &buffs, + size_t send(const tx_streamer::buffs_type& buffs, const size_t nsamps_per_buff, - const uhd::tx_metadata_t &metadata, - const double timeout_ - ){ - double timeout = timeout_; //rw copy + const uhd::tx_metadata_t& metadata, + const double timeout_) + { + double timeout = timeout_; // rw copy _stc->send_pre(metadata, timeout); - _tx_enb_fcn(true); //always enable (it will do the right thing) - size_t num_samps_sent = sph::send_packet_handler::send( - buffs, nsamps_per_buff, metadata, timeout - ); + _tx_enb_fcn(true); // always enable (it will do the right thing) + size_t num_samps_sent = + sph::send_packet_handler::send(buffs, nsamps_per_buff, metadata, timeout); - //handle eob flag (commit the buffer, //disable the DACs) - //check num samps sent to avoid flush on incomplete/timeout - if (metadata.end_of_burst and num_samps_sent == nsamps_per_buff){ + // handle eob flag (commit the buffer, //disable the DACs) + // check num samps sent to avoid flush on incomplete/timeout + if (metadata.end_of_burst and num_samps_sent == nsamps_per_buff) { async_metadata_t metadata; - metadata.channel = 0; + metadata.channel = 0; metadata.has_time_spec = true; - metadata.time_spec = _stc->get_time(); - metadata.event_code = async_metadata_t::EVENT_CODE_BURST_ACK; + metadata.time_spec = _stc->get_time(); + metadata.event_code = async_metadata_t::EVENT_CODE_BURST_ACK; _stc->get_async_queue().push_with_pop_on_full(metadata); _tx_enb_fcn(false); } @@ -410,9 +426,8 @@ public: return num_samps_sent; } - bool recv_async_msg( - async_metadata_t &async_metadata, double timeout = 0.1 - ){ + bool recv_async_msg(async_metadata_t& async_metadata, double timeout = 0.1) + { return _stc->get_async_queue().pop_with_timed_wait(async_metadata, timeout); } @@ -425,19 +440,22 @@ private: /*********************************************************************** * Properties callback methods below **********************************************************************/ -void usrp1_impl::update_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){ - - //sanity checking +void usrp1_impl::update_rx_subdev_spec(const uhd::usrp::subdev_spec_t& spec) +{ + // sanity checking validate_subdev_spec(_tree, spec, "rx"); - _rx_subdev_spec = spec; //shadow + _rx_subdev_spec = spec; // shadow - //set the mux and set the number of rx channels + // set the mux and set the number of rx channels std::vector<mapping_pair_t> mapping; - for(const subdev_spec_pair_t &pair: spec){ - const std::string conn = _tree->access<std::string>(str(boost::format( - "/mboards/0/dboards/%s/rx_frontends/%s/connection" - ) % pair.db_name % pair.sd_name)).get(); + for (const subdev_spec_pair_t& pair : spec) { + const std::string conn = + _tree + ->access<std::string>( + str(boost::format("/mboards/0/dboards/%s/rx_frontends/%s/connection") + % pair.db_name % pair.sd_name)) + .get(); mapping.push_back(std::make_pair(pair.db_name, conn)); } bool s = this->disable_rx(); @@ -445,19 +463,22 @@ void usrp1_impl::update_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){ this->restore_rx(s); } -void usrp1_impl::update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){ - - //sanity checking +void usrp1_impl::update_tx_subdev_spec(const uhd::usrp::subdev_spec_t& spec) +{ + // sanity checking validate_subdev_spec(_tree, spec, "tx"); - _tx_subdev_spec = spec; //shadow + _tx_subdev_spec = spec; // shadow - //set the mux and set the number of tx channels + // set the mux and set the number of tx channels std::vector<mapping_pair_t> mapping; - for(const subdev_spec_pair_t &pair: spec){ - const std::string conn = _tree->access<std::string>(str(boost::format( - "/mboards/0/dboards/%s/tx_frontends/%s/connection" - ) % pair.db_name % pair.sd_name)).get(); + for (const subdev_spec_pair_t& pair : spec) { + const std::string conn = + _tree + ->access<std::string>( + str(boost::format("/mboards/0/dboards/%s/tx_frontends/%s/connection") + % pair.db_name % pair.sd_name)) + .get(); mapping.push_back(std::make_pair(pair.db_name, conn)); } bool s = this->disable_tx(); @@ -465,52 +486,58 @@ void usrp1_impl::update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){ this->restore_tx(s); } -void usrp1_impl::update_tick_rate(const double rate){ - //updating this variable should: - //update dboard iface -> it has a reference - //update dsp freq bounds -> publisher +void usrp1_impl::update_tick_rate(const double rate) +{ + // updating this variable should: + // update dboard iface -> it has a reference + // update dsp freq bounds -> publisher _master_clock_rate = rate; } -uhd::meta_range_t usrp1_impl::get_rx_dsp_host_rates(void){ +uhd::meta_range_t usrp1_impl::get_rx_dsp_host_rates(void) +{ meta_range_t range; - const size_t div = this->has_rx_halfband()? 2 : 1; - for (int rate = 256; rate >= 4; rate -= div){ - range.push_back(range_t(_master_clock_rate/rate)); + const size_t div = this->has_rx_halfband() ? 2 : 1; + for (int rate = 256; rate >= 4; rate -= div) { + range.push_back(range_t(_master_clock_rate / rate)); } return range; } -uhd::meta_range_t usrp1_impl::get_tx_dsp_host_rates(void){ +uhd::meta_range_t usrp1_impl::get_tx_dsp_host_rates(void) +{ meta_range_t range; - const size_t div = this->has_tx_halfband()? 2 : 1; - for (int rate = 256; rate >= 8; rate -= div){ - range.push_back(range_t(_master_clock_rate/rate)); + const size_t div = this->has_tx_halfband() ? 2 : 1; + for (int rate = 256; rate >= 8; rate -= div) { + range.push_back(range_t(_master_clock_rate / rate)); } return range; } -double usrp1_impl::update_rx_samp_rate(size_t dspno, const double samp_rate){ - - const size_t div = this->has_rx_halfband()? 2 : 1; - const size_t rate = boost::math::iround(_master_clock_rate/this->get_rx_dsp_host_rates().clip(samp_rate, true)); - - if (rate < 8 and this->has_rx_halfband()) UHD_LOGGER_WARNING("USRP1") << - "USRP1 cannot achieve decimations below 8 when the half-band filter is present.\n" - "The usrp1_fpga_4rx.rbf file is a special FPGA image without RX half-band filters.\n" - "To load this image, set the device address key/value pair: fpga=usrp1_fpga_4rx.rbf\n" - ; - - if (dspno == 0){ //only care if dsp0 is set since its homogeneous +double usrp1_impl::update_rx_samp_rate(size_t dspno, const double samp_rate) +{ + const size_t div = this->has_rx_halfband() ? 2 : 1; + const size_t rate = boost::math::iround( + _master_clock_rate / this->get_rx_dsp_host_rates().clip(samp_rate, true)); + + if (rate < 8 and this->has_rx_halfband()) + UHD_LOGGER_WARNING("USRP1") << "USRP1 cannot achieve decimations below 8 when " + "the half-band filter is present.\n" + "The usrp1_fpga_4rx.rbf file is a special FPGA " + "image without RX half-band filters.\n" + "To load this image, set the device address " + "key/value pair: fpga=usrp1_fpga_4rx.rbf\n"; + + if (dspno == 0) { // only care if dsp0 is set since its homogeneous bool s = this->disable_rx(); _iface->poke32(FR_RX_SAMPLE_RATE_DIV, div - 1); - _iface->poke32(FR_DECIM_RATE, rate/div - 1); + _iface->poke32(FR_DECIM_RATE, rate / div - 1); this->restore_rx(s); - //update the streamer if created + // update the streamer if created std::shared_ptr<usrp1_recv_packet_streamer> my_streamer = std::dynamic_pointer_cast<usrp1_recv_packet_streamer>(_rx_streamer.lock()); - if (my_streamer.get() != NULL){ + if (my_streamer.get() != NULL) { my_streamer->set_samp_rate(_master_clock_rate / rate); } } @@ -518,21 +545,22 @@ double usrp1_impl::update_rx_samp_rate(size_t dspno, const double samp_rate){ return _master_clock_rate / rate; } -double usrp1_impl::update_tx_samp_rate(size_t dspno, const double samp_rate){ - - const size_t div = this->has_tx_halfband()? 4 : 2; //doubled for codec interp - const size_t rate = boost::math::iround(_master_clock_rate/this->get_tx_dsp_host_rates().clip(samp_rate, true)); +double usrp1_impl::update_tx_samp_rate(size_t dspno, const double samp_rate) +{ + const size_t div = this->has_tx_halfband() ? 4 : 2; // doubled for codec interp + const size_t rate = boost::math::iround( + _master_clock_rate / this->get_tx_dsp_host_rates().clip(samp_rate, true)); - if (dspno == 0){ //only care if dsp0 is set since its homogeneous + if (dspno == 0) { // only care if dsp0 is set since its homogeneous bool s = this->disable_tx(); _iface->poke32(FR_TX_SAMPLE_RATE_DIV, div - 1); - _iface->poke32(FR_INTERP_RATE, rate/div - 1); + _iface->poke32(FR_INTERP_RATE, rate / div - 1); this->restore_tx(s); - //update the streamer if created + // update the streamer if created std::shared_ptr<usrp1_send_packet_streamer> my_streamer = std::dynamic_pointer_cast<usrp1_send_packet_streamer>(_tx_streamer.lock()); - if (my_streamer.get() != NULL){ + if (my_streamer.get() != NULL) { my_streamer->set_samp_rate(_master_clock_rate / rate); } } @@ -540,123 +568,125 @@ double usrp1_impl::update_tx_samp_rate(size_t dspno, const double samp_rate){ return _master_clock_rate / rate; } -void usrp1_impl::update_rates(void){ +void usrp1_impl::update_rates(void) +{ const fs_path mb_path = "/mboards/0"; this->update_tick_rate(_master_clock_rate); - for(const std::string &name: _tree->list(mb_path / "rx_dsps")){ + for (const std::string& name : _tree->list(mb_path / "rx_dsps")) { _tree->access<double>(mb_path / "rx_dsps" / name / "rate" / "value").update(); } - for(const std::string &name: _tree->list(mb_path / "tx_dsps")){ + for (const std::string& name : _tree->list(mb_path / "tx_dsps")) { _tree->access<double>(mb_path / "tx_dsps" / name / "rate" / "value").update(); } } -double usrp1_impl::update_rx_dsp_freq(const size_t dspno, const double freq_){ - - //correct for outside of rate (wrap around) +double usrp1_impl::update_rx_dsp_freq(const size_t dspno, const double freq_) +{ + // correct for outside of rate (wrap around) double freq = std::fmod(freq_, _master_clock_rate); - if (std::abs(freq) > _master_clock_rate/2.0) - freq -= boost::math::sign(freq)*_master_clock_rate; + if (std::abs(freq) > _master_clock_rate / 2.0) + freq -= boost::math::sign(freq) * _master_clock_rate; - //calculate the freq register word (signed) - UHD_ASSERT_THROW(std::abs(freq) <= _master_clock_rate/2.0); + // calculate the freq register word (signed) + UHD_ASSERT_THROW(std::abs(freq) <= _master_clock_rate / 2.0); static const double scale_factor = std::pow(2.0, 32); - const int32_t freq_word = int32_t(boost::math::round((freq / _master_clock_rate) * scale_factor)); + const int32_t freq_word = + int32_t(boost::math::round((freq / _master_clock_rate) * scale_factor)); static const uint32_t dsp_index_to_reg_val[4] = { - FR_RX_FREQ_0, FR_RX_FREQ_1, FR_RX_FREQ_2, FR_RX_FREQ_3 - }; + FR_RX_FREQ_0, FR_RX_FREQ_1, FR_RX_FREQ_2, FR_RX_FREQ_3}; _iface->poke32(dsp_index_to_reg_val[dspno], freq_word); return (double(freq_word) / scale_factor) * _master_clock_rate; } -double usrp1_impl::update_tx_dsp_freq(const size_t dspno, const double freq){ +double usrp1_impl::update_tx_dsp_freq(const size_t dspno, const double freq) +{ const subdev_spec_pair_t pair = _tx_subdev_spec.at(dspno); - //determine the connection type and hence, the sign - const std::string conn = _tree->access<std::string>(str(boost::format( - "/mboards/0/dboards/%s/tx_frontends/%s/connection" - ) % pair.db_name % pair.sd_name)).get(); - double sign = (conn == "I" or conn == "IQ")? +1.0 : -1.0; - - //map this DSP's subdev spec to a particular codec chip - _dbc[pair.db_name].codec->set_duc_freq(sign*freq, _master_clock_rate); - return freq; //assume infinite precision + // determine the connection type and hence, the sign + const std::string conn = + _tree + ->access<std::string>( + str(boost::format("/mboards/0/dboards/%s/tx_frontends/%s/connection") + % pair.db_name % pair.sd_name)) + .get(); + double sign = (conn == "I" or conn == "IQ") ? +1.0 : -1.0; + + // map this DSP's subdev spec to a particular codec chip + _dbc[pair.db_name].codec->set_duc_freq(sign * freq, _master_clock_rate); + return freq; // assume infinite precision } /*********************************************************************** * Async Data **********************************************************************/ -bool usrp1_impl::recv_async_msg( - async_metadata_t &async_metadata, double timeout -){ - boost::this_thread::disable_interruption di; //disable because the wait can throw - return _soft_time_ctrl->get_async_queue().pop_with_timed_wait(async_metadata, timeout); +bool usrp1_impl::recv_async_msg(async_metadata_t& async_metadata, double timeout) +{ + boost::this_thread::disable_interruption di; // disable because the wait can throw + return _soft_time_ctrl->get_async_queue().pop_with_timed_wait( + async_metadata, timeout); } /*********************************************************************** * Receive streamer **********************************************************************/ -rx_streamer::sptr usrp1_impl::get_rx_stream(const uhd::stream_args_t &args_){ +rx_streamer::sptr usrp1_impl::get_rx_stream(const uhd::stream_args_t& args_) +{ stream_args_t args = args_; - //setup defaults for unspecified values - args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; - args.channels.clear(); //NOTE: we have no choice about the channel mapping - for (size_t ch = 0; ch < _rx_subdev_spec.size(); ch++){ + // setup defaults for unspecified values + args.otw_format = args.otw_format.empty() ? "sc16" : args.otw_format; + args.channels.clear(); // NOTE: we have no choice about the channel mapping + for (size_t ch = 0; ch < _rx_subdev_spec.size(); ch++) { args.channels.push_back(ch); } - if (args.otw_format == "sc16"){ - _iface->poke32(FR_RX_FORMAT, 0 - | (0 << bmFR_RX_FORMAT_SHIFT_SHIFT) - | (16 << bmFR_RX_FORMAT_WIDTH_SHIFT) - | bmFR_RX_FORMAT_WANT_Q - ); - } - else if (args.otw_format == "sc8"){ - _iface->poke32(FR_RX_FORMAT, 0 - | (8 << bmFR_RX_FORMAT_SHIFT_SHIFT) - | (8 << bmFR_RX_FORMAT_WIDTH_SHIFT) - | bmFR_RX_FORMAT_WANT_Q - ); - } - else{ - throw uhd::value_error("USRP1 RX cannot handle requested wire format: " + args.otw_format); + if (args.otw_format == "sc16") { + _iface->poke32(FR_RX_FORMAT, + 0 | (0 << bmFR_RX_FORMAT_SHIFT_SHIFT) | (16 << bmFR_RX_FORMAT_WIDTH_SHIFT) + | bmFR_RX_FORMAT_WANT_Q); + } else if (args.otw_format == "sc8") { + _iface->poke32(FR_RX_FORMAT, + 0 | (8 << bmFR_RX_FORMAT_SHIFT_SHIFT) | (8 << bmFR_RX_FORMAT_WIDTH_SHIFT) + | bmFR_RX_FORMAT_WANT_Q); + } else { + throw uhd::value_error( + "USRP1 RX cannot handle requested wire format: " + args.otw_format); } - //calculate packet size - const size_t bpp = _data_transport->get_recv_frame_size()/args.channels.size(); - const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); + // calculate packet size + const size_t bpp = _data_transport->get_recv_frame_size() / args.channels.size(); + const size_t spp = bpp / convert::get_bytes_per_item(args.otw_format); - //make the new streamer given the samples per packet + // make the new streamer given the samples per packet std::shared_ptr<usrp1_recv_packet_streamer> my_streamer = std::make_shared<usrp1_recv_packet_streamer>(spp, _soft_time_ctrl); - //init some streamer stuff + // init some streamer stuff my_streamer->set_tick_rate(_master_clock_rate); my_streamer->set_vrt_unpacker(&usrp1_bs_vrt_unpacker); - my_streamer->set_xport_chan_get_buff(0, std::bind( - &uhd::transport::zero_copy_if::get_recv_buff, _io_impl->data_transport, std::placeholders::_1 - )); + my_streamer->set_xport_chan_get_buff(0, + std::bind(&uhd::transport::zero_copy_if::get_recv_buff, + _io_impl->data_transport, + std::placeholders::_1)); - //set the converter + // set the converter uhd::convert::id_type id; - id.input_format = args.otw_format + "_item16_usrp1"; - id.num_inputs = 1; + id.input_format = args.otw_format + "_item16_usrp1"; + id.num_inputs = 1; id.output_format = args.cpu_format; - id.num_outputs = args.channels.size(); + id.num_outputs = args.channels.size(); my_streamer->set_converter(id); - //special scale factor change for sc8 + // special scale factor change for sc8 if (args.otw_format == "sc8") - my_streamer->set_scale_factor(1.0/127); + my_streamer->set_scale_factor(1.0 / 127); - //save as weak ptr for update access + // save as weak ptr for update access _rx_streamer = my_streamer; - //sets all tick and samp rates on this streamer + // sets all tick and samp rates on this streamer this->update_rates(); return my_streamer; @@ -665,51 +695,54 @@ rx_streamer::sptr usrp1_impl::get_rx_stream(const uhd::stream_args_t &args_){ /*********************************************************************** * Transmit streamer **********************************************************************/ -tx_streamer::sptr usrp1_impl::get_tx_stream(const uhd::stream_args_t &args_){ +tx_streamer::sptr usrp1_impl::get_tx_stream(const uhd::stream_args_t& args_) +{ stream_args_t args = args_; - //setup defaults for unspecified values - args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; - args.channels.clear(); //NOTE: we have no choice about the channel mapping - for (size_t ch = 0; ch < _tx_subdev_spec.size(); ch++){ + // setup defaults for unspecified values + args.otw_format = args.otw_format.empty() ? "sc16" : args.otw_format; + args.channels.clear(); // NOTE: we have no choice about the channel mapping + for (size_t ch = 0; ch < _tx_subdev_spec.size(); ch++) { args.channels.push_back(ch); } - if (args.otw_format != "sc16"){ - throw uhd::value_error("USRP1 TX cannot handle requested wire format: " + args.otw_format); + if (args.otw_format != "sc16") { + throw uhd::value_error( + "USRP1 TX cannot handle requested wire format: " + args.otw_format); } _iface->poke32(FR_TX_FORMAT, bmFR_TX_FORMAT_16_IQ); - //calculate packet size - size_t bpp = _data_transport->get_send_frame_size()/args.channels.size(); - bpp -= alignment_padding - 1; //minus the max remainder after LUT commit - const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); + // calculate packet size + size_t bpp = _data_transport->get_send_frame_size() / args.channels.size(); + bpp -= alignment_padding - 1; // minus the max remainder after LUT commit + const size_t spp = bpp / convert::get_bytes_per_item(args.otw_format); - //make the new streamer given the samples per packet - std::function<void(bool)> tx_fcn = std::bind(&usrp1_impl::tx_stream_on_off, this, std::placeholders::_1); + // make the new streamer given the samples per packet + std::function<void(bool)> tx_fcn = + std::bind(&usrp1_impl::tx_stream_on_off, this, std::placeholders::_1); std::shared_ptr<usrp1_send_packet_streamer> my_streamer = std::make_shared<usrp1_send_packet_streamer>(spp, _soft_time_ctrl, tx_fcn); - //init some streamer stuff + // init some streamer stuff my_streamer->set_tick_rate(_master_clock_rate); my_streamer->set_vrt_packer(&usrp1_bs_vrt_packer); - my_streamer->set_xport_chan_get_buff(0, std::bind( - &usrp1_impl::io_impl::get_send_buff, _io_impl.get(), std::placeholders::_1 - )); + my_streamer->set_xport_chan_get_buff(0, + std::bind( + &usrp1_impl::io_impl::get_send_buff, _io_impl.get(), std::placeholders::_1)); - //set the converter + // set the converter uhd::convert::id_type id; - id.input_format = args.cpu_format; - id.num_inputs = args.channels.size(); + id.input_format = args.cpu_format; + id.num_inputs = args.channels.size(); id.output_format = args.otw_format + "_item16_usrp1"; - id.num_outputs = 1; + id.num_outputs = 1; my_streamer->set_converter(id); - //save as weak ptr for update access + // save as weak ptr for update access _tx_streamer = my_streamer; - //sets all tick and samp rates on this streamer + // sets all tick and samp rates on this streamer this->update_rates(); return my_streamer; diff --git a/host/lib/usrp/usrp1/mb_eeprom.cpp b/host/lib/usrp/usrp1/mb_eeprom.cpp index 9b868fd4e..756a10395 100644 --- a/host/lib/usrp/usrp1/mb_eeprom.cpp +++ b/host/lib/usrp/usrp1/mb_eeprom.cpp @@ -5,22 +5,23 @@ // #include "usrp1_impl.hpp" -#include <uhdlib/utils/eeprom_utils.hpp> -#include <uhd/usrp/mboard_eeprom.hpp> #include <uhd/types/byte_vector.hpp> +#include <uhd/usrp/mboard_eeprom.hpp> +#include <uhdlib/utils/eeprom_utils.hpp> namespace { - const uint8_t USRP1_EEPROM_ADDR = 0x50; - const size_t USRP1_SERIAL_LEN = 8; +const uint8_t USRP1_EEPROM_ADDR = 0x50; +const size_t USRP1_SERIAL_LEN = 8; - //use char array so we dont need to attribute packed - struct usrp1_eeprom_map{ - unsigned char _r[221]; - unsigned char mcr[4]; - unsigned char name[NAME_MAX_LEN]; - unsigned char serial[USRP1_SERIAL_LEN]; - }; -} +// use char array so we dont need to attribute packed +struct usrp1_eeprom_map +{ + unsigned char _r[221]; + unsigned char mcr[4]; + unsigned char name[NAME_MAX_LEN]; + unsigned char serial[USRP1_SERIAL_LEN]; +}; +} // namespace using namespace uhd; using uhd::usrp::mboard_eeprom_t; @@ -29,62 +30,56 @@ mboard_eeprom_t usrp1_impl::get_mb_eeprom(uhd::i2c_iface::sptr iface) { mboard_eeprom_t mb_eeprom; - //extract the serial + // extract the serial mb_eeprom["serial"] = uhd::bytes_to_string(iface->read_eeprom( - USRP1_EEPROM_ADDR, offsetof(usrp1_eeprom_map, serial), USRP1_SERIAL_LEN - )); + USRP1_EEPROM_ADDR, offsetof(usrp1_eeprom_map, serial), USRP1_SERIAL_LEN)); - //extract the name + // extract the name mb_eeprom["name"] = uhd::bytes_to_string(iface->read_eeprom( - USRP1_EEPROM_ADDR, offsetof(usrp1_eeprom_map, name), NAME_MAX_LEN - )); + USRP1_EEPROM_ADDR, offsetof(usrp1_eeprom_map, name), NAME_MAX_LEN)); - //extract master clock rate as a 32-bit uint in Hz + // extract master clock rate as a 32-bit uint in Hz uint32_t master_clock_rate; const byte_vector_t rate_bytes = iface->read_eeprom( - USRP1_EEPROM_ADDR, offsetof(usrp1_eeprom_map, mcr), sizeof(master_clock_rate) - ); - std::copy( - rate_bytes.begin(), rate_bytes.end(), //input - reinterpret_cast<uint8_t *>(&master_clock_rate) //output + USRP1_EEPROM_ADDR, offsetof(usrp1_eeprom_map, mcr), sizeof(master_clock_rate)); + std::copy(rate_bytes.begin(), + rate_bytes.end(), // input + reinterpret_cast<uint8_t*>(&master_clock_rate) // output ); master_clock_rate = ntohl(master_clock_rate); - if (master_clock_rate > 1e6 and master_clock_rate < 1e9){ + if (master_clock_rate > 1e6 and master_clock_rate < 1e9) { mb_eeprom["mcr"] = std::to_string(master_clock_rate); - } - else mb_eeprom["mcr"] = ""; + } else + mb_eeprom["mcr"] = ""; return mb_eeprom; } -void usrp1_impl::set_mb_eeprom(const mboard_eeprom_t &mb_eeprom) +void usrp1_impl::set_mb_eeprom(const mboard_eeprom_t& mb_eeprom) { - auto &iface = _fx2_ctrl; + auto& iface = _fx2_ctrl; - //store the serial - if (mb_eeprom.has_key("serial")) iface->write_eeprom( - USRP1_EEPROM_ADDR, offsetof(usrp1_eeprom_map, serial), - string_to_bytes(mb_eeprom["serial"], USRP1_SERIAL_LEN) - ); + // store the serial + if (mb_eeprom.has_key("serial")) + iface->write_eeprom(USRP1_EEPROM_ADDR, + offsetof(usrp1_eeprom_map, serial), + string_to_bytes(mb_eeprom["serial"], USRP1_SERIAL_LEN)); - //store the name - if (mb_eeprom.has_key("name")) iface->write_eeprom( - USRP1_EEPROM_ADDR, offsetof(usrp1_eeprom_map, name), - string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN) - ); + // store the name + if (mb_eeprom.has_key("name")) + iface->write_eeprom(USRP1_EEPROM_ADDR, + offsetof(usrp1_eeprom_map, name), + string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN)); - //store the master clock rate as a 32-bit uint in Hz - if (mb_eeprom.has_key("mcr")){ + // store the master clock rate as a 32-bit uint in Hz + if (mb_eeprom.has_key("mcr")) { uint32_t master_clock_rate = uint32_t(std::stod(mb_eeprom["mcr"])); - master_clock_rate = htonl(master_clock_rate); + master_clock_rate = htonl(master_clock_rate); const byte_vector_t rate_bytes( - reinterpret_cast<const uint8_t *>(&master_clock_rate), - reinterpret_cast<const uint8_t *>(&master_clock_rate) - + sizeof(master_clock_rate) - ); + reinterpret_cast<const uint8_t*>(&master_clock_rate), + reinterpret_cast<const uint8_t*>(&master_clock_rate) + + sizeof(master_clock_rate)); iface->write_eeprom( - USRP1_EEPROM_ADDR, offsetof(usrp1_eeprom_map, mcr), rate_bytes - ); + USRP1_EEPROM_ADDR, offsetof(usrp1_eeprom_map, mcr), rate_bytes); } } - diff --git a/host/lib/usrp/usrp1/soft_time_ctrl.cpp b/host/lib/usrp/usrp1/soft_time_ctrl.cpp index eb08d0352..42a1e9712 100644 --- a/host/lib/usrp/usrp1/soft_time_ctrl.cpp +++ b/host/lib/usrp/usrp1/soft_time_ctrl.cpp @@ -21,106 +21,117 @@ namespace pt = boost::posix_time; static const time_spec_t TWIDDLE(0.0011); -soft_time_ctrl::~soft_time_ctrl(void){ +soft_time_ctrl::~soft_time_ctrl(void) +{ /* NOP */ } /*********************************************************************** * Soft time control implementation **********************************************************************/ -class soft_time_ctrl_impl : public soft_time_ctrl{ +class soft_time_ctrl_impl : public soft_time_ctrl +{ public: - - soft_time_ctrl_impl(const cb_fcn_type &stream_on_off): - _nsamps_remaining(0), - _stream_mode(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS), - _cmd_queue(2), - _async_msg_queue(1000), - _inline_msg_queue(1000), - _stream_on_off(stream_on_off) + soft_time_ctrl_impl(const cb_fcn_type& stream_on_off) + : _nsamps_remaining(0) + , _stream_mode(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS) + , _cmd_queue(2) + , _async_msg_queue(1000) + , _inline_msg_queue(1000) + , _stream_on_off(stream_on_off) { - //synchronously spawn a new thread + // synchronously spawn a new thread _recv_cmd_task = task::make(std::bind(&soft_time_ctrl_impl::recv_cmd_task, this)); - //initialize the time to something + // initialize the time to something this->set_time(time_spec_t(0.0)); } /******************************************************************* * Time control ******************************************************************/ - void set_time(const time_spec_t &time){ + void set_time(const time_spec_t& time) + { boost::mutex::scoped_lock lock(_update_mutex); _time_offset = uhd::get_system_time() - time; } - time_spec_t get_time(void){ + time_spec_t get_time(void) + { boost::mutex::scoped_lock lock(_update_mutex); return time_now(); } - UHD_INLINE time_spec_t time_now(void){ - //internal get time without scoped lock + UHD_INLINE time_spec_t time_now(void) + { + // internal get time without scoped lock return uhd::get_system_time() - _time_offset; } UHD_INLINE void sleep_until_time( - boost::mutex::scoped_lock &lock, const time_spec_t &time - ){ + boost::mutex::scoped_lock& lock, const time_spec_t& time) + { boost::condition_variable cond; - //use a condition variable to unlock, sleep, lock + // use a condition variable to unlock, sleep, lock double seconds_to_sleep = (time - time_now()).get_real_secs(); - cond.timed_wait(lock, pt::microseconds(long(seconds_to_sleep*1e6))); + cond.timed_wait(lock, pt::microseconds(long(seconds_to_sleep * 1e6))); } /******************************************************************* * Receive control ******************************************************************/ - size_t recv_post(rx_metadata_t &md, const size_t nsamps){ + size_t recv_post(rx_metadata_t& md, const size_t nsamps) + { boost::mutex::scoped_lock lock(_update_mutex); - //Since it timed out on the receive, check for inline messages... - //Must do a post check because recv() will not wake up for a message. - if (md.error_code == rx_metadata_t::ERROR_CODE_TIMEOUT){ - if (_inline_msg_queue.pop_with_haste(md)) return 0; + // Since it timed out on the receive, check for inline messages... + // Must do a post check because recv() will not wake up for a message. + if (md.error_code == rx_metadata_t::ERROR_CODE_TIMEOUT) { + if (_inline_msg_queue.pop_with_haste(md)) + return 0; } - //load the metadata with the expected time + // load the metadata with the expected time md.has_time_spec = true; - md.time_spec = time_now(); - - //none of the stuff below matters in continuous streaming mode - if (_stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS) return nsamps; - - //When to stop streaming: - //The samples have been received and the stream mode is non-continuous. - //Rewrite the sample count to clip to the requested number of samples. - if (_nsamps_remaining <= nsamps) switch(_stream_mode){ - case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE:{ - rx_metadata_t metadata; - metadata.has_time_spec = true; - metadata.time_spec = this->time_now(); - metadata.error_code = rx_metadata_t::ERROR_CODE_BROKEN_CHAIN; - _inline_msg_queue.push_with_pop_on_full(metadata); - } //continue to next case... - UHD_FALLTHROUGH - case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE: - md.end_of_burst = true; - this->issue_stream_cmd(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); - return _nsamps_remaining; - default: break; - } + md.time_spec = time_now(); + + // none of the stuff below matters in continuous streaming mode + if (_stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS) + return nsamps; + + // When to stop streaming: + // The samples have been received and the stream mode is non-continuous. + // Rewrite the sample count to clip to the requested number of samples. + if (_nsamps_remaining <= nsamps) + switch (_stream_mode) { + case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE: { + rx_metadata_t metadata; + metadata.has_time_spec = true; + metadata.time_spec = this->time_now(); + metadata.error_code = rx_metadata_t::ERROR_CODE_BROKEN_CHAIN; + _inline_msg_queue.push_with_pop_on_full(metadata); + } // continue to next case... + UHD_FALLTHROUGH + case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE: + md.end_of_burst = true; + this->issue_stream_cmd(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); + return _nsamps_remaining; + default: + break; + } - //update the consumed samples + // update the consumed samples _nsamps_remaining -= nsamps; return nsamps; } - void issue_stream_cmd(const stream_cmd_t &cmd){ + void issue_stream_cmd(const stream_cmd_t& cmd) + { _cmd_queue.push_with_wait(std::make_shared<stream_cmd_t>(cmd)); } - void stream_on_off(bool enb){ + void stream_on_off(bool enb) + { _stream_on_off(enb); _nsamps_remaining = 0; } @@ -128,20 +139,22 @@ public: /******************************************************************* * Transmit control ******************************************************************/ - void send_pre(const tx_metadata_t &md, double &timeout){ - if (not md.has_time_spec) return; + void send_pre(const tx_metadata_t& md, double& timeout) + { + if (not md.has_time_spec) + return; boost::mutex::scoped_lock lock(_update_mutex); time_spec_t time_at(md.time_spec - TWIDDLE); - //handle late packets - if (time_at < time_now()){ + // handle late packets + if (time_at < time_now()) { async_metadata_t metadata; - metadata.channel = 0; + metadata.channel = 0; metadata.has_time_spec = true; - metadata.time_spec = this->time_now(); - metadata.event_code = async_metadata_t::EVENT_CODE_TIME_ERROR; + metadata.time_spec = this->time_now(); + metadata.event_code = async_metadata_t::EVENT_CODE_TIME_ERROR; _async_msg_queue.push_with_pop_on_full(metadata); return; } @@ -153,59 +166,63 @@ public: /******************************************************************* * Thread control ******************************************************************/ - void recv_cmd_handle_cmd(const stream_cmd_t &cmd){ + void recv_cmd_handle_cmd(const stream_cmd_t& cmd) + { boost::mutex::scoped_lock lock(_update_mutex); - //handle the stream at time by sleeping - if (not cmd.stream_now){ + // handle the stream at time by sleeping + if (not cmd.stream_now) { time_spec_t time_at(cmd.time_spec - TWIDDLE); - if (time_at < time_now()){ + if (time_at < time_now()) { rx_metadata_t metadata; metadata.has_time_spec = true; - metadata.time_spec = this->time_now(); - metadata.error_code = rx_metadata_t::ERROR_CODE_LATE_COMMAND; + metadata.time_spec = this->time_now(); + metadata.error_code = rx_metadata_t::ERROR_CODE_LATE_COMMAND; _inline_msg_queue.push_with_pop_on_full(metadata); this->issue_stream_cmd(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); return; - } - else{ + } else { sleep_until_time(lock, time_at); } } - //When to stop streaming: - //Stop streaming when the command is a stop and streaming. + // When to stop streaming: + // Stop streaming when the command is a stop and streaming. if (cmd.stream_mode == stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS - and _stream_mode != stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS - ) stream_on_off(false); + and _stream_mode != stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS) + stream_on_off(false); - //When to start streaming: - //Start streaming when the command is not a stop and not streaming. + // When to start streaming: + // Start streaming when the command is not a stop and not streaming. if (cmd.stream_mode != stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS - and _stream_mode == stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS - ) stream_on_off(true); + and _stream_mode == stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS) + stream_on_off(true); - //update the state + // update the state _nsamps_remaining += cmd.num_samps; _stream_mode = cmd.stream_mode; } - void recv_cmd_task(void){ //task is looped + void recv_cmd_task(void) + { // task is looped std::shared_ptr<stream_cmd_t> cmd; if (_cmd_queue.pop_with_timed_wait(cmd, 0.25)) { recv_cmd_handle_cmd(*cmd); } } - bounded_buffer<async_metadata_t> &get_async_queue(void){ + bounded_buffer<async_metadata_t>& get_async_queue(void) + { return _async_msg_queue; } - bounded_buffer<rx_metadata_t> &get_inline_queue(void){ + bounded_buffer<rx_metadata_t>& get_inline_queue(void) + { return _inline_msg_queue; } - void stop(void){ + void stop(void) + { _recv_cmd_task.reset(); } @@ -214,7 +231,7 @@ private: size_t _nsamps_remaining; stream_cmd_t::stream_mode_t _stream_mode; time_spec_t _time_offset; - bounded_buffer<std::shared_ptr<stream_cmd_t> > _cmd_queue; + bounded_buffer<std::shared_ptr<stream_cmd_t>> _cmd_queue; bounded_buffer<async_metadata_t> _async_msg_queue; bounded_buffer<rx_metadata_t> _inline_msg_queue; const cb_fcn_type _stream_on_off; @@ -224,6 +241,7 @@ private: /*********************************************************************** * Soft time control factor **********************************************************************/ -soft_time_ctrl::sptr soft_time_ctrl::make(const cb_fcn_type &stream_on_off){ +soft_time_ctrl::sptr soft_time_ctrl::make(const cb_fcn_type& stream_on_off) +{ return sptr(new soft_time_ctrl_impl(stream_on_off)); } diff --git a/host/lib/usrp/usrp1/soft_time_ctrl.hpp b/host/lib/usrp/usrp1/soft_time_ctrl.hpp index 48915499a..b346f4453 100644 --- a/host/lib/usrp/usrp1/soft_time_ctrl.hpp +++ b/host/lib/usrp/usrp1/soft_time_ctrl.hpp @@ -8,15 +8,15 @@ #ifndef INCLUDED_LIBUHD_USRP_USRP1_SOFT_TIME_CTRL_HPP #define INCLUDED_LIBUHD_USRP_USRP1_SOFT_TIME_CTRL_HPP +#include <uhd/transport/bounded_buffer.hpp> +#include <uhd/types/metadata.hpp> #include <uhd/types/stream_cmd.hpp> #include <uhd/types/time_spec.hpp> -#include <uhd/types/metadata.hpp> -#include <uhd/transport/bounded_buffer.hpp> #include <uhd/utils/noncopyable.hpp> -#include <memory> #include <functional> +#include <memory> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { /*! * The soft time control emulates some of the @@ -25,7 +25,8 @@ namespace uhd{ namespace usrp{ * timed transmits, timed receive commands, device time, * and inline and async error messages. */ -class soft_time_ctrl : uhd::noncopyable{ +class soft_time_ctrl : uhd::noncopyable +{ public: typedef std::shared_ptr<soft_time_ctrl> sptr; typedef std::function<void(bool)> cb_fcn_type; @@ -37,33 +38,33 @@ public: * \param stream_on_off a function to enable/disable rx * \return a new soft time control object */ - static sptr make(const cb_fcn_type &stream_on_off); + static sptr make(const cb_fcn_type& stream_on_off); //! Set the current time - virtual void set_time(const time_spec_t &time) = 0; + virtual void set_time(const time_spec_t& time) = 0; //! Get the current time virtual time_spec_t get_time(void) = 0; //! Call after the internal recv function - virtual size_t recv_post(rx_metadata_t &md, const size_t nsamps) = 0; + virtual size_t recv_post(rx_metadata_t& md, const size_t nsamps) = 0; //! Call before the internal send function - virtual void send_pre(const tx_metadata_t &md, double &timeout) = 0; + virtual void send_pre(const tx_metadata_t& md, double& timeout) = 0; //! Issue a stream command to receive - virtual void issue_stream_cmd(const stream_cmd_t &cmd) = 0; + virtual void issue_stream_cmd(const stream_cmd_t& cmd) = 0; //! Get access to a buffer of async metadata - virtual transport::bounded_buffer<async_metadata_t> &get_async_queue(void) = 0; + virtual transport::bounded_buffer<async_metadata_t>& get_async_queue(void) = 0; //! Get access to a buffer of inline metadata - virtual transport::bounded_buffer<rx_metadata_t> &get_inline_queue(void) = 0; + virtual transport::bounded_buffer<rx_metadata_t>& get_inline_queue(void) = 0; //! Stops threads before deconstruction to avoid race conditions virtual void stop(void) = 0; }; -}} //namespace +}} // namespace uhd::usrp #endif /* INCLUDED_LIBUHD_USRP_USRP1_SOFT_TIME_CTRL_HPP */ diff --git a/host/lib/usrp/usrp1/usrp1_calc_mux.hpp b/host/lib/usrp/usrp1/usrp1_calc_mux.hpp index 1169f2fe8..63f00f514 100644 --- a/host/lib/usrp/usrp1/usrp1_calc_mux.hpp +++ b/host/lib/usrp/usrp1/usrp1_calc_mux.hpp @@ -12,14 +12,14 @@ #include <uhd/utils/log.hpp> #include <boost/assign/list_of.hpp> #include <boost/format.hpp> +#include <string> #include <utility> #include <vector> -#include <string> #ifndef INCLUDED_USRP1_CALC_MUX_HPP -#define INCLUDED_USRP1_CALC_MUX_HPP +# define INCLUDED_USRP1_CALC_MUX_HPP -//db_name, conn_type for the mux calculations below... +// db_name, conn_type for the mux calculations below... typedef std::pair<std::string, std::string> mapping_pair_t; /*********************************************************************** @@ -27,7 +27,8 @@ typedef std::pair<std::string, std::string> mapping_pair_t; * The I and Q mux values are intentionally reversed to flip I and Q * to account for the reversal in the type conversion routines. **********************************************************************/ -static int calc_rx_mux_pair(int adc_for_i, int adc_for_q){ +static int calc_rx_mux_pair(int adc_for_i, int adc_for_q) +{ return (adc_for_i << 0) | (adc_for_q << 2); } @@ -38,48 +39,49 @@ static int calc_rx_mux_pair(int adc_for_i, int adc_for_q){ * | must be zero | Q3| I3| Q2| I2| Q1| I1| Q0| I0|Z| NCH | * +-----------------------+-------+-------+-------+-------+-+-----+ */ -static uint32_t calc_rx_mux(const std::vector<mapping_pair_t> &mapping){ - //create look-up-table for mapping dboard name and connection type to ADC flags +static uint32_t calc_rx_mux(const std::vector<mapping_pair_t>& mapping) +{ + // create look-up-table for mapping dboard name and connection type to ADC flags static const int ADC0 = 0, ADC1 = 1, ADC2 = 2, ADC3 = 3; - static const uhd::dict<std::string, uhd::dict<std::string, int> > name_to_conn_to_flag = boost::assign::map_list_of - ("A", boost::assign::map_list_of - ("IQ", calc_rx_mux_pair(ADC0, ADC1)) //I and Q - ("QI", calc_rx_mux_pair(ADC1, ADC0)) //I and Q - ("I", calc_rx_mux_pair(ADC0, ADC0)) //I and Q (Q identical but ignored Z=1) - ("Q", calc_rx_mux_pair(ADC1, ADC1)) //I and Q (Q identical but ignored Z=1) - ) - ("B", boost::assign::map_list_of - ("IQ", calc_rx_mux_pair(ADC2, ADC3)) //I and Q - ("QI", calc_rx_mux_pair(ADC3, ADC2)) //I and Q - ("I", calc_rx_mux_pair(ADC2, ADC2)) //I and Q (Q identical but ignored Z=1) - ("Q", calc_rx_mux_pair(ADC3, ADC3)) //I and Q (Q identical but ignored Z=1) - ) - ; - - //extract the number of channels + static const uhd::dict<std::string, uhd::dict<std::string, int>> + name_to_conn_to_flag = boost::assign::map_list_of("A", + boost::assign::map_list_of("IQ", calc_rx_mux_pair(ADC0, ADC1)) // I and Q + ("QI", calc_rx_mux_pair(ADC1, ADC0)) // I and Q + ("I", calc_rx_mux_pair(ADC0, ADC0)) // I and Q (Q identical but ignored Z=1) + ("Q", calc_rx_mux_pair(ADC1, ADC1)) // I and Q (Q identical but ignored Z=1) + )("B", + boost::assign::map_list_of("IQ", calc_rx_mux_pair(ADC2, ADC3)) // I and Q + ("QI", calc_rx_mux_pair(ADC3, ADC2)) // I and Q + ("I", calc_rx_mux_pair(ADC2, ADC2)) // I and Q (Q identical but ignored Z=1) + ("Q", calc_rx_mux_pair(ADC3, ADC3)) // I and Q (Q identical but ignored Z=1) + ); + + // extract the number of channels const size_t nchan = mapping.size(); - //calculate the channel flags + // calculate the channel flags int channel_flags = 0; size_t num_reals = 0, num_quads = 0; - for(const mapping_pair_t &pair: uhd::reversed(mapping)){ + for (const mapping_pair_t& pair : uhd::reversed(mapping)) { const std::string name = pair.first, conn = pair.second; - if (conn == "IQ" or conn == "QI") num_quads++; - if (conn == "I" or conn == "Q") num_reals++; + if (conn == "IQ" or conn == "QI") + num_quads++; + if (conn == "I" or conn == "Q") + num_reals++; channel_flags = (channel_flags << 4) | name_to_conn_to_flag[name][conn]; } - //calculate Z: + // calculate Z: // for all real sources: Z = 1 // for all quadrature sources: Z = 0 // for mixed sources: warning + Z = 0 - int Z = (num_quads > 0)? 0 : 1; - if (num_quads != 0 and num_reals != 0) UHD_LOGGER_WARNING("USRP1") << boost::format( - "Mixing real and quadrature rx subdevices is not supported.\n" - "The Q input to the real source(s) will be non-zero.\n" - ); + int Z = (num_quads > 0) ? 0 : 1; + if (num_quads != 0 and num_reals != 0) + UHD_LOGGER_WARNING("USRP1") << boost::format( + "Mixing real and quadrature rx subdevices is not supported.\n" + "The Q input to the real source(s) will be non-zero.\n"); - //calculate the rx mux value + // calculate the rx mux value return ((channel_flags & 0xffff) << 4) | ((Z & 0x1) << 3) | ((nchan & 0x7) << 0); } @@ -88,7 +90,8 @@ static uint32_t calc_rx_mux(const std::vector<mapping_pair_t> &mapping){ * The I and Q mux values are intentionally reversed to flip I and Q * to account for the reversal in the type conversion routines. **********************************************************************/ -static int calc_tx_mux_pair(int chn_for_i, int chn_for_q){ +static int calc_tx_mux_pair(int chn_for_i, int chn_for_q) +{ return (chn_for_i << 0) | (chn_for_q << 4); } @@ -99,48 +102,50 @@ static int calc_tx_mux_pair(int chn_for_i, int chn_for_q){ * | | DAC1Q | DAC1I | DAC0Q | DAC0I |0| NCH | * +-----------------------------------------------+-------+-+-----+ */ -static uint32_t calc_tx_mux(const std::vector<mapping_pair_t> &mapping){ - //create look-up-table for mapping channel number and connection type to flags +static uint32_t calc_tx_mux(const std::vector<mapping_pair_t>& mapping) +{ + // create look-up-table for mapping channel number and connection type to flags static const int ENB = 1 << 3, CHAN_I0 = 0, CHAN_Q0 = 1, CHAN_I1 = 2, CHAN_Q1 = 3; - static const uhd::dict<size_t, uhd::dict<std::string, int> > chan_to_conn_to_flag = boost::assign::map_list_of - (0, boost::assign::map_list_of - ("IQ", calc_tx_mux_pair(CHAN_I0 | ENB, CHAN_Q0 | ENB)) - ("QI", calc_tx_mux_pair(CHAN_Q0 | ENB, CHAN_I0 | ENB)) - ("I", calc_tx_mux_pair(CHAN_I0 | ENB, 0 )) - ("Q", calc_tx_mux_pair(0, CHAN_I0 | ENB)) - ) - (1, boost::assign::map_list_of - ("IQ", calc_tx_mux_pair(CHAN_I1 | ENB, CHAN_Q1 | ENB)) - ("QI", calc_tx_mux_pair(CHAN_Q1 | ENB, CHAN_I1 | ENB)) - ("I", calc_tx_mux_pair(CHAN_I1 | ENB, 0 )) - ("Q", calc_tx_mux_pair(0, CHAN_I1 | ENB)) - ) - ; - - //extract the number of channels + static const uhd::dict<size_t, uhd::dict<std::string, int>> chan_to_conn_to_flag = + boost::assign::map_list_of(0, + boost::assign::map_list_of( + "IQ", calc_tx_mux_pair(CHAN_I0 | ENB, CHAN_Q0 | ENB))( + "QI", calc_tx_mux_pair(CHAN_Q0 | ENB, CHAN_I0 | ENB))( + "I", calc_tx_mux_pair(CHAN_I0 | ENB, 0))( + "Q", calc_tx_mux_pair(0, CHAN_I0 | ENB)))(1, + boost::assign::map_list_of( + "IQ", calc_tx_mux_pair(CHAN_I1 | ENB, CHAN_Q1 | ENB))( + "QI", calc_tx_mux_pair(CHAN_Q1 | ENB, CHAN_I1 | ENB))( + "I", calc_tx_mux_pair(CHAN_I1 | ENB, 0))( + "Q", calc_tx_mux_pair(0, CHAN_I1 | ENB))); + + // extract the number of channels size_t nchan = mapping.size(); - //calculate the channel flags + // calculate the channel flags int channel_flags = 0, chan = 0; - uhd::dict<std::string, int> slot_to_chan_count = boost::assign::map_list_of("A", 0)("B", 0); - for(const mapping_pair_t &pair: mapping){ + uhd::dict<std::string, int> slot_to_chan_count = + boost::assign::map_list_of("A", 0)("B", 0); + for (const mapping_pair_t& pair : mapping) { const std::string name = pair.first, conn = pair.second; - //combine the channel flags: shift for slot A vs B - if (name == "A") channel_flags |= chan_to_conn_to_flag[chan][conn] << 0; - if (name == "B") channel_flags |= chan_to_conn_to_flag[chan][conn] << 8; + // combine the channel flags: shift for slot A vs B + if (name == "A") + channel_flags |= chan_to_conn_to_flag[chan][conn] << 0; + if (name == "B") + channel_flags |= chan_to_conn_to_flag[chan][conn] << 8; - //sanity check, only 1 channel per slot + // sanity check, only 1 channel per slot slot_to_chan_count[name]++; - if (slot_to_chan_count[name] > 1) throw uhd::value_error( - "cannot assign dboard slot to multiple channels: " + name - ); + if (slot_to_chan_count[name] > 1) + throw uhd::value_error( + "cannot assign dboard slot to multiple channels: " + name); - //increment for the next channel + // increment for the next channel chan++; } - //calculate the tx mux value + // calculate the tx mux value return ((channel_flags & 0xffff) << 4) | ((nchan & 0x7) << 0); } diff --git a/host/lib/usrp/usrp1/usrp1_iface.cpp b/host/lib/usrp/usrp1/usrp1_iface.cpp index ebc438f20..574dec51c 100644 --- a/host/lib/usrp/usrp1/usrp1_iface.cpp +++ b/host/lib/usrp/usrp1/usrp1_iface.cpp @@ -6,18 +6,19 @@ // #include "usrp1_iface.hpp" -#include <uhd/utils/log.hpp> #include <uhd/exception.hpp> #include <uhd/utils/byteswap.hpp> +#include <uhd/utils/log.hpp> #include <boost/format.hpp> -#include <stdexcept> #include <iomanip> +#include <stdexcept> using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; -class usrp1_iface_impl : public usrp1_iface{ +class usrp1_iface_impl : public usrp1_iface +{ public: /******************************************************************* * Structors @@ -39,54 +40,50 @@ public: { uint32_t swapped = uhd::htonx(value); - UHD_LOGGER_TRACE("USRP1") - << "poke32(" - << std::dec << std::setw(2) << addr << ", 0x" - << std::hex << std::setw(8) << value << ")" - ; + UHD_LOGGER_TRACE("USRP1") << "poke32(" << std::dec << std::setw(2) << addr + << ", 0x" << std::hex << std::setw(8) << value << ")"; uint8_t w_index_h = SPI_ENABLE_FPGA & 0xff; uint8_t w_index_l = (SPI_FMT_MSB | SPI_FMT_HDR_1) & 0xff; - int ret =_ctrl_transport->usrp_control_write( - VRQ_SPI_WRITE, - addr & 0x7f, - (w_index_h << 8) | (w_index_l << 0), - (unsigned char*) &swapped, - sizeof(uint32_t)); + int ret = _ctrl_transport->usrp_control_write(VRQ_SPI_WRITE, + addr & 0x7f, + (w_index_h << 8) | (w_index_l << 0), + (unsigned char*)&swapped, + sizeof(uint32_t)); - if (ret < 0) throw uhd::io_error("USRP1: failed control write"); + if (ret < 0) + throw uhd::io_error("USRP1: failed control write"); } uint32_t peek32(const uint32_t addr) { - UHD_LOGGER_TRACE("USRP1") - << "peek32(" - << std::dec << std::setw(2) << addr << ")" - ; + UHD_LOGGER_TRACE("USRP1") << "peek32(" << std::dec << std::setw(2) << addr << ")"; uint32_t value_out; uint8_t w_index_h = SPI_ENABLE_FPGA & 0xff; uint8_t w_index_l = (SPI_FMT_MSB | SPI_FMT_HDR_1) & 0xff; - int ret = _ctrl_transport->usrp_control_read( - VRQ_SPI_READ, - 0x80 | (addr & 0x7f), - (w_index_h << 8) | (w_index_l << 0), - (unsigned char*) &value_out, - sizeof(uint32_t)); + int ret = _ctrl_transport->usrp_control_read(VRQ_SPI_READ, + 0x80 | (addr & 0x7f), + (w_index_h << 8) | (w_index_l << 0), + (unsigned char*)&value_out, + sizeof(uint32_t)); - if (ret < 0) throw uhd::io_error("USRP1: failed control read"); + if (ret < 0) + throw uhd::io_error("USRP1: failed control read"); return uhd::ntohx(value_out); } - void poke16(const uint32_t, const uint16_t) { + void poke16(const uint32_t, const uint16_t) + { throw uhd::not_implemented_error("Unhandled command poke16()"); } - uint16_t peek16(const uint32_t) { + uint16_t peek16(const uint32_t) + { throw uhd::not_implemented_error("Unhandled command peek16()"); return 0; } @@ -94,11 +91,13 @@ public: /******************************************************************* * I2C ******************************************************************/ - void write_i2c(uint16_t addr, const byte_vector_t &bytes){ + void write_i2c(uint16_t addr, const byte_vector_t& bytes) + { return _ctrl_transport->write_i2c(addr, bytes); } - byte_vector_t read_i2c(uint16_t addr, size_t num_bytes){ + byte_vector_t read_i2c(uint16_t addr, size_t num_bytes) + { return _ctrl_transport->read_i2c(addr, num_bytes); } @@ -114,70 +113,68 @@ public: * control buffer for IN data. ******************************************************************/ uint32_t transact_spi(int which_slave, - const spi_config_t &, - uint32_t bits, - size_t num_bits, - bool readback) + const spi_config_t&, + uint32_t bits, + size_t num_bits, + bool readback) { UHD_LOGGER_TRACE("USRP1") << "transact_spi: " - << " slave: " << which_slave - << " bits: " << bits - << " num_bits: " << num_bits - << " readback: " << readback - ; + << " slave: " << which_slave << " bits: " << bits + << " num_bits: " << num_bits << " readback: " << readback; UHD_ASSERT_THROW((num_bits <= 32) && !(num_bits % 8)); size_t num_bytes = num_bits / 8; if (readback) { - unsigned char buff[4] = { - (unsigned char)(bits & 0xff), + unsigned char buff[4] = {(unsigned char)(bits & 0xff), (unsigned char)((bits >> 8) & 0xff), (unsigned char)((bits >> 16) & 0xff), - (unsigned char)((bits >> 24) & 0xff) - }; - //conditions where there are two header bytes - if (num_bytes >= 3 and buff[num_bytes-1] != 0 and buff[num_bytes-2] != 0 and buff[num_bytes-3] == 0){ - if (int(num_bytes-2) != _ctrl_transport->usrp_control_read( - VRQ_SPI_READ, (buff[num_bytes-1] << 8) | (buff[num_bytes-2] << 0), - (which_slave << 8) | SPI_FMT_MSB | SPI_FMT_HDR_2, - buff, num_bytes-2 - )) throw uhd::io_error("USRP1: failed SPI readback transaction"); + (unsigned char)((bits >> 24) & 0xff)}; + // conditions where there are two header bytes + if (num_bytes >= 3 and buff[num_bytes - 1] != 0 and buff[num_bytes - 2] != 0 + and buff[num_bytes - 3] == 0) { + if (int(num_bytes - 2) + != _ctrl_transport->usrp_control_read(VRQ_SPI_READ, + (buff[num_bytes - 1] << 8) | (buff[num_bytes - 2] << 0), + (which_slave << 8) | SPI_FMT_MSB | SPI_FMT_HDR_2, + buff, + num_bytes - 2)) + throw uhd::io_error("USRP1: failed SPI readback transaction"); } - //conditions where there is one header byte - else if (num_bytes >= 2 and buff[num_bytes-1] != 0 and buff[num_bytes-2] == 0){ - if (int(num_bytes-1) != _ctrl_transport->usrp_control_read( - VRQ_SPI_READ, buff[num_bytes-1], - (which_slave << 8) | SPI_FMT_MSB | SPI_FMT_HDR_1, - buff, num_bytes-1 - )) throw uhd::io_error("USRP1: failed SPI readback transaction"); - } - else{ + // conditions where there is one header byte + else if (num_bytes >= 2 and buff[num_bytes - 1] != 0 + and buff[num_bytes - 2] == 0) { + if (int(num_bytes - 1) + != _ctrl_transport->usrp_control_read(VRQ_SPI_READ, + buff[num_bytes - 1], + (which_slave << 8) | SPI_FMT_MSB | SPI_FMT_HDR_1, + buff, + num_bytes - 1)) + throw uhd::io_error("USRP1: failed SPI readback transaction"); + } else { throw uhd::io_error("USRP1: invalid input data for SPI readback"); } - uint32_t val = (((uint32_t)buff[0]) << 0) | - (((uint32_t)buff[1]) << 8) | - (((uint32_t)buff[2]) << 16) | - (((uint32_t)buff[3]) << 24); + uint32_t val = (((uint32_t)buff[0]) << 0) | (((uint32_t)buff[1]) << 8) + | (((uint32_t)buff[2]) << 16) | (((uint32_t)buff[3]) << 24); return val; - } - else { + } else { // Byteswap on num_bytes - unsigned char buff[4] = { 0 }; + unsigned char buff[4] = {0}; for (size_t i = 1; i <= num_bytes; i++) buff[num_bytes - i] = (bits >> ((i - 1) * 8)) & 0xff; uint8_t w_index_h = which_slave & 0xff; uint8_t w_index_l = (SPI_FMT_MSB | SPI_FMT_HDR_0) & 0xff; - int ret =_ctrl_transport->usrp_control_write( - VRQ_SPI_WRITE, - 0x00, - (w_index_h << 8) | (w_index_l << 0), - buff, num_bytes); + int ret = _ctrl_transport->usrp_control_write(VRQ_SPI_WRITE, + 0x00, + (w_index_h << 8) | (w_index_l << 0), + buff, + num_bytes); - if (ret < 0) throw uhd::io_error("USRP1: failed SPI transaction"); + if (ret < 0) + throw uhd::io_error("USRP1: failed SPI transaction"); return 0; } diff --git a/host/lib/usrp/usrp1/usrp1_iface.hpp b/host/lib/usrp/usrp1/usrp1_iface.hpp index b01b2d088..efcc50b58 100644 --- a/host/lib/usrp/usrp1/usrp1_iface.hpp +++ b/host/lib/usrp/usrp1/usrp1_iface.hpp @@ -8,23 +8,23 @@ #ifndef INCLUDED_USRP1_IFACE_HPP #define INCLUDED_USRP1_IFACE_HPP -#include <uhdlib/usrp/common/fx2_ctrl.hpp> -#include <uhd/types/wb_iface.hpp> #include <uhd/types/serial.hpp> -#include <memory> +#include <uhd/types/wb_iface.hpp> #include <uhd/utils/noncopyable.hpp> +#include <uhdlib/usrp/common/fx2_ctrl.hpp> +#include <memory> -#define SPI_ENABLE_FPGA 0x01 +#define SPI_ENABLE_FPGA 0x01 #define SPI_FMT_HDR_MASK (3 << 5) -#define SPI_FMT_HDR_0 (0 << 5) -#define SPI_FMT_HDR_1 (1 << 5) -#define SPI_FMT_HDR_2 (2 << 5) -#define SPI_FMT_LSB (1 << 7) -#define SPI_FMT_MSB (0 << 7) +#define SPI_FMT_HDR_0 (0 << 5) +#define SPI_FMT_HDR_1 (1 << 5) +#define SPI_FMT_HDR_2 (2 << 5) +#define SPI_FMT_LSB (1 << 7) +#define SPI_FMT_MSB (0 << 7) #define SPI_FMT_xSB_MASK (1 << 7) -#define VRQ_SPI_READ 0x82 -#define VRQ_SPI_WRITE 0x09 -#define VRQ_FW_COMPAT 0x83 +#define VRQ_SPI_READ 0x82 +#define VRQ_SPI_WRITE 0x09 +#define VRQ_FW_COMPAT 0x83 /*! @@ -32,7 +32,10 @@ * Provides a set of functions to implementation layer. * Including spi, peek, poke, control... */ -class usrp1_iface : public uhd::wb_iface, public uhd::i2c_iface, public uhd::spi_iface, uhd::noncopyable +class usrp1_iface : public uhd::wb_iface, + public uhd::i2c_iface, + public uhd::spi_iface, + uhd::noncopyable { public: typedef std::shared_ptr<usrp1_iface> sptr; diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp index a641c008c..d86bf6d56 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.cpp +++ b/host/lib/usrp/usrp1/usrp1_impl.cpp @@ -26,33 +26,34 @@ using namespace uhd::usrp; using namespace uhd::transport; namespace { - constexpr uint16_t USRP1_VENDOR_ID = 0xfffe; - constexpr uint16_t USRP1_PRODUCT_ID = 0x0002; - constexpr int64_t REENUMERATION_TIMEOUT_MS = 3000; -} +constexpr uint16_t USRP1_VENDOR_ID = 0xfffe; +constexpr uint16_t USRP1_PRODUCT_ID = 0x0002; +constexpr int64_t REENUMERATION_TIMEOUT_MS = 3000; +} // namespace const std::vector<usrp1_impl::dboard_slot_t> usrp1_impl::_dboard_slots{ - usrp1_impl::DBOARD_SLOT_A, - usrp1_impl::DBOARD_SLOT_B -}; + usrp1_impl::DBOARD_SLOT_A, usrp1_impl::DBOARD_SLOT_B}; /*********************************************************************** * Discovery **********************************************************************/ -static device_addrs_t usrp1_find(const device_addr_t &hint) +static device_addrs_t usrp1_find(const device_addr_t& hint) { device_addrs_t usrp1_addrs; - //return an empty list of addresses when type is set to non-usrp1 - if (hint.has_key("type") and hint["type"] != "usrp1") return usrp1_addrs; + // return an empty list of addresses when type is set to non-usrp1 + if (hint.has_key("type") and hint["type"] != "usrp1") + return usrp1_addrs; - //Return an empty list of addresses when an address or resource is specified, - //since an address and resource is intended for a different, non-USB, device. - if (hint.has_key("addr") || hint.has_key("resource")) return usrp1_addrs; + // Return an empty list of addresses when an address or resource is specified, + // since an address and resource is intended for a different, non-USB, device. + if (hint.has_key("addr") || hint.has_key("resource")) + return usrp1_addrs; uint16_t vid, pid; - if(hint.has_key("vid") && hint.has_key("pid") && hint.has_key("type") && hint["type"] == "usrp1") { + if (hint.has_key("vid") && hint.has_key("pid") && hint.has_key("type") + && hint["type"] == "usrp1") { vid = uhd::cast::hexstr_cast<uint16_t>(hint.get("vid")); pid = uhd::cast::hexstr_cast<uint16_t>(hint.get("pid")); } else { @@ -66,55 +67,61 @@ static device_addrs_t usrp1_find(const device_addr_t &hint) // so that re-enumeration after fw load can occur successfully. // This requirement is a courtesy of libusb1.0 on windows. - //find the usrps and load firmware + // find the usrps and load firmware size_t found = 0; - for(usb_device_handle::sptr handle: usb_device_handle::get_device_list(vid, pid)) { - //extract the firmware path for the USRP1 + for (usb_device_handle::sptr handle : usb_device_handle::get_device_list(vid, pid)) { + // extract the firmware path for the USRP1 std::string usrp1_fw_image; - try{ + try { usrp1_fw_image = find_image_path(hint.get("fw", "usrp1_fw.ihx")); + } catch (...) { + UHD_LOGGER_WARNING("USRP1") + << boost::format("Could not locate USRP1 firmware. %s") + % print_utility_error("uhd_images_downloader.py"); } - catch(...){ - UHD_LOGGER_WARNING("USRP1") << boost::format("Could not locate USRP1 firmware. %s") % print_utility_error("uhd_images_downloader.py"); - } - UHD_LOGGER_DEBUG("USRP1") << "USRP1 firmware image: " << usrp1_fw_image ; + UHD_LOGGER_DEBUG("USRP1") << "USRP1 firmware image: " << usrp1_fw_image; usb_control::sptr control; - try{control = usb_control::make(handle, 0);} - catch(const uhd::exception &){continue;} //ignore claimed + try { + control = usb_control::make(handle, 0); + } catch (const uhd::exception&) { + continue; + } // ignore claimed fx2_ctrl::make(control)->usrp_load_firmware(usrp1_fw_image); found++; } - //get descriptors again with serial number, but using the initialized VID/PID now since we have firmware + // get descriptors again with serial number, but using the initialized VID/PID now + // since we have firmware vid = USRP1_VENDOR_ID; pid = USRP1_PRODUCT_ID; - const auto timeout_time = - std::chrono::steady_clock::now() - + std::chrono::milliseconds(REENUMERATION_TIMEOUT_MS); + const auto timeout_time = std::chrono::steady_clock::now() + + std::chrono::milliseconds(REENUMERATION_TIMEOUT_MS); - //search for the device until found or timeout - while (std::chrono::steady_clock::now() < timeout_time - and usrp1_addrs.empty() and found != 0) { - for (usb_device_handle::sptr handle : usb_device_handle::get_device_list(vid, pid)) { + // search for the device until found or timeout + while (std::chrono::steady_clock::now() < timeout_time and usrp1_addrs.empty() + and found != 0) { + for (usb_device_handle::sptr handle : + usb_device_handle::get_device_list(vid, pid)) { usb_control::sptr control; - try{control = usb_control::make(handle, 0);} - catch(const uhd::exception &){continue;} //ignore claimed - - fx2_ctrl::sptr fx2_ctrl = fx2_ctrl::make(control); - const mboard_eeprom_t mb_eeprom = - usrp1_impl::get_mb_eeprom(fx2_ctrl); + try { + control = usb_control::make(handle, 0); + } catch (const uhd::exception&) { + continue; + } // ignore claimed + + fx2_ctrl::sptr fx2_ctrl = fx2_ctrl::make(control); + const mboard_eeprom_t mb_eeprom = usrp1_impl::get_mb_eeprom(fx2_ctrl); device_addr_t new_addr; - new_addr["type"] = "usrp1"; - new_addr["name"] = mb_eeprom["name"]; + new_addr["type"] = "usrp1"; + new_addr["name"] = mb_eeprom["name"]; new_addr["serial"] = handle->get_serial(); - //this is a found usrp1 when the hint serial and name match or blank - if ( - (not hint.has_key("name") or hint["name"] == new_addr["name"]) and - (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) - ){ + // this is a found usrp1 when the hint serial and name match or blank + if ((not hint.has_key("name") or hint["name"] == new_addr["name"]) + and (not hint.has_key("serial") + or hint["serial"] == new_addr["serial"])) { usrp1_addrs.push_back(new_addr); } } @@ -126,139 +133,150 @@ static device_addrs_t usrp1_find(const device_addr_t &hint) /*********************************************************************** * Make **********************************************************************/ -static device::sptr usrp1_make(const device_addr_t &device_addr){ +static device::sptr usrp1_make(const device_addr_t& device_addr) +{ return device::sptr(new usrp1_impl(device_addr)); } -UHD_STATIC_BLOCK(register_usrp1_device){ +UHD_STATIC_BLOCK(register_usrp1_device) +{ device::register_device(&usrp1_find, &usrp1_make, device::USRP); } /*********************************************************************** * Structors **********************************************************************/ -usrp1_impl::usrp1_impl(const device_addr_t &device_addr){ +usrp1_impl::usrp1_impl(const device_addr_t& device_addr) +{ UHD_LOGGER_INFO("USRP1") << "Opening a USRP1 device..."; _type = device::USRP; - //extract the FPGA path for the USRP1 - std::string usrp1_fpga_image = find_image_path( - device_addr.get("fpga", "usrp1_fpga.rbf") - ); - UHD_LOGGER_DEBUG("USRP1") << "USRP1 FPGA image: " << usrp1_fpga_image ; + // extract the FPGA path for the USRP1 + std::string usrp1_fpga_image = + find_image_path(device_addr.get("fpga", "usrp1_fpga.rbf")); + UHD_LOGGER_DEBUG("USRP1") << "USRP1 FPGA image: " << usrp1_fpga_image; - //try to match the given device address with something on the USB bus + // try to match the given device address with something on the USB bus std::vector<usb_device_handle::sptr> device_list = usb_device_handle::get_device_list(USRP1_VENDOR_ID, USRP1_PRODUCT_ID); - //locate the matching handle in the device list + // locate the matching handle in the device list usb_device_handle::sptr handle; - for(usb_device_handle::sptr dev_handle: device_list) { - if (dev_handle->get_serial() == device_addr["serial"]){ + for (usb_device_handle::sptr dev_handle : device_list) { + if (dev_handle->get_serial() == device_addr["serial"]) { handle = dev_handle; break; } } - UHD_ASSERT_THROW(handle.get() != NULL); //better be found + UHD_ASSERT_THROW(handle.get() != NULL); // better be found //////////////////////////////////////////////////////////////////// // Create controller objects //////////////////////////////////////////////////////////////////// - //usb_control::sptr usb_ctrl = usb_control::make(handle); + // usb_control::sptr usb_ctrl = usb_control::make(handle); _fx2_ctrl = fx2_ctrl::make(usb_control::make(handle, 0)); _fx2_ctrl->usrp_load_fpga(usrp1_fpga_image); _fx2_ctrl->usrp_init(); - _data_transport = usb_zero_copy::make( - handle, // identifier - 2, 6, // IN interface, endpoint - 1, 2, // OUT interface, endpoint - device_addr // param hints + _data_transport = usb_zero_copy::make(handle, // identifier + 2, + 6, // IN interface, endpoint + 1, + 2, // OUT interface, endpoint + device_addr // param hints ); - _iface = usrp1_iface::make(_fx2_ctrl); + _iface = usrp1_iface::make(_fx2_ctrl); _soft_time_ctrl = soft_time_ctrl::make( - std::bind(&usrp1_impl::rx_stream_on_off, this, std::placeholders::_1) - ); - _dbc["A"]; _dbc["B"]; //ensure that keys exist + std::bind(&usrp1_impl::rx_stream_on_off, this, std::placeholders::_1)); + _dbc["A"]; + _dbc["B"]; // ensure that keys exist // Normal mode with no loopback or Rx counting _iface->poke32(FR_MODE, 0x00000000); _iface->poke32(FR_DEBUG_EN, 0x00000000); - UHD_LOGGER_DEBUG("USRP1") - << "USRP1 Capabilities" - << " number of duc's: " << get_num_ddcs() - << " number of ddc's: " << get_num_ducs() - << " rx halfband: " << has_rx_halfband() - << " tx halfband: " << has_tx_halfband() - ; + UHD_LOGGER_DEBUG("USRP1") << "USRP1 Capabilities" + << " number of duc's: " << get_num_ddcs() + << " number of ddc's: " << get_num_ducs() + << " rx halfband: " << has_rx_halfband() + << " tx halfband: " << has_tx_halfband(); //////////////////////////////////////////////////////////////////// // Initialize the properties tree //////////////////////////////////////////////////////////////////// _rx_dc_offset_shadow = 0; - _tree = property_tree::make(); + _tree = property_tree::make(); _tree->create<std::string>("/name").set("USRP1 Device"); const fs_path mb_path = "/mboards/0"; _tree->create<std::string>(mb_path / "name").set("USRP1"); _tree->create<std::string>(mb_path / "load_eeprom") - .add_coerced_subscriber(std::bind(&fx2_ctrl::usrp_load_eeprom, _fx2_ctrl, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&fx2_ctrl::usrp_load_eeprom, _fx2_ctrl, std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // create user-defined control objects //////////////////////////////////////////////////////////////////// - _tree->create<std::pair<uint8_t, uint32_t> >(mb_path / "user" / "regs") - .add_coerced_subscriber(std::bind(&usrp1_impl::set_reg, this, std::placeholders::_1)); + _tree->create<std::pair<uint8_t, uint32_t>>(mb_path / "user" / "regs") + .add_coerced_subscriber( + std::bind(&usrp1_impl::set_reg, this, std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // setup the mboard eeprom //////////////////////////////////////////////////////////////////// - //const mboard_eeprom_t mb_eeprom(*_fx2_ctrl, USRP1_EEPROM_MAP_KEY); + // const mboard_eeprom_t mb_eeprom(*_fx2_ctrl, USRP1_EEPROM_MAP_KEY); const mboard_eeprom_t mb_eeprom = this->get_mb_eeprom(_fx2_ctrl); _tree->create<mboard_eeprom_t>(mb_path / "eeprom") .set(mb_eeprom) - .add_coerced_subscriber(std::bind(&usrp1_impl::set_mb_eeprom, this, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&usrp1_impl::set_mb_eeprom, this, std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // create clock control objects //////////////////////////////////////////////////////////////////// _master_clock_rate = 64e6; - if (device_addr.has_key("mcr")){ - try{ + if (device_addr.has_key("mcr")) { + try { _master_clock_rate = std::stod(device_addr["mcr"]); + } catch (const std::exception& e) { + UHD_LOGGER_ERROR("USRP1") + << "Error parsing FPGA clock rate from device address: " << e.what(); } - catch(const std::exception &e){ - UHD_LOGGER_ERROR("USRP1") << "Error parsing FPGA clock rate from device address: " << e.what() ; - } - } - else if (not mb_eeprom["mcr"].empty()){ - try{ + } else if (not mb_eeprom["mcr"].empty()) { + try { _master_clock_rate = std::stod(mb_eeprom["mcr"]); - } - catch(const std::exception &e){ - UHD_LOGGER_ERROR("USRP1") << "Error parsing FPGA clock rate from EEPROM: " << e.what() ; + } catch (const std::exception& e) { + UHD_LOGGER_ERROR("USRP1") + << "Error parsing FPGA clock rate from EEPROM: " << e.what(); } } - UHD_LOGGER_INFO("USRP1") << boost::format("Using FPGA clock rate of %fMHz...") % (_master_clock_rate/1e6) ; + UHD_LOGGER_INFO("USRP1") << boost::format("Using FPGA clock rate of %fMHz...") + % (_master_clock_rate / 1e6); _tree->create<double>(mb_path / "tick_rate") - .add_coerced_subscriber(std::bind(&usrp1_impl::update_tick_rate, this, std::placeholders::_1)) + .add_coerced_subscriber( + std::bind(&usrp1_impl::update_tick_rate, this, std::placeholders::_1)) .set(_master_clock_rate); //////////////////////////////////////////////////////////////////// // create codec control objects //////////////////////////////////////////////////////////////////// - for(const std::string &db: _dbc.keys()){ - _dbc[db].codec = usrp1_codec_ctrl::make(_iface, (db == "A")? SPI_ENABLE_CODEC_A : SPI_ENABLE_CODEC_B); + for (const std::string& db : _dbc.keys()) { + _dbc[db].codec = usrp1_codec_ctrl::make( + _iface, (db == "A") ? SPI_ENABLE_CODEC_A : SPI_ENABLE_CODEC_B); const fs_path rx_codec_path = mb_path / "rx_codecs" / db; const fs_path tx_codec_path = mb_path / "tx_codecs" / db; _tree->create<std::string>(rx_codec_path / "name").set("ad9522"); - _tree->create<meta_range_t>(rx_codec_path / "gains/pga/range").set(usrp1_codec_ctrl::rx_pga_gain_range); + _tree->create<meta_range_t>(rx_codec_path / "gains/pga/range") + .set(usrp1_codec_ctrl::rx_pga_gain_range); _tree->create<double>(rx_codec_path / "gains/pga/value") - .set_coercer(std::bind(&usrp1_impl::update_rx_codec_gain, this, db, std::placeholders::_1)) + .set_coercer(std::bind( + &usrp1_impl::update_rx_codec_gain, this, db, std::placeholders::_1)) .set(0.0); _tree->create<std::string>(tx_codec_path / "name").set("ad9522"); - _tree->create<meta_range_t>(tx_codec_path / "gains/pga/range").set(usrp1_codec_ctrl::tx_pga_gain_range); + _tree->create<meta_range_t>(tx_codec_path / "gains/pga/range") + .set(usrp1_codec_ctrl::tx_pga_gain_range); _tree->create<double>(tx_codec_path / "gains/pga/value") - .add_coerced_subscriber(std::bind(&usrp1_codec_ctrl::set_tx_pga_gain, _dbc[db].codec, std::placeholders::_1)) + .add_coerced_subscriber(std::bind(&usrp1_codec_ctrl::set_tx_pga_gain, + _dbc[db].codec, + std::placeholders::_1)) .set_publisher(std::bind(&usrp1_codec_ctrl::get_tx_pga_gain, _dbc[db].codec)) .set(0.0); } @@ -266,65 +284,76 @@ usrp1_impl::usrp1_impl(const device_addr_t &device_addr){ //////////////////////////////////////////////////////////////////// // and do the misc mboard sensors //////////////////////////////////////////////////////////////////// - //none for now... - _tree->create<int>(mb_path / "sensors"); //phony property so this dir exists + // none for now... + _tree->create<int>(mb_path / "sensors"); // phony property so this dir exists //////////////////////////////////////////////////////////////////// // create frontend control objects //////////////////////////////////////////////////////////////////// _tree->create<subdev_spec_t>(mb_path / "rx_subdev_spec") .set(subdev_spec_t()) - .add_coerced_subscriber(std::bind(&usrp1_impl::update_rx_subdev_spec, this, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&usrp1_impl::update_rx_subdev_spec, this, std::placeholders::_1)); _tree->create<subdev_spec_t>(mb_path / "tx_subdev_spec") .set(subdev_spec_t()) - .add_coerced_subscriber(std::bind(&usrp1_impl::update_tx_subdev_spec, this, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&usrp1_impl::update_tx_subdev_spec, this, std::placeholders::_1)); - for(const std::string &db: _dbc.keys()){ + for (const std::string& db : _dbc.keys()) { const fs_path rx_fe_path = mb_path / "rx_frontends" / db; - _tree->create<std::complex<double> >(rx_fe_path / "dc_offset" / "value") - .set_coercer(std::bind(&usrp1_impl::set_rx_dc_offset, this, db, std::placeholders::_1)) + _tree->create<std::complex<double>>(rx_fe_path / "dc_offset" / "value") + .set_coercer( + std::bind(&usrp1_impl::set_rx_dc_offset, this, db, std::placeholders::_1)) .set(std::complex<double>(0.0, 0.0)); _tree->create<bool>(rx_fe_path / "dc_offset" / "enable") - .add_coerced_subscriber(std::bind(&usrp1_impl::set_enb_rx_dc_offset, this, db, std::placeholders::_1)) + .add_coerced_subscriber(std::bind( + &usrp1_impl::set_enb_rx_dc_offset, this, db, std::placeholders::_1)) .set(true); } //////////////////////////////////////////////////////////////////// // create rx dsp control objects //////////////////////////////////////////////////////////////////// - _tree->create<int>(mb_path / "rx_dsps"); //dummy in case we have none - for (size_t dspno = 0; dspno < get_num_ddcs(); dspno++){ + _tree->create<int>(mb_path / "rx_dsps"); // dummy in case we have none + for (size_t dspno = 0; dspno < get_num_ddcs(); dspno++) { fs_path rx_dsp_path = mb_path / str(boost::format("rx_dsps/%u") % dspno); _tree->create<meta_range_t>(rx_dsp_path / "rate/range") .set_publisher(std::bind(&usrp1_impl::get_rx_dsp_host_rates, this)); _tree->create<double>(rx_dsp_path / "rate/value") - .set(1e6) //some default rate - .set_coercer(std::bind(&usrp1_impl::update_rx_samp_rate, this, dspno, std::placeholders::_1)); + .set(1e6) // some default rate + .set_coercer(std::bind( + &usrp1_impl::update_rx_samp_rate, this, dspno, std::placeholders::_1)); _tree->create<double>(rx_dsp_path / "freq/value") - .set_coercer(std::bind(&usrp1_impl::update_rx_dsp_freq, this, dspno, std::placeholders::_1)); + .set_coercer(std::bind( + &usrp1_impl::update_rx_dsp_freq, this, dspno, std::placeholders::_1)); _tree->create<meta_range_t>(rx_dsp_path / "freq/range") .set_publisher(std::bind(&usrp1_impl::get_rx_dsp_freq_range, this)); _tree->create<stream_cmd_t>(rx_dsp_path / "stream_cmd"); - if (dspno == 0){ - //only add_coerced_subscriber the callback for dspno 0 since it will stream all dsps + if (dspno == 0) { + // only add_coerced_subscriber the callback for dspno 0 since it will stream + // all dsps _tree->access<stream_cmd_t>(rx_dsp_path / "stream_cmd") - .add_coerced_subscriber(std::bind(&soft_time_ctrl::issue_stream_cmd, _soft_time_ctrl, std::placeholders::_1)); + .add_coerced_subscriber(std::bind(&soft_time_ctrl::issue_stream_cmd, + _soft_time_ctrl, + std::placeholders::_1)); } } //////////////////////////////////////////////////////////////////// // create tx dsp control objects //////////////////////////////////////////////////////////////////// - _tree->create<int>(mb_path / "tx_dsps"); //dummy in case we have none - for (size_t dspno = 0; dspno < get_num_ducs(); dspno++){ + _tree->create<int>(mb_path / "tx_dsps"); // dummy in case we have none + for (size_t dspno = 0; dspno < get_num_ducs(); dspno++) { fs_path tx_dsp_path = mb_path / str(boost::format("tx_dsps/%u") % dspno); _tree->create<meta_range_t>(tx_dsp_path / "rate/range") .set_publisher(std::bind(&usrp1_impl::get_tx_dsp_host_rates, this)); _tree->create<double>(tx_dsp_path / "rate/value") - .set(1e6) //some default rate - .set_coercer(std::bind(&usrp1_impl::update_tx_samp_rate, this, dspno, std::placeholders::_1)); + .set(1e6) // some default rate + .set_coercer(std::bind( + &usrp1_impl::update_tx_samp_rate, this, dspno, std::placeholders::_1)); _tree->create<double>(tx_dsp_path / "freq/value") - .set_coercer(std::bind(&usrp1_impl::update_tx_dsp_freq, this, dspno, std::placeholders::_1)); + .set_coercer(std::bind( + &usrp1_impl::update_tx_dsp_freq, this, dspno, std::placeholders::_1)); _tree->create<meta_range_t>(tx_dsp_path / "freq/range") .set_publisher(std::bind(&usrp1_impl::get_tx_dsp_freq_range, this)); } @@ -334,59 +363,70 @@ usrp1_impl::usrp1_impl(const device_addr_t &device_addr){ //////////////////////////////////////////////////////////////////// _tree->create<time_spec_t>(mb_path / "time/now") .set_publisher(std::bind(&soft_time_ctrl::get_time, _soft_time_ctrl)) - .add_coerced_subscriber(std::bind(&soft_time_ctrl::set_time, _soft_time_ctrl, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&soft_time_ctrl::set_time, _soft_time_ctrl, std::placeholders::_1)); - _tree->create<std::vector<std::string> >(mb_path / "clock_source/options").set(std::vector<std::string>(1, "internal")); - _tree->create<std::vector<std::string> >(mb_path / "time_source/options").set(std::vector<std::string>(1, "none")); + _tree->create<std::vector<std::string>>(mb_path / "clock_source/options") + .set(std::vector<std::string>(1, "internal")); + _tree->create<std::vector<std::string>>(mb_path / "time_source/options") + .set(std::vector<std::string>(1, "none")); _tree->create<std::string>(mb_path / "clock_source/value").set("internal"); _tree->create<std::string>(mb_path / "time_source/value").set("none"); //////////////////////////////////////////////////////////////////// // create dboard control objects //////////////////////////////////////////////////////////////////// - for(const std::string &db: _dbc.keys()){ - - //read the dboard eeprom to extract the dboard ids + for (const std::string& db : _dbc.keys()) { + // read the dboard eeprom to extract the dboard ids dboard_eeprom_t rx_db_eeprom, tx_db_eeprom, gdb_eeprom; - rx_db_eeprom.load(*_fx2_ctrl, (db == "A")? (I2C_ADDR_RX_A) : (I2C_ADDR_RX_B)); - tx_db_eeprom.load(*_fx2_ctrl, (db == "A")? (I2C_ADDR_TX_A) : (I2C_ADDR_TX_B)); - gdb_eeprom.load(*_fx2_ctrl, (db == "A")? (I2C_ADDR_TX_A ^ 5) : (I2C_ADDR_TX_B ^ 5)); - - //disable rx dc offset if LFRX - if (rx_db_eeprom.id == 0x000f) _tree->access<bool>(mb_path / "rx_frontends" / db / "dc_offset" / "enable").set(false); - - //create the properties and register subscribers - _tree->create<dboard_eeprom_t>(mb_path / "dboards" / db/ "rx_eeprom") + rx_db_eeprom.load(*_fx2_ctrl, (db == "A") ? (I2C_ADDR_RX_A) : (I2C_ADDR_RX_B)); + tx_db_eeprom.load(*_fx2_ctrl, (db == "A") ? (I2C_ADDR_TX_A) : (I2C_ADDR_TX_B)); + gdb_eeprom.load( + *_fx2_ctrl, (db == "A") ? (I2C_ADDR_TX_A ^ 5) : (I2C_ADDR_TX_B ^ 5)); + + // disable rx dc offset if LFRX + if (rx_db_eeprom.id == 0x000f) + _tree->access<bool>(mb_path / "rx_frontends" / db / "dc_offset" / "enable") + .set(false); + + // create the properties and register subscribers + _tree->create<dboard_eeprom_t>(mb_path / "dboards" / db / "rx_eeprom") .set(rx_db_eeprom) - .add_coerced_subscriber(std::bind(&usrp1_impl::set_db_eeprom, this, db, "rx", std::placeholders::_1)); - _tree->create<dboard_eeprom_t>(mb_path / "dboards" / db/ "tx_eeprom") + .add_coerced_subscriber(std::bind( + &usrp1_impl::set_db_eeprom, this, db, "rx", std::placeholders::_1)); + _tree->create<dboard_eeprom_t>(mb_path / "dboards" / db / "tx_eeprom") .set(tx_db_eeprom) - .add_coerced_subscriber(std::bind(&usrp1_impl::set_db_eeprom, this, db, "tx", std::placeholders::_1)); - _tree->create<dboard_eeprom_t>(mb_path / "dboards" / db/ "gdb_eeprom") + .add_coerced_subscriber(std::bind( + &usrp1_impl::set_db_eeprom, this, db, "tx", std::placeholders::_1)); + _tree->create<dboard_eeprom_t>(mb_path / "dboards" / db / "gdb_eeprom") .set(gdb_eeprom) - .add_coerced_subscriber(std::bind(&usrp1_impl::set_db_eeprom, this, db, "gdb", std::placeholders::_1)); - - //create a new dboard interface and manager - dboard_iface::sptr dboard_iface = make_dboard_iface( - _iface, _dbc[db].codec, - (db == "A")? DBOARD_SLOT_A : DBOARD_SLOT_B, - _master_clock_rate, rx_db_eeprom.id - ); - _dbc[db].dboard_manager = dboard_manager::make( - rx_db_eeprom.id, tx_db_eeprom.id, gdb_eeprom.id, - dboard_iface, _tree->subtree(mb_path / "dboards" / db) - ); - - //init the subdev specs if we have a dboard (wont leave this loop empty) - if (rx_db_eeprom.id != dboard_id_t::none() or _rx_subdev_spec.empty()){ - _rx_subdev_spec = subdev_spec_t(db + ":" + _tree->list(mb_path / "dboards" / db / "rx_frontends").at(0)); + .add_coerced_subscriber(std::bind( + &usrp1_impl::set_db_eeprom, this, db, "gdb", std::placeholders::_1)); + + // create a new dboard interface and manager + dboard_iface::sptr dboard_iface = make_dboard_iface(_iface, + _dbc[db].codec, + (db == "A") ? DBOARD_SLOT_A : DBOARD_SLOT_B, + _master_clock_rate, + rx_db_eeprom.id); + _dbc[db].dboard_manager = dboard_manager::make(rx_db_eeprom.id, + tx_db_eeprom.id, + gdb_eeprom.id, + dboard_iface, + _tree->subtree(mb_path / "dboards" / db)); + + // init the subdev specs if we have a dboard (wont leave this loop empty) + if (rx_db_eeprom.id != dboard_id_t::none() or _rx_subdev_spec.empty()) { + _rx_subdev_spec = subdev_spec_t( + db + ":" + _tree->list(mb_path / "dboards" / db / "rx_frontends").at(0)); } - if (tx_db_eeprom.id != dboard_id_t::none() or _tx_subdev_spec.empty()){ - _tx_subdev_spec = subdev_spec_t(db + ":" + _tree->list(mb_path / "dboards" / db / "tx_frontends").at(0)); + if (tx_db_eeprom.id != dboard_id_t::none() or _tx_subdev_spec.empty()) { + _tx_subdev_spec = subdev_spec_t( + db + ":" + _tree->list(mb_path / "dboards" / db / "tx_frontends").at(0)); } } - //initialize io handling + // initialize io handling this->io_init(); //////////////////////////////////////////////////////////////////// @@ -394,8 +434,8 @@ usrp1_impl::usrp1_impl(const device_addr_t &device_addr){ //////////////////////////////////////////////////////////////////// this->update_rates(); - //reset cordic rates and their properties to zero - for(const std::string &name: _tree->list(mb_path / "rx_dsps")){ + // reset cordic rates and their properties to zero + for (const std::string& name : _tree->list(mb_path / "rx_dsps")) { _tree->access<double>(mb_path / "rx_dsps" / name / "freq" / "value").set(0.0); } @@ -406,13 +446,11 @@ usrp1_impl::usrp1_impl(const device_addr_t &device_addr){ _tree->create<double>(mb_path / "link_max_rate").set(USRP1_MAX_RATE_USB2); } -usrp1_impl::~usrp1_impl(void){ - UHD_SAFE_CALL( - this->enable_rx(false); - this->enable_tx(false); - ) - _soft_time_ctrl->stop(); //stops cmd task before proceeding - _io_impl.reset(); //stops vandal before other stuff gets deconstructed +usrp1_impl::~usrp1_impl(void) +{ + UHD_SAFE_CALL(this->enable_rx(false); this->enable_tx(false);) + _soft_time_ctrl->stop(); // stops cmd task before proceeding + _io_impl.reset(); // stops vandal before other stuff gets deconstructed } /*! @@ -424,22 +462,26 @@ usrp1_impl::~usrp1_impl(void){ * | Reserved |T|DUCs |R|DDCs | * +-----------------------------------------------+-+-----+-+-----+ */ -size_t usrp1_impl::get_num_ddcs(void){ +size_t usrp1_impl::get_num_ddcs(void) +{ uint32_t regval = _iface->peek32(FR_RB_CAPS); return (regval >> 0) & 0x0007; } -size_t usrp1_impl::get_num_ducs(void){ +size_t usrp1_impl::get_num_ducs(void) +{ uint32_t regval = _iface->peek32(FR_RB_CAPS); return (regval >> 4) & 0x0007; } -bool usrp1_impl::has_rx_halfband(void){ +bool usrp1_impl::has_rx_halfband(void) +{ uint32_t regval = _iface->peek32(FR_RB_CAPS); return (regval >> 3) & 0x0001; } -bool usrp1_impl::has_tx_halfband(void){ +bool usrp1_impl::has_tx_halfband(void) +{ uint32_t regval = _iface->peek32(FR_RB_CAPS); return (regval >> 7) & 0x0001; } @@ -447,46 +489,59 @@ bool usrp1_impl::has_tx_halfband(void){ /*********************************************************************** * Properties callback methods below **********************************************************************/ -void usrp1_impl::set_db_eeprom(const std::string &db, const std::string &type, const uhd::usrp::dboard_eeprom_t &db_eeprom){ - if (type == "rx") db_eeprom.store(*_fx2_ctrl, (db == "A")? (I2C_ADDR_RX_A) : (I2C_ADDR_RX_B)); - if (type == "tx") db_eeprom.store(*_fx2_ctrl, (db == "A")? (I2C_ADDR_TX_A) : (I2C_ADDR_TX_B)); - if (type == "gdb") db_eeprom.store(*_fx2_ctrl, (db == "A")? (I2C_ADDR_TX_A ^ 5) : (I2C_ADDR_TX_B ^ 5)); +void usrp1_impl::set_db_eeprom(const std::string& db, + const std::string& type, + const uhd::usrp::dboard_eeprom_t& db_eeprom) +{ + if (type == "rx") + db_eeprom.store(*_fx2_ctrl, (db == "A") ? (I2C_ADDR_RX_A) : (I2C_ADDR_RX_B)); + if (type == "tx") + db_eeprom.store(*_fx2_ctrl, (db == "A") ? (I2C_ADDR_TX_A) : (I2C_ADDR_TX_B)); + if (type == "gdb") + db_eeprom.store( + *_fx2_ctrl, (db == "A") ? (I2C_ADDR_TX_A ^ 5) : (I2C_ADDR_TX_B ^ 5)); } -double usrp1_impl::update_rx_codec_gain(const std::string &db, const double gain){ - //set gain on both I and Q, readback on one - //TODO in the future, gains should have individual control +double usrp1_impl::update_rx_codec_gain(const std::string& db, const double gain) +{ + // set gain on both I and Q, readback on one + // TODO in the future, gains should have individual control _dbc[db].codec->set_rx_pga_gain(gain, 'A'); _dbc[db].codec->set_rx_pga_gain(gain, 'B'); return _dbc[db].codec->get_rx_pga_gain('A'); } -uhd::meta_range_t usrp1_impl::get_rx_dsp_freq_range(void){ - return meta_range_t(-_master_clock_rate/2, +_master_clock_rate/2); +uhd::meta_range_t usrp1_impl::get_rx_dsp_freq_range(void) +{ + return meta_range_t(-_master_clock_rate / 2, +_master_clock_rate / 2); } -uhd::meta_range_t usrp1_impl::get_tx_dsp_freq_range(void){ - //magic scalar comes from codec control: - return meta_range_t(-_master_clock_rate*0.6875, +_master_clock_rate*0.6875); +uhd::meta_range_t usrp1_impl::get_tx_dsp_freq_range(void) +{ + // magic scalar comes from codec control: + return meta_range_t(-_master_clock_rate * 0.6875, +_master_clock_rate * 0.6875); } -void usrp1_impl::set_enb_rx_dc_offset(const std::string &db, const bool enb){ - const size_t shift = (db == "A")? 0 : 2; - _rx_dc_offset_shadow &= ~(0x3 << shift); //clear bits - _rx_dc_offset_shadow |= ((enb)? 0x3 : 0x0) << shift; +void usrp1_impl::set_enb_rx_dc_offset(const std::string& db, const bool enb) +{ + const size_t shift = (db == "A") ? 0 : 2; + _rx_dc_offset_shadow &= ~(0x3 << shift); // clear bits + _rx_dc_offset_shadow |= ((enb) ? 0x3 : 0x0) << shift; _iface->poke32(FR_DC_OFFSET_CL_EN, _rx_dc_offset_shadow & 0xf); } -std::complex<double> usrp1_impl::set_rx_dc_offset(const std::string &db, const std::complex<double> &offset){ +std::complex<double> usrp1_impl::set_rx_dc_offset( + const std::string& db, const std::complex<double>& offset) +{ const int32_t i_off = boost::math::iround(offset.real() * (1ul << 31)); const int32_t q_off = boost::math::iround(offset.imag() * (1ul << 31)); - if (db == "A"){ + if (db == "A") { _iface->poke32(FR_ADC_OFFSET_0, i_off); _iface->poke32(FR_ADC_OFFSET_1, q_off); } - if (db == "B"){ + if (db == "B") { _iface->poke32(FR_ADC_OFFSET_2, i_off); _iface->poke32(FR_ADC_OFFSET_3, q_off); } @@ -494,7 +549,7 @@ std::complex<double> usrp1_impl::set_rx_dc_offset(const std::string &db, const s return std::complex<double>(double(i_off) * (1ul << 31), double(q_off) * (1ul << 31)); } -void usrp1_impl::set_reg(const std::pair<uint8_t, uint32_t> ®) +void usrp1_impl::set_reg(const std::pair<uint8_t, uint32_t>& reg) { _iface->poke32(reg.first, reg.second); } diff --git a/host/lib/usrp/usrp1/usrp1_impl.hpp b/host/lib/usrp/usrp1/usrp1_impl.hpp index 9e0a97f47..336b82baa 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.hpp +++ b/host/lib/usrp/usrp1/usrp1_impl.hpp @@ -24,79 +24,79 @@ #include <memory> #ifndef INCLUDED_USRP1_IMPL_HPP -#define INCLUDED_USRP1_IMPL_HPP +# define INCLUDED_USRP1_IMPL_HPP static const std::string USRP1_EEPROM_MAP_KEY = "B000"; -static const size_t USRP1_MAX_RATE_USB2 = 32000000; // bytes/s - -#define FR_RB_CAPS 3 -#define FR_MODE 13 -#define FR_DEBUG_EN 14 -#define FR_DC_OFFSET_CL_EN 15 -#define FR_ADC_OFFSET_0 16 -#define FR_ADC_OFFSET_1 17 -#define FR_ADC_OFFSET_2 18 -#define FR_ADC_OFFSET_3 19 - -#define I2C_DEV_EEPROM 0x50 -#define I2C_ADDR_BOOT (I2C_DEV_EEPROM | 0x0) -#define I2C_ADDR_TX_A (I2C_DEV_EEPROM | 0x4) -#define I2C_ADDR_RX_A (I2C_DEV_EEPROM | 0x5) -#define I2C_ADDR_TX_B (I2C_DEV_EEPROM | 0x6) -#define I2C_ADDR_RX_B (I2C_DEV_EEPROM | 0x7) - -#define SPI_ENABLE_CODEC_A 0x02 -#define SPI_ENABLE_CODEC_B 0x04 +static const size_t USRP1_MAX_RATE_USB2 = 32000000; // bytes/s + +# define FR_RB_CAPS 3 +# define FR_MODE 13 +# define FR_DEBUG_EN 14 +# define FR_DC_OFFSET_CL_EN 15 +# define FR_ADC_OFFSET_0 16 +# define FR_ADC_OFFSET_1 17 +# define FR_ADC_OFFSET_2 18 +# define FR_ADC_OFFSET_3 19 + +# define I2C_DEV_EEPROM 0x50 +# define I2C_ADDR_BOOT (I2C_DEV_EEPROM | 0x0) +# define I2C_ADDR_TX_A (I2C_DEV_EEPROM | 0x4) +# define I2C_ADDR_RX_A (I2C_DEV_EEPROM | 0x5) +# define I2C_ADDR_TX_B (I2C_DEV_EEPROM | 0x6) +# define I2C_ADDR_RX_B (I2C_DEV_EEPROM | 0x7) + +# define SPI_ENABLE_CODEC_A 0x02 +# define SPI_ENABLE_CODEC_B 0x04 /*! * USRP1 implementation guts: * The implementation details are encapsulated here. * Handles properties on the mboard, dboard, dsps... */ -class usrp1_impl : public uhd::device { +class usrp1_impl : public uhd::device +{ public: //! used everywhere to differentiate slots/sides... - enum dboard_slot_t{ - DBOARD_SLOT_A = 'A', - DBOARD_SLOT_B = 'B' - }; - //and a way to enumerate through a list of the above... + enum dboard_slot_t { DBOARD_SLOT_A = 'A', DBOARD_SLOT_B = 'B' }; + // and a way to enumerate through a list of the above... static const std::vector<dboard_slot_t> _dboard_slots; - //structors - usrp1_impl(const uhd::device_addr_t &); + // structors + usrp1_impl(const uhd::device_addr_t&); ~usrp1_impl(void); - //the io interface - uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t &args); - uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t &args); - bool recv_async_msg(uhd::async_metadata_t &, double); + // the io interface + uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t& args); + uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t& args); + bool recv_async_msg(uhd::async_metadata_t&, double); static uhd::usrp::mboard_eeprom_t get_mb_eeprom(uhd::i2c_iface::sptr); private: - //controllers + // controllers uhd::usrp::fx2_ctrl::sptr _fx2_ctrl; usrp1_iface::sptr _iface; uhd::usrp::soft_time_ctrl::sptr _soft_time_ctrl; uhd::transport::usb_zero_copy::sptr _data_transport; - struct db_container_type{ + struct db_container_type + { usrp1_codec_ctrl::sptr codec; uhd::usrp::dboard_manager::sptr dboard_manager; }; uhd::dict<std::string, db_container_type> _dbc; - double _master_clock_rate; //clock rate shadow + double _master_clock_rate; // clock rate shadow - //weak pointers to streamers for update purposes + // weak pointers to streamers for update purposes std::weak_ptr<uhd::rx_streamer> _rx_streamer; std::weak_ptr<uhd::tx_streamer> _tx_streamer; - void set_mb_eeprom(const uhd::usrp::mboard_eeprom_t &); - void set_db_eeprom(const std::string &, const std::string &, const uhd::usrp::dboard_eeprom_t &); - double update_rx_codec_gain(const std::string &, const double); //sets A and B at once - void update_rx_subdev_spec(const uhd::usrp::subdev_spec_t &); - void update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &); + void set_mb_eeprom(const uhd::usrp::mboard_eeprom_t&); + void set_db_eeprom( + const std::string&, const std::string&, const uhd::usrp::dboard_eeprom_t&); + double update_rx_codec_gain(const std::string&, const double); // sets A and B at once + void update_rx_subdev_spec(const uhd::usrp::subdev_spec_t&); + void update_tx_subdev_spec(const uhd::usrp::subdev_spec_t&); double update_rx_samp_rate(size_t dspno, const double); double update_tx_samp_rate(size_t dspno, const double); void update_rates(void); @@ -108,76 +108,80 @@ private: uhd::meta_range_t get_rx_dsp_host_rates(void); uhd::meta_range_t get_tx_dsp_host_rates(void); size_t _rx_dc_offset_shadow; - void set_enb_rx_dc_offset(const std::string &db, const bool); - std::complex<double> set_rx_dc_offset(const std::string &db, const std::complex<double> &); + void set_enb_rx_dc_offset(const std::string& db, const bool); + std::complex<double> set_rx_dc_offset( + const std::string& db, const std::complex<double>&); - static uhd::usrp::dboard_iface::sptr make_dboard_iface( - usrp1_iface::sptr, + static uhd::usrp::dboard_iface::sptr make_dboard_iface(usrp1_iface::sptr, usrp1_codec_ctrl::sptr, dboard_slot_t, - const double &, - const uhd::usrp::dboard_id_t & - ); + const double&, + const uhd::usrp::dboard_id_t&); - //handle io stuff + // handle io stuff UHD_PIMPL_DECL(io_impl) _io_impl; void io_init(void); void rx_stream_on_off(bool); void tx_stream_on_off(bool); void handle_overrun(size_t); - //channel mapping shadows + // channel mapping shadows uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec; - //capabilities + // capabilities size_t get_num_ducs(void); size_t get_num_ddcs(void); bool has_rx_halfband(void); bool has_tx_halfband(void); - void vandal_conquest_loop(std::atomic<bool> &); + void vandal_conquest_loop(std::atomic<bool>&); - void set_reg(const std::pair<uint8_t, uint32_t> ®); + void set_reg(const std::pair<uint8_t, uint32_t>& reg); - //handle the enables + // handle the enables bool _rx_enabled, _tx_enabled; - void enable_rx(bool enb){ + void enable_rx(bool enb) + { _rx_enabled = enb; _fx2_ctrl->usrp_rx_enable(enb); } - void enable_tx(bool enb){ + void enable_tx(bool enb) + { _tx_enabled = enb; _fx2_ctrl->usrp_tx_enable(enb); - for(const std::string &key: _dbc.keys()) - { + for (const std::string& key : _dbc.keys()) { _dbc[key].codec->enable_tx_digital(enb); } } - //conditionally disable and enable rx - bool disable_rx(void){ - if (_rx_enabled){ + // conditionally disable and enable rx + bool disable_rx(void) + { + if (_rx_enabled) { enable_rx(false); return true; } return false; } - void restore_rx(bool last){ - if (last != _rx_enabled){ + void restore_rx(bool last) + { + if (last != _rx_enabled) { enable_rx(last); } } - //conditionally disable and enable tx - bool disable_tx(void){ - if (_tx_enabled){ + // conditionally disable and enable tx + bool disable_tx(void) + { + if (_tx_enabled) { enable_tx(false); return true; } return false; } - void restore_tx(bool last){ - if (last != _tx_enabled){ + void restore_tx(bool last) + { + if (last != _tx_enabled) { enable_tx(last); } } diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp index 40f7c75f6..19a7fc1c5 100644 --- a/host/lib/usrp/usrp2/clock_ctrl.cpp +++ b/host/lib/usrp/usrp2/clock_ctrl.cpp @@ -8,10 +8,10 @@ #include "clock_ctrl.hpp" #include "ad9510_regs.hpp" -#include "usrp2_regs.hpp" //spi slave constants #include "usrp2_clk_regs.hpp" -#include <uhd/utils/safe_call.hpp> +#include "usrp2_regs.hpp" //spi slave constants #include <uhd/utils/assert_has.hpp> +#include <uhd/utils/safe_call.hpp> #include <uhdlib/utils/narrow.hpp> #include <stdint.h> #include <boost/math/special_functions/round.hpp> @@ -21,17 +21,20 @@ using namespace uhd; static const bool enb_test_clk = false; -usrp2_clock_ctrl::~usrp2_clock_ctrl(void){ +usrp2_clock_ctrl::~usrp2_clock_ctrl(void) +{ /* NOP */ } /*! * A usrp2 clock control specific to the ad9510 ic. */ -class usrp2_clock_ctrl_impl : public usrp2_clock_ctrl{ +class usrp2_clock_ctrl_impl : public usrp2_clock_ctrl +{ public: - usrp2_clock_ctrl_impl(usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface){ - _iface = iface; + usrp2_clock_ctrl_impl(usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface) + { + _iface = iface; _spiface = spiface; clk_regs = usrp2_clk_regs_t(_iface->get_rev()); @@ -44,7 +47,7 @@ public: // But why not leave it in for those who want to mess with clock settings? // 100mhz = 10mhz/R * (P*B + A) - _ad9510_regs.pll_power_down = ad9510_regs_t::PLL_POWER_DOWN_NORMAL; + _ad9510_regs.pll_power_down = ad9510_regs_t::PLL_POWER_DOWN_NORMAL; _ad9510_regs.prescaler_value = ad9510_regs_t::PRESCALER_VALUE_DIV2; this->write_reg(clk_regs.pll_4); @@ -74,181 +77,213 @@ public: this->enable_test_clock(enb_test_clk); } - ~usrp2_clock_ctrl_impl(void){UHD_SAFE_CALL( - //power down clock outputs - this->enable_external_ref(false); - this->enable_rx_dboard_clock(false); - this->enable_tx_dboard_clock(false); - this->enable_dac_clock(false); - this->enable_adc_clock(false); - this->enable_mimo_clock_out(false); - this->enable_test_clock(false); - )} - - void enable_mimo_clock_out(bool enb){ - //calculate the low and high dividers - size_t divider = size_t(this->get_master_clock_rate()/10e6); - size_t high = divider/2; - size_t low = divider - high; - - switch(clk_regs.exp){ - case 2: //U2 rev 3 - _ad9510_regs.power_down_lvpecl_out2 = enb? - ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_NORMAL : - ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_SAFE_PD; - _ad9510_regs.output_level_lvpecl_out2 = ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT2_810MV; - //set the registers (divider - 1) - _ad9510_regs.divider_low_cycles_out2 = uhd::narrow_cast<uint8_t>(low - 1); - _ad9510_regs.divider_high_cycles_out2 = uhd::narrow_cast<uint8_t>(high - 1); - _ad9510_regs.bypass_divider_out2 = 0; - break; - - case 5: //U2 rev 4 - _ad9510_regs.power_down_lvds_cmos_out5 = enb? 0 : 1; - _ad9510_regs.lvds_cmos_select_out5 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT5_LVDS; - _ad9510_regs.output_level_lvds_out5 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT5_1_75MA; - //set the registers (divider - 1) - _ad9510_regs.divider_low_cycles_out5 = uhd::narrow_cast<uint8_t>(low - 1); - _ad9510_regs.divider_high_cycles_out5 = uhd::narrow_cast<uint8_t>(high - 1); - _ad9510_regs.bypass_divider_out5 = 0; - break; - - case 6: //U2+ - _ad9510_regs.power_down_lvds_cmos_out6 = enb? 0 : 1; - _ad9510_regs.lvds_cmos_select_out6 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT6_LVDS; - _ad9510_regs.output_level_lvds_out6 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT6_1_75MA; - //set the registers (divider - 1) - _ad9510_regs.divider_low_cycles_out6 = uhd::narrow_cast<uint8_t>(low - 1); - _ad9510_regs.divider_high_cycles_out6 = uhd::narrow_cast<uint8_t>(high - 1); - _ad9510_regs.bypass_divider_out5 = 0; - break; - - default: - break; + ~usrp2_clock_ctrl_impl(void) + { + UHD_SAFE_CALL( + // power down clock outputs + this->enable_external_ref(false); this->enable_rx_dboard_clock(false); + this->enable_tx_dboard_clock(false); + this->enable_dac_clock(false); + this->enable_adc_clock(false); + this->enable_mimo_clock_out(false); + this->enable_test_clock(false);) + } + + void enable_mimo_clock_out(bool enb) + { + // calculate the low and high dividers + size_t divider = size_t(this->get_master_clock_rate() / 10e6); + size_t high = divider / 2; + size_t low = divider - high; + + switch (clk_regs.exp) { + case 2: // U2 rev 3 + _ad9510_regs.power_down_lvpecl_out2 = + enb ? ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_NORMAL + : ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_SAFE_PD; + _ad9510_regs.output_level_lvpecl_out2 = + ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT2_810MV; + // set the registers (divider - 1) + _ad9510_regs.divider_low_cycles_out2 = uhd::narrow_cast<uint8_t>(low - 1); + _ad9510_regs.divider_high_cycles_out2 = + uhd::narrow_cast<uint8_t>(high - 1); + _ad9510_regs.bypass_divider_out2 = 0; + break; + + case 5: // U2 rev 4 + _ad9510_regs.power_down_lvds_cmos_out5 = enb ? 0 : 1; + _ad9510_regs.lvds_cmos_select_out5 = + ad9510_regs_t::LVDS_CMOS_SELECT_OUT5_LVDS; + _ad9510_regs.output_level_lvds_out5 = + ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT5_1_75MA; + // set the registers (divider - 1) + _ad9510_regs.divider_low_cycles_out5 = uhd::narrow_cast<uint8_t>(low - 1); + _ad9510_regs.divider_high_cycles_out5 = + uhd::narrow_cast<uint8_t>(high - 1); + _ad9510_regs.bypass_divider_out5 = 0; + break; + + case 6: // U2+ + _ad9510_regs.power_down_lvds_cmos_out6 = enb ? 0 : 1; + _ad9510_regs.lvds_cmos_select_out6 = + ad9510_regs_t::LVDS_CMOS_SELECT_OUT6_LVDS; + _ad9510_regs.output_level_lvds_out6 = + ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT6_1_75MA; + // set the registers (divider - 1) + _ad9510_regs.divider_low_cycles_out6 = uhd::narrow_cast<uint8_t>(low - 1); + _ad9510_regs.divider_high_cycles_out6 = + uhd::narrow_cast<uint8_t>(high - 1); + _ad9510_regs.bypass_divider_out5 = 0; + break; + + default: + break; } this->write_reg(clk_regs.output(clk_regs.exp)); this->write_reg(clk_regs.div_lo(clk_regs.exp)); this->update_regs(); } - //uses output clock 7 (cmos) - void enable_rx_dboard_clock(bool enb){ - switch(_iface->get_rev()) { + // uses output clock 7 (cmos) + void enable_rx_dboard_clock(bool enb) + { + switch (_iface->get_rev()) { case usrp2_iface::USRP_N200_R4: case usrp2_iface::USRP_N210_R4: - _ad9510_regs.power_down_lvds_cmos_out7 = enb? 0 : 1; - _ad9510_regs.lvds_cmos_select_out7 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT7_LVDS; - _ad9510_regs.output_level_lvds_out7 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT7_1_75MA; + _ad9510_regs.power_down_lvds_cmos_out7 = enb ? 0 : 1; + _ad9510_regs.lvds_cmos_select_out7 = + ad9510_regs_t::LVDS_CMOS_SELECT_OUT7_LVDS; + _ad9510_regs.output_level_lvds_out7 = + ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT7_1_75MA; this->write_reg(clk_regs.output(clk_regs.rx_db)); this->update_regs(); break; default: - _ad9510_regs.power_down_lvds_cmos_out7 = enb? 0 : 1; - _ad9510_regs.lvds_cmos_select_out7 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT7_CMOS; - _ad9510_regs.output_level_lvds_out7 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT7_1_75MA; + _ad9510_regs.power_down_lvds_cmos_out7 = enb ? 0 : 1; + _ad9510_regs.lvds_cmos_select_out7 = + ad9510_regs_t::LVDS_CMOS_SELECT_OUT7_CMOS; + _ad9510_regs.output_level_lvds_out7 = + ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT7_1_75MA; this->write_reg(clk_regs.output(clk_regs.rx_db)); this->update_regs(); break; } } - void set_rate_rx_dboard_clock(double rate){ + void set_rate_rx_dboard_clock(double rate) + { assert_has(get_rates_rx_dboard_clock(), rate, "rx dboard clock rate"); - size_t divider = size_t(get_master_clock_rate()/rate); - //bypass when the divider ratio is one - _ad9510_regs.bypass_divider_out7 = (divider == 1)? 1 : 0; - //calculate the low and high dividers - size_t high = divider/2; - size_t low = divider - high; - //set the registers (divider - 1) - _ad9510_regs.divider_low_cycles_out7 = uhd::narrow_cast<uint8_t>(low - 1); + size_t divider = size_t(get_master_clock_rate() / rate); + // bypass when the divider ratio is one + _ad9510_regs.bypass_divider_out7 = (divider == 1) ? 1 : 0; + // calculate the low and high dividers + size_t high = divider / 2; + size_t low = divider - high; + // set the registers (divider - 1) + _ad9510_regs.divider_low_cycles_out7 = uhd::narrow_cast<uint8_t>(low - 1); _ad9510_regs.divider_high_cycles_out7 = uhd::narrow_cast<uint8_t>(high - 1); - //write the registers + // write the registers this->write_reg(clk_regs.div_lo(clk_regs.rx_db)); this->write_reg(clk_regs.div_hi(clk_regs.rx_db)); this->update_regs(); } - std::vector<double> get_rates_rx_dboard_clock(void){ + std::vector<double> get_rates_rx_dboard_clock(void) + { std::vector<double> rates; - for (size_t i = 1; i <= 16+16; i++) rates.push_back(get_master_clock_rate()/i); + for (size_t i = 1; i <= 16 + 16; i++) + rates.push_back(get_master_clock_rate() / i); return rates; } - //uses output clock 6 (cmos) on USRP2, output clock 5 (cmos) on N200/N210 r3, - //and output clock 5 (lvds) on N200/N210 r4 - void enable_tx_dboard_clock(bool enb){ - switch(_iface->get_rev()) { - case usrp2_iface::USRP_N200_R4: - case usrp2_iface::USRP_N210_R4: - _ad9510_regs.power_down_lvds_cmos_out5 = enb? 0 : 1; - _ad9510_regs.lvds_cmos_select_out5 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT5_LVDS; - _ad9510_regs.output_level_lvds_out5 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT5_1_75MA; - break; - case usrp2_iface::USRP_N200: - case usrp2_iface::USRP_N210: - _ad9510_regs.power_down_lvds_cmos_out5 = enb? 0 : 1; - _ad9510_regs.lvds_cmos_select_out5 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT5_CMOS; - _ad9510_regs.output_level_lvds_out5 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT5_1_75MA; - break; - case usrp2_iface::USRP2_REV3: - case usrp2_iface::USRP2_REV4: - _ad9510_regs.power_down_lvds_cmos_out6 = enb? 0 : 1; - _ad9510_regs.lvds_cmos_select_out6 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT6_CMOS; - _ad9510_regs.output_level_lvds_out6 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT6_1_75MA; - break; - - default: - //throw uhd::not_implemented_error("enable_tx_dboard_clock: unknown hardware version"); - break; + // uses output clock 6 (cmos) on USRP2, output clock 5 (cmos) on N200/N210 r3, + // and output clock 5 (lvds) on N200/N210 r4 + void enable_tx_dboard_clock(bool enb) + { + switch (_iface->get_rev()) { + case usrp2_iface::USRP_N200_R4: + case usrp2_iface::USRP_N210_R4: + _ad9510_regs.power_down_lvds_cmos_out5 = enb ? 0 : 1; + _ad9510_regs.lvds_cmos_select_out5 = + ad9510_regs_t::LVDS_CMOS_SELECT_OUT5_LVDS; + _ad9510_regs.output_level_lvds_out5 = + ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT5_1_75MA; + break; + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + _ad9510_regs.power_down_lvds_cmos_out5 = enb ? 0 : 1; + _ad9510_regs.lvds_cmos_select_out5 = + ad9510_regs_t::LVDS_CMOS_SELECT_OUT5_CMOS; + _ad9510_regs.output_level_lvds_out5 = + ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT5_1_75MA; + break; + case usrp2_iface::USRP2_REV3: + case usrp2_iface::USRP2_REV4: + _ad9510_regs.power_down_lvds_cmos_out6 = enb ? 0 : 1; + _ad9510_regs.lvds_cmos_select_out6 = + ad9510_regs_t::LVDS_CMOS_SELECT_OUT6_CMOS; + _ad9510_regs.output_level_lvds_out6 = + ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT6_1_75MA; + break; + + default: + // throw uhd::not_implemented_error("enable_tx_dboard_clock: unknown + // hardware version"); + break; } this->write_reg(clk_regs.output(clk_regs.tx_db)); this->update_regs(); } - void set_rate_tx_dboard_clock(double rate){ + void set_rate_tx_dboard_clock(double rate) + { assert_has(get_rates_tx_dboard_clock(), rate, "tx dboard clock rate"); - size_t divider = size_t(get_master_clock_rate()/rate); - //bypass when the divider ratio is one - _ad9510_regs.bypass_divider_out6 = (divider == 1)? 1 : 0; - //calculate the low and high dividers - size_t high = divider/2; - size_t low = divider - high; - - switch(clk_regs.tx_db) { - case 5: //USRP2+ - _ad9510_regs.bypass_divider_out5 = (divider == 1)? 1 : 0; - _ad9510_regs.divider_low_cycles_out5 = uhd::narrow_cast<uint8_t>(low - 1); - _ad9510_regs.divider_high_cycles_out5 = uhd::narrow_cast<uint8_t>(high - 1); - break; - case 6: //USRP2 - //bypass when the divider ratio is one - _ad9510_regs.bypass_divider_out6 = (divider == 1)? 1 : 0; - //set the registers (divider - 1) - _ad9510_regs.divider_low_cycles_out6 = uhd::narrow_cast<uint8_t>(low - 1); - _ad9510_regs.divider_high_cycles_out6 = uhd::narrow_cast<uint8_t>(high - 1); - break; + size_t divider = size_t(get_master_clock_rate() / rate); + // bypass when the divider ratio is one + _ad9510_regs.bypass_divider_out6 = (divider == 1) ? 1 : 0; + // calculate the low and high dividers + size_t high = divider / 2; + size_t low = divider - high; + + switch (clk_regs.tx_db) { + case 5: // USRP2+ + _ad9510_regs.bypass_divider_out5 = (divider == 1) ? 1 : 0; + _ad9510_regs.divider_low_cycles_out5 = uhd::narrow_cast<uint8_t>(low - 1); + _ad9510_regs.divider_high_cycles_out5 = + uhd::narrow_cast<uint8_t>(high - 1); + break; + case 6: // USRP2 + // bypass when the divider ratio is one + _ad9510_regs.bypass_divider_out6 = (divider == 1) ? 1 : 0; + // set the registers (divider - 1) + _ad9510_regs.divider_low_cycles_out6 = uhd::narrow_cast<uint8_t>(low - 1); + _ad9510_regs.divider_high_cycles_out6 = + uhd::narrow_cast<uint8_t>(high - 1); + break; } - //write the registers + // write the registers this->write_reg(clk_regs.div_hi(clk_regs.tx_db)); this->write_reg(clk_regs.div_lo(clk_regs.tx_db)); this->update_regs(); } - std::vector<double> get_rates_tx_dboard_clock(void){ - return get_rates_rx_dboard_clock(); //same master clock, same dividers... + std::vector<double> get_rates_tx_dboard_clock(void) + { + return get_rates_rx_dboard_clock(); // same master clock, same dividers... } - - void enable_test_clock(bool enb) { - _ad9510_regs.power_down_lvpecl_out0 = enb? - ad9510_regs_t::POWER_DOWN_LVPECL_OUT0_NORMAL : - ad9510_regs_t::POWER_DOWN_LVPECL_OUT0_SAFE_PD; - _ad9510_regs.output_level_lvpecl_out0 = ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT0_810MV; - _ad9510_regs.divider_low_cycles_out0 = 0; + + void enable_test_clock(bool enb) + { + _ad9510_regs.power_down_lvpecl_out0 = + enb ? ad9510_regs_t::POWER_DOWN_LVPECL_OUT0_NORMAL + : ad9510_regs_t::POWER_DOWN_LVPECL_OUT0_SAFE_PD; + _ad9510_regs.output_level_lvpecl_out0 = + ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT0_810MV; + _ad9510_regs.divider_low_cycles_out0 = 0; _ad9510_regs.divider_high_cycles_out0 = 0; - _ad9510_regs.bypass_divider_out0 = 1; + _ad9510_regs.bypass_divider_out0 = 1; this->write_reg(0x3c); this->write_reg(0x48); this->write_reg(0x49); @@ -258,64 +293,69 @@ public: * If we are to use an external reference, enable the charge pump. * \param enb true to enable the CP */ - void enable_external_ref(bool enb){ - _ad9510_regs.charge_pump_mode = (enb)? - ad9510_regs_t::CHARGE_PUMP_MODE_NORMAL : - ad9510_regs_t::CHARGE_PUMP_MODE_3STATE ; + void enable_external_ref(bool enb) + { + _ad9510_regs.charge_pump_mode = (enb) ? ad9510_regs_t::CHARGE_PUMP_MODE_NORMAL + : ad9510_regs_t::CHARGE_PUMP_MODE_3STATE; _ad9510_regs.pll_mux_control = ad9510_regs_t::PLL_MUX_CONTROL_DLD_HIGH; - _ad9510_regs.pfd_polarity = ad9510_regs_t::PFD_POLARITY_POS; + _ad9510_regs.pfd_polarity = ad9510_regs_t::PFD_POLARITY_POS; this->write_reg(clk_regs.pll_2); this->update_regs(); } - double get_master_clock_rate(void){ + double get_master_clock_rate(void) + { return 100e6; } - - void set_mimo_clock_delay(double delay) { - //delay_val is a 5-bit value (0-31) for fine control - //the equations below determine delay for a given ramp current, # of caps and fine delay register - //delay range: - //range_ns = 200*((caps+3)/i_ramp_ua)*1.3286 - //offset (zero delay): - //offset_ns = 0.34 + (1600 - i_ramp_ua)*1e-4 + ((caps-1)/ramp)*6 - //delay_ns = offset_ns + range_ns * delay / 31 - - int delay_val = boost::math::iround(delay/9.744e-9*31); - - if(delay_val == 0) { - switch(clk_regs.exp) { - case 5: - _ad9510_regs.delay_control_out5 = 1; - break; - case 6: - _ad9510_regs.delay_control_out6 = 1; - break; - default: - break; //delay not supported on U2 rev 3 + + void set_mimo_clock_delay(double delay) + { + // delay_val is a 5-bit value (0-31) for fine control + // the equations below determine delay for a given ramp current, # of caps and + // fine delay register delay range: range_ns = 200*((caps+3)/i_ramp_ua)*1.3286 + // offset (zero delay): + // offset_ns = 0.34 + (1600 - i_ramp_ua)*1e-4 + ((caps-1)/ramp)*6 + // delay_ns = offset_ns + range_ns * delay / 31 + + int delay_val = boost::math::iround(delay / 9.744e-9 * 31); + + if (delay_val == 0) { + switch (clk_regs.exp) { + case 5: + _ad9510_regs.delay_control_out5 = 1; + break; + case 6: + _ad9510_regs.delay_control_out6 = 1; + break; + default: + break; // delay not supported on U2 rev 3 } } else { - switch(clk_regs.exp) { - case 5: - _ad9510_regs.delay_control_out5 = 0; - _ad9510_regs.ramp_current_out5 = ad9510_regs_t::RAMP_CURRENT_OUT5_200UA; - _ad9510_regs.ramp_capacitor_out5 = ad9510_regs_t::RAMP_CAPACITOR_OUT5_4CAPS; - _ad9510_regs.delay_fine_adjust_out5 = delay_val; - this->write_reg(0x34); - this->write_reg(0x35); - this->write_reg(0x36); - break; - case 6: - _ad9510_regs.delay_control_out6 = 0; - _ad9510_regs.ramp_current_out6 = ad9510_regs_t::RAMP_CURRENT_OUT6_200UA; - _ad9510_regs.ramp_capacitor_out6 = ad9510_regs_t::RAMP_CAPACITOR_OUT6_4CAPS; - _ad9510_regs.delay_fine_adjust_out6 = delay_val; - this->write_reg(0x38); - this->write_reg(0x39); - this->write_reg(0x3A); - break; - default: - break; + switch (clk_regs.exp) { + case 5: + _ad9510_regs.delay_control_out5 = 0; + _ad9510_regs.ramp_current_out5 = + ad9510_regs_t::RAMP_CURRENT_OUT5_200UA; + _ad9510_regs.ramp_capacitor_out5 = + ad9510_regs_t::RAMP_CAPACITOR_OUT5_4CAPS; + _ad9510_regs.delay_fine_adjust_out5 = delay_val; + this->write_reg(0x34); + this->write_reg(0x35); + this->write_reg(0x36); + break; + case 6: + _ad9510_regs.delay_control_out6 = 0; + _ad9510_regs.ramp_current_out6 = + ad9510_regs_t::RAMP_CURRENT_OUT6_200UA; + _ad9510_regs.ramp_capacitor_out6 = + ad9510_regs_t::RAMP_CAPACITOR_OUT6_4CAPS; + _ad9510_regs.delay_fine_adjust_out6 = delay_val; + this->write_reg(0x38); + this->write_reg(0x39); + this->write_reg(0x3A); + break; + default: + break; } } } @@ -325,7 +365,8 @@ private: * Write a single register to the spi regs. * \param addr the address to write */ - void write_reg(uint8_t addr){ + void write_reg(uint8_t addr) + { uint32_t data = _ad9510_regs.get_write_reg(addr); _spiface->write_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, data, 24); } @@ -333,45 +374,54 @@ private: /*! * Tells the ad9510 to latch the settings into the operational registers. */ - void update_regs(void){ + void update_regs(void) + { _ad9510_regs.update_registers = 1; this->write_reg(clk_regs.update); } - //uses output clock 3 (pecl) - //this is the same between USRP2 and USRP2+ and doesn't get a switch statement - void enable_dac_clock(bool enb){ - _ad9510_regs.power_down_lvpecl_out3 = (enb)? - ad9510_regs_t::POWER_DOWN_LVPECL_OUT3_NORMAL : - ad9510_regs_t::POWER_DOWN_LVPECL_OUT3_SAFE_PD; - _ad9510_regs.output_level_lvpecl_out3 = ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT3_810MV; + // uses output clock 3 (pecl) + // this is the same between USRP2 and USRP2+ and doesn't get a switch statement + void enable_dac_clock(bool enb) + { + _ad9510_regs.power_down_lvpecl_out3 = + (enb) ? ad9510_regs_t::POWER_DOWN_LVPECL_OUT3_NORMAL + : ad9510_regs_t::POWER_DOWN_LVPECL_OUT3_SAFE_PD; + _ad9510_regs.output_level_lvpecl_out3 = + ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT3_810MV; _ad9510_regs.bypass_divider_out3 = 1; this->write_reg(clk_regs.output(clk_regs.dac)); this->write_reg(clk_regs.div_hi(clk_regs.dac)); this->update_regs(); } - //uses output clock 4 (lvds) on USRP2 and output clock 2 (lvpecl) on USRP2+ - void enable_adc_clock(bool enb){ - switch(clk_regs.adc) { - case 2: - _ad9510_regs.power_down_lvpecl_out2 = enb? ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_NORMAL : ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_SAFE_PD; - _ad9510_regs.output_level_lvpecl_out2 = ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT2_500MV; - _ad9510_regs.bypass_divider_out2 = 1; - break; - case 4: - _ad9510_regs.power_down_lvds_cmos_out4 = enb? 0 : 1; - _ad9510_regs.lvds_cmos_select_out4 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT4_LVDS; - _ad9510_regs.output_level_lvds_out4 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT4_1_75MA; - _ad9510_regs.bypass_divider_out4 = 1; - break; + // uses output clock 4 (lvds) on USRP2 and output clock 2 (lvpecl) on USRP2+ + void enable_adc_clock(bool enb) + { + switch (clk_regs.adc) { + case 2: + _ad9510_regs.power_down_lvpecl_out2 = + enb ? ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_NORMAL + : ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_SAFE_PD; + _ad9510_regs.output_level_lvpecl_out2 = + ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT2_500MV; + _ad9510_regs.bypass_divider_out2 = 1; + break; + case 4: + _ad9510_regs.power_down_lvds_cmos_out4 = enb ? 0 : 1; + _ad9510_regs.lvds_cmos_select_out4 = + ad9510_regs_t::LVDS_CMOS_SELECT_OUT4_LVDS; + _ad9510_regs.output_level_lvds_out4 = + ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT4_1_75MA; + _ad9510_regs.bypass_divider_out4 = 1; + break; } this->write_reg(clk_regs.output(clk_regs.adc)); this->write_reg(clk_regs.div_hi(clk_regs.adc)); this->update_regs(); } - + usrp2_iface::sptr _iface; uhd::spi_iface::sptr _spiface; usrp2_clk_regs_t clk_regs; @@ -381,6 +431,8 @@ private: /*********************************************************************** * Public make function for the ad9510 clock control **********************************************************************/ -usrp2_clock_ctrl::sptr usrp2_clock_ctrl::make(usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface){ +usrp2_clock_ctrl::sptr usrp2_clock_ctrl::make( + usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface) +{ return sptr(new usrp2_clock_ctrl_impl(iface, spiface)); } diff --git a/host/lib/usrp/usrp2/clock_ctrl.hpp b/host/lib/usrp/usrp2/clock_ctrl.hpp index b82dd4723..d1e8ee551 100644 --- a/host/lib/usrp/usrp2/clock_ctrl.hpp +++ b/host/lib/usrp/usrp2/clock_ctrl.hpp @@ -13,7 +13,8 @@ #include <memory> #include <vector> -class usrp2_clock_ctrl : uhd::noncopyable{ +class usrp2_clock_ctrl : uhd::noncopyable +{ public: typedef std::shared_ptr<usrp2_clock_ctrl> sptr; @@ -76,7 +77,7 @@ public: * \param enb true to enable */ virtual void enable_external_ref(bool enb) = 0; - + /*! * Enable/disable test clock output. * \param enb true to enable @@ -88,7 +89,7 @@ public: * \param enb true to enable */ virtual void enable_mimo_clock_out(bool enb) = 0; - + /*! * Set the output delay of the mimo clock * Used to synchronise daisy-chained USRPs over the MIMO cable @@ -96,7 +97,6 @@ public: * \param delay the clock delay in seconds */ virtual void set_mimo_clock_delay(double delay) = 0; - }; #endif /* INCLUDED_CLOCK_CTRL_HPP */ diff --git a/host/lib/usrp/usrp2/codec_ctrl.cpp b/host/lib/usrp/usrp2/codec_ctrl.cpp index 88f6007e8..6fe91da9e 100644 --- a/host/lib/usrp/usrp2/codec_ctrl.cpp +++ b/host/lib/usrp/usrp2/codec_ctrl.cpp @@ -9,173 +9,197 @@ #include "ad9777_regs.hpp" #include "ads62p44_regs.hpp" #include "usrp2_regs.hpp" +#include <uhd/exception.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/safe_call.hpp> -#include <uhd/exception.hpp> #include <stdint.h> using namespace uhd; -usrp2_codec_ctrl::~usrp2_codec_ctrl(void){ +usrp2_codec_ctrl::~usrp2_codec_ctrl(void) +{ /* NOP */ } /*! * A usrp2 codec control specific to the ad9777 ic. */ -class usrp2_codec_ctrl_impl : public usrp2_codec_ctrl{ +class usrp2_codec_ctrl_impl : public usrp2_codec_ctrl +{ public: - usrp2_codec_ctrl_impl(usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface){ - _iface = iface; + usrp2_codec_ctrl_impl(usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface) + { + _iface = iface; _spiface = spiface; - //setup the ad9777 dac - _ad9777_regs.x_1r_2r_mode = ad9777_regs_t::X_1R_2R_MODE_1R; + // setup the ad9777 dac + _ad9777_regs.x_1r_2r_mode = ad9777_regs_t::X_1R_2R_MODE_1R; _ad9777_regs.filter_interp_rate = ad9777_regs_t::FILTER_INTERP_RATE_4X; - _ad9777_regs.mix_mode = ad9777_regs_t::MIX_MODE_COMPLEX; - _ad9777_regs.pll_divide_ratio = ad9777_regs_t::PLL_DIVIDE_RATIO_DIV1; - _ad9777_regs.pll_state = ad9777_regs_t::PLL_STATE_ON; - _ad9777_regs.auto_cp_control = ad9777_regs_t::AUTO_CP_CONTROL_AUTO; - //I dac values - _ad9777_regs.idac_fine_gain_adjust = 0; + _ad9777_regs.mix_mode = ad9777_regs_t::MIX_MODE_COMPLEX; + _ad9777_regs.pll_divide_ratio = ad9777_regs_t::PLL_DIVIDE_RATIO_DIV1; + _ad9777_regs.pll_state = ad9777_regs_t::PLL_STATE_ON; + _ad9777_regs.auto_cp_control = ad9777_regs_t::AUTO_CP_CONTROL_AUTO; + // I dac values + _ad9777_regs.idac_fine_gain_adjust = 0; _ad9777_regs.idac_coarse_gain_adjust = 0xf; - _ad9777_regs.idac_offset_adjust_lsb = 0; - _ad9777_regs.idac_offset_adjust_msb = 0; - //Q dac values - _ad9777_regs.qdac_fine_gain_adjust = 0; + _ad9777_regs.idac_offset_adjust_lsb = 0; + _ad9777_regs.idac_offset_adjust_msb = 0; + // Q dac values + _ad9777_regs.qdac_fine_gain_adjust = 0; _ad9777_regs.qdac_coarse_gain_adjust = 0xf; - _ad9777_regs.qdac_offset_adjust_lsb = 0; - _ad9777_regs.qdac_offset_adjust_msb = 0; - //write all regs - for(uint8_t addr = 0; addr <= 0xC; addr++){ + _ad9777_regs.qdac_offset_adjust_lsb = 0; + _ad9777_regs.qdac_offset_adjust_msb = 0; + // write all regs + for (uint8_t addr = 0; addr <= 0xC; addr++) { this->send_ad9777_reg(addr); } set_tx_mod_mode(0); - //power-up adc - switch(_iface->get_rev()){ - case usrp2_iface::USRP2_REV3: - case usrp2_iface::USRP2_REV4: - _iface->poke32(U2_REG_MISC_CTRL_ADC, U2_FLAG_MISC_CTRL_ADC_ON); - break; - - case usrp2_iface::USRP_N200: - case usrp2_iface::USRP_N210: - _ads62p44_regs.reset = 1; - this->send_ads62p44_reg(0x00); //issue a reset to the ADC - //everything else should be pretty much default, i think - //_ads62p44_regs.decimation = DECIMATION_DECIMATE_1; - _ads62p44_regs.power_down = ads62p44_regs_t::POWER_DOWN_NORMAL; - this->send_ads62p44_reg(0x14); - this->set_rx_analog_gain(1); - break; - - case usrp2_iface::USRP_N200_R4: - case usrp2_iface::USRP_N210_R4: - _ads62p44_regs.reset = 1; - this->send_ads62p44_reg(0x00); //issue a reset to the ADC - //everything else should be pretty much default, i think - //_ads62p44_regs.decimation = DECIMATION_DECIMATE_1; - _ads62p44_regs.override = 1; - this->send_ads62p44_reg(0x14); - _ads62p44_regs.power_down = ads62p44_regs_t::POWER_DOWN_NORMAL; - _ads62p44_regs.output_interface = ads62p44_regs_t::OUTPUT_INTERFACE_LVDS; - _ads62p44_regs.lvds_current = ads62p44_regs_t::LVDS_CURRENT_2_5MA; - _ads62p44_regs.lvds_data_term = ads62p44_regs_t::LVDS_DATA_TERM_100; - this->send_ads62p44_reg(0x11); - this->send_ads62p44_reg(0x12); - this->send_ads62p44_reg(0x14); - this->set_rx_analog_gain(1); - break; - - case usrp2_iface::USRP_NXXX: break; + // power-up adc + switch (_iface->get_rev()) { + case usrp2_iface::USRP2_REV3: + case usrp2_iface::USRP2_REV4: + _iface->poke32(U2_REG_MISC_CTRL_ADC, U2_FLAG_MISC_CTRL_ADC_ON); + break; + + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + _ads62p44_regs.reset = 1; + this->send_ads62p44_reg(0x00); // issue a reset to the ADC + // everything else should be pretty much default, i think + //_ads62p44_regs.decimation = DECIMATION_DECIMATE_1; + _ads62p44_regs.power_down = ads62p44_regs_t::POWER_DOWN_NORMAL; + this->send_ads62p44_reg(0x14); + this->set_rx_analog_gain(1); + break; + + case usrp2_iface::USRP_N200_R4: + case usrp2_iface::USRP_N210_R4: + _ads62p44_regs.reset = 1; + this->send_ads62p44_reg(0x00); // issue a reset to the ADC + // everything else should be pretty much default, i think + //_ads62p44_regs.decimation = DECIMATION_DECIMATE_1; + _ads62p44_regs.override = 1; + this->send_ads62p44_reg(0x14); + _ads62p44_regs.power_down = ads62p44_regs_t::POWER_DOWN_NORMAL; + _ads62p44_regs.output_interface = ads62p44_regs_t::OUTPUT_INTERFACE_LVDS; + _ads62p44_regs.lvds_current = ads62p44_regs_t::LVDS_CURRENT_2_5MA; + _ads62p44_regs.lvds_data_term = ads62p44_regs_t::LVDS_DATA_TERM_100; + this->send_ads62p44_reg(0x11); + this->send_ads62p44_reg(0x12); + this->send_ads62p44_reg(0x14); + this->set_rx_analog_gain(1); + break; + + case usrp2_iface::USRP_NXXX: + break; } } - ~usrp2_codec_ctrl_impl(void){UHD_SAFE_CALL( - //power-down dac - _ad9777_regs.power_down_mode = 1; - this->send_ad9777_reg(0); - - //power-down adc - switch(_iface->get_rev()){ - case usrp2_iface::USRP2_REV3: - case usrp2_iface::USRP2_REV4: - _iface->poke32(U2_REG_MISC_CTRL_ADC, U2_FLAG_MISC_CTRL_ADC_OFF); - break; - - case usrp2_iface::USRP_N200: - case usrp2_iface::USRP_N210: - case usrp2_iface::USRP_N200_R4: - case usrp2_iface::USRP_N210_R4: - //send a global power-down to the ADC here... it will get lifted on reset - _ads62p44_regs.power_down = ads62p44_regs_t::POWER_DOWN_GLOBAL_PD; - this->send_ads62p44_reg(0x14); - break; - - case usrp2_iface::USRP_NXXX: break; - } - )} - - void set_tx_mod_mode(int mod_mode){ - //set the sign of the frequency shift - _ad9777_regs.modulation_form = (mod_mode > 0)? - ad9777_regs_t::MODULATION_FORM_E_PLUS_JWT: - ad9777_regs_t::MODULATION_FORM_E_MINUS_JWT - ; - - //set the frequency shift - switch(std::abs(mod_mode)){ - case 0: - case 1: _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_NONE; break; - case 2: _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_FS_2; break; - case 4: _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_FS_4; break; - case 8: _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_FS_8; break; - default: throw uhd::value_error("unknown modulation mode for ad9777"); + ~usrp2_codec_ctrl_impl(void) + { + UHD_SAFE_CALL( + // power-down dac + _ad9777_regs.power_down_mode = 1; this->send_ad9777_reg(0); + + // power-down adc + switch (_iface->get_rev()) { + case usrp2_iface::USRP2_REV3: + case usrp2_iface::USRP2_REV4: + _iface->poke32(U2_REG_MISC_CTRL_ADC, U2_FLAG_MISC_CTRL_ADC_OFF); + break; + + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + case usrp2_iface::USRP_N200_R4: + case usrp2_iface::USRP_N210_R4: + // send a global power-down to the ADC here... it will get lifted on + // reset + _ads62p44_regs.power_down = ads62p44_regs_t::POWER_DOWN_GLOBAL_PD; + this->send_ads62p44_reg(0x14); + break; + + case usrp2_iface::USRP_NXXX: + break; + }) + } + + void set_tx_mod_mode(int mod_mode) + { + // set the sign of the frequency shift + _ad9777_regs.modulation_form = (mod_mode > 0) + ? ad9777_regs_t::MODULATION_FORM_E_PLUS_JWT + : ad9777_regs_t::MODULATION_FORM_E_MINUS_JWT; + + // set the frequency shift + switch (std::abs(mod_mode)) { + case 0: + case 1: + _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_NONE; + break; + case 2: + _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_FS_2; + break; + case 4: + _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_FS_4; + break; + case 8: + _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_FS_8; + break; + default: + throw uhd::value_error("unknown modulation mode for ad9777"); } - this->send_ad9777_reg(0x01); //set the register + this->send_ad9777_reg(0x01); // set the register } - void set_rx_digital_gain(double gain) { //fine digital gain - switch(_iface->get_rev()){ - case usrp2_iface::USRP_N200: - case usrp2_iface::USRP_N210: - case usrp2_iface::USRP_N200_R4: - case usrp2_iface::USRP_N210_R4: - _ads62p44_regs.fine_gain = int(gain/0.5); - this->send_ads62p44_reg(0x17); - break; - - default: UHD_THROW_INVALID_CODE_PATH(); + void set_rx_digital_gain(double gain) + { // fine digital gain + switch (_iface->get_rev()) { + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + case usrp2_iface::USRP_N200_R4: + case usrp2_iface::USRP_N210_R4: + _ads62p44_regs.fine_gain = int(gain / 0.5); + this->send_ads62p44_reg(0x17); + break; + + default: + UHD_THROW_INVALID_CODE_PATH(); } } - void set_rx_digital_fine_gain(double gain) { //gain correction - switch(_iface->get_rev()){ - case usrp2_iface::USRP_N200: - case usrp2_iface::USRP_N210: - case usrp2_iface::USRP_N200_R4: - case usrp2_iface::USRP_N210_R4: - _ads62p44_regs.gain_correction = int(gain / 0.05); - this->send_ads62p44_reg(0x1A); - break; - - default: UHD_THROW_INVALID_CODE_PATH(); + void set_rx_digital_fine_gain(double gain) + { // gain correction + switch (_iface->get_rev()) { + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + case usrp2_iface::USRP_N200_R4: + case usrp2_iface::USRP_N210_R4: + _ads62p44_regs.gain_correction = int(gain / 0.05); + this->send_ads62p44_reg(0x1A); + break; + + default: + UHD_THROW_INVALID_CODE_PATH(); } } - void set_rx_analog_gain(bool /*gain*/) { //turns on/off analog 3.5dB preamp - switch(_iface->get_rev()){ - case usrp2_iface::USRP_N200: - case usrp2_iface::USRP_N210: - case usrp2_iface::USRP_N200_R4: - case usrp2_iface::USRP_N210_R4: - _ads62p44_regs.coarse_gain = ads62p44_regs_t::COARSE_GAIN_3_5DB;//gain ? ads62p44_regs_t::COARSE_GAIN_3_5DB : ads62p44_regs_t::COARSE_GAIN_0DB; - this->send_ads62p44_reg(0x14); - break; - - default: UHD_THROW_INVALID_CODE_PATH(); + void set_rx_analog_gain(bool /*gain*/) + { // turns on/off analog 3.5dB preamp + switch (_iface->get_rev()) { + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + case usrp2_iface::USRP_N200_R4: + case usrp2_iface::USRP_N210_R4: + _ads62p44_regs.coarse_gain = ads62p44_regs_t:: + COARSE_GAIN_3_5DB; // gain ? ads62p44_regs_t::COARSE_GAIN_3_5DB : + // ads62p44_regs_t::COARSE_GAIN_0DB; + this->send_ads62p44_reg(0x14); + break; + + default: + UHD_THROW_INVALID_CODE_PATH(); } } @@ -190,27 +214,25 @@ private: usrp2_iface::sptr _iface; uhd::spi_iface::sptr _spiface; - void send_ad9777_reg(uint8_t addr){ + void send_ad9777_reg(uint8_t addr) + { uint16_t reg = _ad9777_regs.get_write_reg(addr); UHD_LOG_TRACE("USRP2", "send_ad9777_reg: 0x" << std::hex << reg); - _spiface->write_spi( - SPI_SS_AD9777, spi_config_t::EDGE_RISE, - reg, 16 - ); + _spiface->write_spi(SPI_SS_AD9777, spi_config_t::EDGE_RISE, reg, 16); } - void send_ads62p44_reg(uint8_t addr) { + void send_ads62p44_reg(uint8_t addr) + { uint16_t reg = _ads62p44_regs.get_write_reg(addr); - _spiface->write_spi( - SPI_SS_ADS62P44, spi_config_t::EDGE_FALL, - reg, 16 - ); + _spiface->write_spi(SPI_SS_ADS62P44, spi_config_t::EDGE_FALL, reg, 16); } }; /*********************************************************************** * Public make function for the usrp2 codec control **********************************************************************/ -usrp2_codec_ctrl::sptr usrp2_codec_ctrl::make(usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface){ +usrp2_codec_ctrl::sptr usrp2_codec_ctrl::make( + usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface) +{ return sptr(new usrp2_codec_ctrl_impl(iface, spiface)); } diff --git a/host/lib/usrp/usrp2/codec_ctrl.hpp b/host/lib/usrp/usrp2/codec_ctrl.hpp index c769d102a..550e7208a 100644 --- a/host/lib/usrp/usrp2/codec_ctrl.hpp +++ b/host/lib/usrp/usrp2/codec_ctrl.hpp @@ -9,10 +9,11 @@ #define INCLUDED_CODEC_CTRL_HPP #include "usrp2_iface.hpp" -#include <memory> #include <uhd/utils/noncopyable.hpp> +#include <memory> -class usrp2_codec_ctrl : uhd::noncopyable{ +class usrp2_codec_ctrl : uhd::noncopyable +{ public: typedef std::shared_ptr<usrp2_codec_ctrl> sptr; @@ -62,7 +63,6 @@ public: * modulation. */ virtual size_t get_tx_interpolation() const = 0; - }; #endif /* INCLUDED_CODEC_CTRL_HPP */ diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index a245705df..55325dafc 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -5,39 +5,39 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include "ad5623_regs.hpp" //aux dac +#include "ad7922_regs.hpp" //aux adc #include "clock_ctrl.hpp" -#include "usrp2_regs.hpp" //wishbone address constants #include "usrp2_fifo_ctrl.hpp" -#include "ad7922_regs.hpp" //aux adc -#include "ad5623_regs.hpp" //aux dac -#include <uhdlib/usrp/cores/gpio_core_200.hpp> +#include "usrp2_regs.hpp" //wishbone address constants +#include <uhd/exception.hpp> +#include <uhd/types/dict.hpp> #include <uhd/types/serial.hpp> #include <uhd/usrp/dboard_iface.hpp> -#include <uhd/types/dict.hpp> -#include <uhd/exception.hpp> #include <uhd/utils/algorithm.hpp> -#include <boost/assign/list_of.hpp> +#include <uhdlib/usrp/cores/gpio_core_200.hpp> #include <boost/asio.hpp> //htonl and ntohl +#include <boost/assign/list_of.hpp> #include <boost/math/special_functions/round.hpp> using namespace uhd; using namespace uhd::usrp; using namespace boost::assign; -class usrp2_dboard_iface : public dboard_iface{ +class usrp2_dboard_iface : public dboard_iface +{ public: - usrp2_dboard_iface( - timed_wb_iface::sptr wb_iface, + usrp2_dboard_iface(timed_wb_iface::sptr wb_iface, uhd::i2c_iface::sptr i2c_iface, uhd::spi_iface::sptr spi_iface, - usrp2_clock_ctrl::sptr clock_ctrl - ); + usrp2_clock_ctrl::sptr clock_ctrl); ~usrp2_dboard_iface(void); - special_props_t get_special_props(void){ + special_props_t get_special_props(void) + { special_props_t props; props.soft_clock_divider = false; - props.mangle_i2c_addrs = false; + props.mangle_i2c_addrs = false; return props; } @@ -46,7 +46,8 @@ public: void set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_pin_ctrl(unit_t unit); - void set_atr_reg(unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask = 0xffffffff); + void set_atr_reg( + unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_atr_reg(unit_t unit, atr_reg_t reg); void set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_gpio_ddr(unit_t unit); @@ -57,7 +58,7 @@ public: void set_command_time(const uhd::time_spec_t& t); uhd::time_spec_t get_command_time(void); - void write_i2c(uint16_t, const byte_vector_t &); + void write_i2c(uint16_t, const byte_vector_t&); byte_vector_t read_i2c(uint16_t, size_t); void set_clock_rate(unit_t, double); @@ -65,21 +66,14 @@ public: std::vector<double> get_clock_rates(unit_t); void set_clock_enabled(unit_t, bool); double get_codec_rate(unit_t); - void set_fe_connection(unit_t unit, const std::string&, const fe_connection_t& fe_conn); + void set_fe_connection( + unit_t unit, const std::string&, const fe_connection_t& fe_conn); void write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits - ); + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits); uint32_t read_write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits - ); + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits); private: timed_wb_iface::sptr _wb_iface; @@ -96,241 +90,264 @@ private: /*********************************************************************** * Make Function **********************************************************************/ -dboard_iface::sptr make_usrp2_dboard_iface( - timed_wb_iface::sptr wb_iface, +dboard_iface::sptr make_usrp2_dboard_iface(timed_wb_iface::sptr wb_iface, uhd::i2c_iface::sptr i2c_iface, uhd::spi_iface::sptr spi_iface, - usrp2_clock_ctrl::sptr clock_ctrl -){ - return dboard_iface::sptr(new usrp2_dboard_iface(wb_iface, i2c_iface, spi_iface, clock_ctrl)); + usrp2_clock_ctrl::sptr clock_ctrl) +{ + return dboard_iface::sptr( + new usrp2_dboard_iface(wb_iface, i2c_iface, spi_iface, clock_ctrl)); } /*********************************************************************** * Structors **********************************************************************/ -usrp2_dboard_iface::usrp2_dboard_iface( - timed_wb_iface::sptr wb_iface, +usrp2_dboard_iface::usrp2_dboard_iface(timed_wb_iface::sptr wb_iface, uhd::i2c_iface::sptr i2c_iface, uhd::spi_iface::sptr spi_iface, - usrp2_clock_ctrl::sptr clock_ctrl -): - _wb_iface(wb_iface), - _i2c_iface(i2c_iface), - _spi_iface(spi_iface), - _clock_ctrl(clock_ctrl) + usrp2_clock_ctrl::sptr clock_ctrl) + : _wb_iface(wb_iface) + , _i2c_iface(i2c_iface) + , _spi_iface(spi_iface) + , _clock_ctrl(clock_ctrl) { _gpio = gpio_core_200::make(wb_iface, U2_REG_SR_ADDR(SR_GPIO), U2_REG_GPIO_RB); - //reset the aux dacs + // reset the aux dacs _dac_regs[UNIT_RX] = ad5623_regs_t(); _dac_regs[UNIT_TX] = ad5623_regs_t(); - for(unit_t unit: _dac_regs.keys()){ + for (unit_t unit : _dac_regs.keys()) { _dac_regs[unit].data = 1; _dac_regs[unit].addr = ad5623_regs_t::ADDR_ALL; _dac_regs[unit].cmd = ad5623_regs_t::CMD_RESET; this->_write_aux_dac(unit); } - //init the clock rate shadows with max rate clock + // init the clock rate shadows with max rate clock this->set_clock_rate(UNIT_RX, sorted(this->get_clock_rates(UNIT_RX)).back()); this->set_clock_rate(UNIT_TX, sorted(this->get_clock_rates(UNIT_TX)).back()); } -usrp2_dboard_iface::~usrp2_dboard_iface(void){ +usrp2_dboard_iface::~usrp2_dboard_iface(void) +{ /* NOP */ } /*********************************************************************** * Clocks **********************************************************************/ -void usrp2_dboard_iface::set_clock_rate(unit_t unit, double rate){ - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); - _clock_rates[unit] = rate; //set to shadow - switch(unit){ - case UNIT_RX: _clock_ctrl->set_rate_rx_dboard_clock(rate); return; - case UNIT_TX: _clock_ctrl->set_rate_tx_dboard_clock(rate); return; - default: UHD_THROW_INVALID_CODE_PATH(); +void usrp2_dboard_iface::set_clock_rate(unit_t unit, double rate) +{ + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); + _clock_rates[unit] = rate; // set to shadow + switch (unit) { + case UNIT_RX: + _clock_ctrl->set_rate_rx_dboard_clock(rate); + return; + case UNIT_TX: + _clock_ctrl->set_rate_tx_dboard_clock(rate); + return; + default: + UHD_THROW_INVALID_CODE_PATH(); } } -double usrp2_dboard_iface::get_clock_rate(unit_t unit){ - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); - return _clock_rates[unit]; //get from shadow +double usrp2_dboard_iface::get_clock_rate(unit_t unit) +{ + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); + return _clock_rates[unit]; // get from shadow } -std::vector<double> usrp2_dboard_iface::get_clock_rates(unit_t unit){ - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); - switch(unit){ - case UNIT_RX: return _clock_ctrl->get_rates_rx_dboard_clock(); - case UNIT_TX: return _clock_ctrl->get_rates_tx_dboard_clock(); - default: UHD_THROW_INVALID_CODE_PATH(); +std::vector<double> usrp2_dboard_iface::get_clock_rates(unit_t unit) +{ + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); + switch (unit) { + case UNIT_RX: + return _clock_ctrl->get_rates_rx_dboard_clock(); + case UNIT_TX: + return _clock_ctrl->get_rates_tx_dboard_clock(); + default: + UHD_THROW_INVALID_CODE_PATH(); } } -void usrp2_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); - switch(unit){ - case UNIT_RX: _clock_ctrl->enable_rx_dboard_clock(enb); return; - case UNIT_TX: _clock_ctrl->enable_tx_dboard_clock(enb); return; - default: UHD_THROW_INVALID_CODE_PATH(); +void usrp2_dboard_iface::set_clock_enabled(unit_t unit, bool enb) +{ + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); + switch (unit) { + case UNIT_RX: + _clock_ctrl->enable_rx_dboard_clock(enb); + return; + case UNIT_TX: + _clock_ctrl->enable_tx_dboard_clock(enb); + return; + default: + UHD_THROW_INVALID_CODE_PATH(); } } -double usrp2_dboard_iface::get_codec_rate(unit_t unit){ - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); +double usrp2_dboard_iface::get_codec_rate(unit_t unit) +{ + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); return _clock_ctrl->get_master_clock_rate(); } /*********************************************************************** * GPIO **********************************************************************/ -void usrp2_dboard_iface::set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask){ +void usrp2_dboard_iface::set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask) +{ _gpio->set_pin_ctrl(unit, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); } -uint32_t usrp2_dboard_iface::get_pin_ctrl(unit_t unit){ +uint32_t usrp2_dboard_iface::get_pin_ctrl(unit_t unit) +{ return static_cast<uint32_t>(_gpio->get_pin_ctrl(unit)); } -void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask){ - _gpio->set_atr_reg(unit, reg, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); +void usrp2_dboard_iface::set_atr_reg( + unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask) +{ + _gpio->set_atr_reg( + unit, reg, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); } -uint32_t usrp2_dboard_iface::get_atr_reg(unit_t unit, atr_reg_t reg){ +uint32_t usrp2_dboard_iface::get_atr_reg(unit_t unit, atr_reg_t reg) +{ return static_cast<uint32_t>(_gpio->get_atr_reg(unit, reg)); } -void usrp2_dboard_iface::set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask){ +void usrp2_dboard_iface::set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask) +{ _gpio->set_gpio_ddr(unit, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); } -uint32_t usrp2_dboard_iface::get_gpio_ddr(unit_t unit){ +uint32_t usrp2_dboard_iface::get_gpio_ddr(unit_t unit) +{ return static_cast<uint32_t>(_gpio->get_gpio_ddr(unit)); } -void usrp2_dboard_iface::set_gpio_out(unit_t unit, uint32_t value, uint32_t mask){ +void usrp2_dboard_iface::set_gpio_out(unit_t unit, uint32_t value, uint32_t mask) +{ _gpio->set_gpio_out(unit, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); } -uint32_t usrp2_dboard_iface::get_gpio_out(unit_t unit){ +uint32_t usrp2_dboard_iface::get_gpio_out(unit_t unit) +{ return static_cast<uint32_t>(_gpio->get_gpio_out(unit)); } -uint32_t usrp2_dboard_iface::read_gpio(unit_t unit){ +uint32_t usrp2_dboard_iface::read_gpio(unit_t unit) +{ return _gpio->read_gpio(unit); } /*********************************************************************** * SPI **********************************************************************/ -static const uhd::dict<dboard_iface::unit_t, int> unit_to_spi_dev = map_list_of - (dboard_iface::UNIT_TX, SPI_SS_TX_DB) - (dboard_iface::UNIT_RX, SPI_SS_RX_DB) -; +static const uhd::dict<dboard_iface::unit_t, int> unit_to_spi_dev = + map_list_of(dboard_iface::UNIT_TX, SPI_SS_TX_DB)(dboard_iface::UNIT_RX, SPI_SS_RX_DB); void usrp2_dboard_iface::write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits -){ - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits) +{ + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); _spi_iface->write_spi(unit_to_spi_dev[unit], config, data, num_bits); } uint32_t usrp2_dboard_iface::read_write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits -){ - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits) +{ + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); return _spi_iface->read_spi(unit_to_spi_dev[unit], config, data, num_bits); } /*********************************************************************** * I2C **********************************************************************/ -void usrp2_dboard_iface::write_i2c(uint16_t addr, const byte_vector_t &bytes){ +void usrp2_dboard_iface::write_i2c(uint16_t addr, const byte_vector_t& bytes) +{ return _i2c_iface->write_i2c(addr, bytes); } -byte_vector_t usrp2_dboard_iface::read_i2c(uint16_t addr, size_t num_bytes){ +byte_vector_t usrp2_dboard_iface::read_i2c(uint16_t addr, size_t num_bytes) +{ return _i2c_iface->read_i2c(addr, num_bytes); } /*********************************************************************** * Aux DAX/ADC **********************************************************************/ -void usrp2_dboard_iface::_write_aux_dac(unit_t unit){ - static const uhd::dict<unit_t, int> unit_to_spi_dac = map_list_of - (UNIT_RX, SPI_SS_RX_DAC) - (UNIT_TX, SPI_SS_TX_DAC) - ; - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); +void usrp2_dboard_iface::_write_aux_dac(unit_t unit) +{ + static const uhd::dict<unit_t, int> unit_to_spi_dac = + map_list_of(UNIT_RX, SPI_SS_RX_DAC)(UNIT_TX, SPI_SS_TX_DAC); + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); _spi_iface->write_spi( - unit_to_spi_dac[unit], spi_config_t::EDGE_FALL, - _dac_regs[unit].get_reg(), 24 - ); + unit_to_spi_dac[unit], spi_config_t::EDGE_FALL, _dac_regs[unit].get_reg(), 24); } -void usrp2_dboard_iface::write_aux_dac(unit_t unit, aux_dac_t which, double value){ - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); +void usrp2_dboard_iface::write_aux_dac(unit_t unit, aux_dac_t which, double value) +{ + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); - _dac_regs[unit].data = boost::math::iround(4095*value/3.3); - _dac_regs[unit].cmd = ad5623_regs_t::CMD_WR_UP_DAC_CHAN_N; + _dac_regs[unit].data = boost::math::iround(4095 * value / 3.3); + _dac_regs[unit].cmd = ad5623_regs_t::CMD_WR_UP_DAC_CHAN_N; typedef uhd::dict<aux_dac_t, ad5623_regs_t::addr_t> aux_dac_to_addr; - static const uhd::dict<unit_t, aux_dac_to_addr> unit_to_which_to_addr = map_list_of - (UNIT_RX, map_list_of - (AUX_DAC_A, ad5623_regs_t::ADDR_DAC_B) - (AUX_DAC_B, ad5623_regs_t::ADDR_DAC_A) - (AUX_DAC_C, ad5623_regs_t::ADDR_DAC_A) - (AUX_DAC_D, ad5623_regs_t::ADDR_DAC_B) - ) - (UNIT_TX, map_list_of - (AUX_DAC_A, ad5623_regs_t::ADDR_DAC_A) - (AUX_DAC_B, ad5623_regs_t::ADDR_DAC_B) - (AUX_DAC_C, ad5623_regs_t::ADDR_DAC_B) - (AUX_DAC_D, ad5623_regs_t::ADDR_DAC_A) - ) - ; + static const uhd::dict<unit_t, aux_dac_to_addr> unit_to_which_to_addr = + map_list_of(UNIT_RX, + map_list_of(AUX_DAC_A, ad5623_regs_t::ADDR_DAC_B)(AUX_DAC_B, + ad5623_regs_t::ADDR_DAC_A)(AUX_DAC_C, ad5623_regs_t::ADDR_DAC_A)( + AUX_DAC_D, ad5623_regs_t::ADDR_DAC_B))(UNIT_TX, + map_list_of(AUX_DAC_A, ad5623_regs_t::ADDR_DAC_A)(AUX_DAC_B, + ad5623_regs_t::ADDR_DAC_B)(AUX_DAC_C, ad5623_regs_t::ADDR_DAC_B)( + AUX_DAC_D, ad5623_regs_t::ADDR_DAC_A)); _dac_regs[unit].addr = unit_to_which_to_addr[unit][which]; this->_write_aux_dac(unit); } -double usrp2_dboard_iface::read_aux_adc(unit_t unit, aux_adc_t which){ - static const uhd::dict<unit_t, int> unit_to_spi_adc = map_list_of - (UNIT_RX, SPI_SS_RX_ADC) - (UNIT_TX, SPI_SS_TX_ADC) - ; +double usrp2_dboard_iface::read_aux_adc(unit_t unit, aux_adc_t which) +{ + static const uhd::dict<unit_t, int> unit_to_spi_adc = + map_list_of(UNIT_RX, SPI_SS_RX_ADC)(UNIT_TX, SPI_SS_TX_ADC); - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); - //setup spi config args + // setup spi config args spi_config_t config; config.mosi_edge = spi_config_t::EDGE_FALL; config.miso_edge = spi_config_t::EDGE_RISE; - //setup the spi registers + // setup the spi registers ad7922_regs_t ad7922_regs; - switch(which){ - case AUX_ADC_A: ad7922_regs.mod = 0; break; - case AUX_ADC_B: ad7922_regs.mod = 1; break; - } ad7922_regs.chn = ad7922_regs.mod; //normal mode: mod == chn + switch (which) { + case AUX_ADC_A: + ad7922_regs.mod = 0; + break; + case AUX_ADC_B: + ad7922_regs.mod = 1; + break; + } + ad7922_regs.chn = ad7922_regs.mod; // normal mode: mod == chn - //write and read spi - _spi_iface->write_spi( - unit_to_spi_adc[unit], config, - ad7922_regs.get_reg(), 16 - ); - ad7922_regs.set_reg(uint16_t(_spi_iface->read_spi( - unit_to_spi_adc[unit], config, - ad7922_regs.get_reg(), 16 - ))); - - //convert to voltage and return - return 3.3*ad7922_regs.result/4095; + // write and read spi + _spi_iface->write_spi(unit_to_spi_adc[unit], config, ad7922_regs.get_reg(), 16); + ad7922_regs.set_reg(uint16_t( + _spi_iface->read_spi(unit_to_spi_adc[unit], config, ad7922_regs.get_reg(), 16))); + + // convert to voltage and return + return 3.3 * ad7922_regs.result / 4095; } uhd::time_spec_t usrp2_dboard_iface::get_command_time() @@ -343,7 +360,9 @@ void usrp2_dboard_iface::set_command_time(const uhd::time_spec_t& t) _wb_iface->set_time(t); } -void usrp2_dboard_iface::set_fe_connection(unit_t, const std::string&, const fe_connection_t&) +void usrp2_dboard_iface::set_fe_connection( + unit_t, const std::string&, const fe_connection_t&) { - throw uhd::not_implemented_error("fe connection configuration support not implemented"); + throw uhd::not_implemented_error( + "fe connection configuration support not implemented"); } diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 1f8540c16..792b4721b 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -32,13 +32,14 @@ using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; namespace asio = boost::asio; -namespace pt = boost::posix_time; +namespace pt = boost::posix_time; /*********************************************************************** * helpers **********************************************************************/ -static UHD_INLINE pt::time_duration to_time_dur(double timeout){ - return pt::microseconds(long(timeout*1e6)); +static UHD_INLINE pt::time_duration to_time_dur(double timeout) +{ + return pt::microseconds(long(timeout * 1e6)); } /*********************************************************************** @@ -51,7 +52,8 @@ static const size_t vrt_send_header_offset_words32 = 1; * - the pirate thread calls update * - the get send buffer calls check **********************************************************************/ -class flow_control_monitor{ +class flow_control_monitor +{ public: typedef uint32_t seq_type; typedef std::shared_ptr<flow_control_monitor> sptr; @@ -60,13 +62,15 @@ public: * Make a new flow control monitor. * \param max_seqs_out num seqs before throttling */ - flow_control_monitor(seq_type max_seqs_out):_max_seqs_out(max_seqs_out){ + flow_control_monitor(seq_type max_seqs_out) : _max_seqs_out(max_seqs_out) + { this->clear(); _ready_fcn = std::bind(&flow_control_monitor::ready, this); } //! Clear the monitor, Ex: when a streamer is created - void clear(void){ + void clear(void) + { _last_seq_out = 0; _last_seq_ack = 0; } @@ -76,7 +80,8 @@ public: * Increments the sequence for the next call * \return the sequence to be sent to the dsp */ - UHD_INLINE seq_type get_curr_seq_out(void){ + UHD_INLINE seq_type get_curr_seq_out(void) + { return _last_seq_out++; } @@ -85,10 +90,12 @@ public: * \param timeout the timeout in seconds * \return false on timeout */ - UHD_INLINE bool check_fc_condition(double timeout){ + UHD_INLINE bool check_fc_condition(double timeout) + { boost::mutex::scoped_lock lock(_fc_mutex); - if (this->ready()) return true; - boost::this_thread::disable_interruption di; //disable because the wait can throw + if (this->ready()) + return true; + boost::this_thread::disable_interruption di; // disable because the wait can throw return _fc_cond.timed_wait(lock, to_time_dur(timeout), _ready_fcn); } @@ -96,7 +103,8 @@ public: * Update the flow control condition. * \param seq the last sequence number to be ACK'd */ - UHD_INLINE void update_fc_condition(seq_type seq){ + UHD_INLINE void update_fc_condition(seq_type seq) + { boost::mutex::scoped_lock lock(_fc_mutex); _last_seq_ack = seq; lock.unlock(); @@ -104,8 +112,9 @@ public: } private: - bool ready(void){ - return seq_type(_last_seq_out -_last_seq_ack) < _max_seqs_out; + bool ready(void) + { + return seq_type(_last_seq_out - _last_seq_ack) < _max_seqs_out; } boost::mutex _fc_mutex; @@ -122,41 +131,44 @@ private: * - thread loop * - vrt packet handler states **********************************************************************/ -struct usrp2_impl::io_impl{ - - io_impl(void): - async_msg_fifo(1000/*messages deep*/), - tick_rate(1 /*non-zero default*/) +struct usrp2_impl::io_impl +{ + io_impl(void) + : async_msg_fifo(1000 /*messages deep*/), tick_rate(1 /*non-zero default*/) { /* NOP */ } - ~io_impl(void){ - //Manually deconstuct the tasks, since this was not happening automatically. + ~io_impl(void) + { + // Manually deconstuct the tasks, since this was not happening automatically. pirate_tasks.clear(); } - managed_send_buffer::sptr get_send_buff(size_t chan, double timeout){ - flow_control_monitor &fc_mon = *fc_mons[chan]; + managed_send_buffer::sptr get_send_buff(size_t chan, double timeout) + { + flow_control_monitor& fc_mon = *fc_mons[chan]; - //wait on flow control w/ timeout - if (not fc_mon.check_fc_condition(timeout)) return managed_send_buffer::sptr(); + // wait on flow control w/ timeout + if (not fc_mon.check_fc_condition(timeout)) + return managed_send_buffer::sptr(); - //get a buffer from the transport w/ timeout + // get a buffer from the transport w/ timeout managed_send_buffer::sptr buff = tx_xports[chan]->get_send_buff(timeout); - //write the flow control word into the buffer - if (buff.get()) buff->cast<uint32_t *>()[0] = uhd::htonx(fc_mon.get_curr_seq_out()); + // write the flow control word into the buffer + if (buff.get()) + buff->cast<uint32_t*>()[0] = uhd::htonx(fc_mon.get_curr_seq_out()); return buff; } - //tx dsp: xports and flow control monitors + // tx dsp: xports and flow control monitors std::vector<zero_copy_if::sptr> tx_xports; std::vector<flow_control_monitor::sptr> fc_mons; - //methods and variables for the pirate crew - void recv_pirate_loop(zero_copy_if::sptr, size_t, const std::atomic<bool> &); + // methods and variables for the pirate crew + void recv_pirate_loop(zero_copy_if::sptr, size_t, const std::atomic<bool>&); std::list<task::sptr> pirate_tasks; bounded_buffer<async_metadata_t> async_msg_fifo; double tick_rate; @@ -169,47 +181,54 @@ struct usrp2_impl::io_impl{ * - put async message packets into queue **********************************************************************/ void usrp2_impl::io_impl::recv_pirate_loop( - zero_copy_if::sptr err_xport, size_t index, const std::atomic<bool> &exit_loop -){ + zero_copy_if::sptr err_xport, size_t index, const std::atomic<bool>& exit_loop) +{ set_thread_priority_safe(); - //store a reference to the flow control monitor (offset by max dsps) - flow_control_monitor &fc_mon = *(this->fc_mons[index]); + // store a reference to the flow control monitor (offset by max dsps) + flow_control_monitor& fc_mon = *(this->fc_mons[index]); - while (not exit_loop){ + while (not exit_loop) { managed_recv_buffer::sptr buff = err_xport->get_recv_buff(); - if (not buff.get()) continue; //ignore timeout/error buffers + if (not buff.get()) + continue; // ignore timeout/error buffers - try{ - //extract the vrt header packet info + try { + // extract the vrt header packet info vrt::if_packet_info_t if_packet_info; - if_packet_info.num_packet_words32 = buff->size()/sizeof(uint32_t); - const uint32_t *vrt_hdr = buff->cast<const uint32_t *>(); + if_packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t); + const uint32_t* vrt_hdr = buff->cast<const uint32_t*>(); vrt::if_hdr_unpack_be(vrt_hdr, if_packet_info); - //handle a tx async report message - if (if_packet_info.sid == USRP2_TX_ASYNC_SID and if_packet_info.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA){ - - //fill in the async metadata + // handle a tx async report message + if (if_packet_info.sid == USRP2_TX_ASYNC_SID + and if_packet_info.packet_type + != vrt::if_packet_info_t::PACKET_TYPE_DATA) { + // fill in the async metadata async_metadata_t metadata; - load_metadata_from_buff(uhd::ntohx<uint32_t>, metadata, if_packet_info, vrt_hdr, tick_rate, index); - - //catch the flow control packets and react - if (metadata.event_code == 0){ + load_metadata_from_buff(uhd::ntohx<uint32_t>, + metadata, + if_packet_info, + vrt_hdr, + tick_rate, + index); + + // catch the flow control packets and react + if (metadata.event_code == 0) { uint32_t fc_word32 = (vrt_hdr + if_packet_info.num_header_words32)[1]; fc_mon.update_fc_condition(uhd::ntohx(fc_word32)); continue; } - //else UHD_LOGGER_DEBUG("USRP2") << "metadata.event_code " << metadata.event_code; + // else UHD_LOGGER_DEBUG("USRP2") << "metadata.event_code " << + // metadata.event_code; async_msg_fifo.push_with_pop_on_full(metadata); standard_async_msg_prints(metadata); + } else { + // TODO unknown received packet, may want to print error... } - else{ - //TODO unknown received packet, may want to print error... - } - }catch(const std::exception &e){ - UHD_LOGGER_ERROR("USRP2") << "Error in recv pirate loop: " << e.what() ; + } catch (const std::exception& e) { + UHD_LOGGER_ERROR("USRP2") << "Error in recv pirate loop: " << e.what(); } } } @@ -217,137 +236,166 @@ void usrp2_impl::io_impl::recv_pirate_loop( /*********************************************************************** * Helper Functions **********************************************************************/ -void usrp2_impl::io_init(void){ - //create new io impl +void usrp2_impl::io_init(void) +{ + // create new io impl _io_impl = UHD_PIMPL_MAKE(io_impl, ()); - //init first so we dont have an access race - for(const std::string &mb: _mbc.keys()){ - //init the tx xport and flow control monitor + // init first so we dont have an access race + for (const std::string& mb : _mbc.keys()) { + // init the tx xport and flow control monitor _io_impl->tx_xports.push_back(_mbc[mb].tx_dsp_xport); - _io_impl->fc_mons.push_back(flow_control_monitor::sptr(new flow_control_monitor( - device_addr.cast("send_buff_size", USRP2_SRAM_BYTES) / - _mbc[mb].tx_dsp_xport->get_send_frame_size() - ))); + _io_impl->fc_mons.push_back(flow_control_monitor::sptr( + new flow_control_monitor(device_addr.cast("send_buff_size", USRP2_SRAM_BYTES) + / _mbc[mb].tx_dsp_xport->get_send_frame_size()))); } - //allocate streamer weak ptrs containers - for(const std::string &mb: _mbc.keys()){ + // allocate streamer weak ptrs containers + for (const std::string& mb : _mbc.keys()) { _mbc[mb].rx_streamers.resize(_mbc[mb].rx_dsps.size()); - _mbc[mb].tx_streamers.resize(1/*known to be 1 dsp*/); + _mbc[mb].tx_streamers.resize(1 /*known to be 1 dsp*/); } - //create a new pirate thread for each zc if (yarr!!) + // create a new pirate thread for each zc if (yarr!!) size_t index = 0; - for(const std::string &mb: _mbc.keys()){ - //spawn a new pirate to plunder the recv booty - _io_impl->pirate_tasks.push_back(task::make(std::bind( - &usrp2_impl::io_impl::recv_pirate_loop, _io_impl.get(), - _mbc[mb].tx_dsp_xport, index++, - std::ref(_pirate_task_exit) - ))); + for (const std::string& mb : _mbc.keys()) { + // spawn a new pirate to plunder the recv booty + _io_impl->pirate_tasks.push_back( + task::make(std::bind(&usrp2_impl::io_impl::recv_pirate_loop, + _io_impl.get(), + _mbc[mb].tx_dsp_xport, + index++, + std::ref(_pirate_task_exit)))); } } -void usrp2_impl::update_tick_rate(const double rate){ - _io_impl->tick_rate = rate; //shadow for async msg +void usrp2_impl::update_tick_rate(const double rate) +{ + _io_impl->tick_rate = rate; // shadow for async msg - //update the tick rate on all existing streamers -> thread safe - for(const std::string &mb: _mbc.keys()){ - for (size_t i = 0; i < _mbc[mb].rx_streamers.size(); i++){ + // update the tick rate on all existing streamers -> thread safe + for (const std::string& mb : _mbc.keys()) { + for (size_t i = 0; i < _mbc[mb].rx_streamers.size(); i++) { std::shared_ptr<sph::recv_packet_streamer> my_streamer = - std::dynamic_pointer_cast<sph::recv_packet_streamer>(_mbc[mb].rx_streamers[i].lock()); - if (my_streamer.get() == NULL) continue; + std::dynamic_pointer_cast<sph::recv_packet_streamer>( + _mbc[mb].rx_streamers[i].lock()); + if (my_streamer.get() == NULL) + continue; my_streamer->set_tick_rate(rate); } - for (size_t i = 0; i < _mbc[mb].tx_streamers.size(); i++){ + for (size_t i = 0; i < _mbc[mb].tx_streamers.size(); i++) { std::shared_ptr<sph::send_packet_streamer> my_streamer = - std::dynamic_pointer_cast<sph::send_packet_streamer>(_mbc[mb].tx_streamers[i].lock()); - if (my_streamer.get() == NULL) continue; + std::dynamic_pointer_cast<sph::send_packet_streamer>( + _mbc[mb].tx_streamers[i].lock()); + if (my_streamer.get() == NULL) + continue; my_streamer->set_tick_rate(rate); } } } -void usrp2_impl::update_rx_samp_rate(const std::string &mb, const size_t dsp, const double rate){ +void usrp2_impl::update_rx_samp_rate( + const std::string& mb, const size_t dsp, const double rate) +{ std::shared_ptr<sph::recv_packet_streamer> my_streamer = - std::dynamic_pointer_cast<sph::recv_packet_streamer>(_mbc[mb].rx_streamers[dsp].lock()); - if (my_streamer.get() == NULL) return; + std::dynamic_pointer_cast<sph::recv_packet_streamer>( + _mbc[mb].rx_streamers[dsp].lock()); + if (my_streamer.get() == NULL) + return; my_streamer->set_samp_rate(rate); const double adj = _mbc[mb].rx_dsps[dsp]->get_scaling_adjustment(); my_streamer->set_scale_factor(adj); } -void usrp2_impl::update_tx_samp_rate(const std::string &mb, const size_t dsp, const double rate){ +void usrp2_impl::update_tx_samp_rate( + const std::string& mb, const size_t dsp, const double rate) +{ std::shared_ptr<sph::send_packet_streamer> my_streamer = - std::dynamic_pointer_cast<sph::send_packet_streamer>(_mbc[mb].tx_streamers[dsp].lock()); - if (my_streamer.get() == NULL) return; + std::dynamic_pointer_cast<sph::send_packet_streamer>( + _mbc[mb].tx_streamers[dsp].lock()); + if (my_streamer.get() == NULL) + return; my_streamer->set_samp_rate(rate); const double adj = _mbc[mb].tx_dsp->get_scaling_adjustment(); my_streamer->set_scale_factor(adj); } -void usrp2_impl::update_rates(void){ - for(const std::string &mb: _mbc.keys()){ +void usrp2_impl::update_rates(void) +{ + for (const std::string& mb : _mbc.keys()) { fs_path root = "/mboards/" + mb; _tree->access<double>(root / "tick_rate").update(); - //and now that the tick rate is set, init the host rates to something - for(const std::string &name: _tree->list(root / "rx_dsps")){ + // and now that the tick rate is set, init the host rates to something + for (const std::string& name : _tree->list(root / "rx_dsps")) { _tree->access<double>(root / "rx_dsps" / name / "rate" / "value").update(); } - for(const std::string &name: _tree->list(root / "tx_dsps")){ + for (const std::string& name : _tree->list(root / "tx_dsps")) { _tree->access<double>(root / "tx_dsps" / name / "rate" / "value").update(); } } } -void usrp2_impl::update_rx_subdev_spec(const std::string &which_mb, const subdev_spec_t &spec){ +void usrp2_impl::update_rx_subdev_spec( + const std::string& which_mb, const subdev_spec_t& spec) +{ fs_path root = "/mboards/" + which_mb + "/dboards"; - //sanity checking + // sanity checking validate_subdev_spec(_tree, spec, "rx", which_mb); - //setup mux for this spec + // setup mux for this spec bool fe_swapped = false; - for (size_t i = 0; i < spec.size(); i++){ - const std::string conn = _tree->access<std::string>(root / spec[i].db_name / "rx_frontends" / spec[i].sd_name / "connection").get(); - if (i == 0 and (conn == "QI" or conn == "Q")) fe_swapped = true; + for (size_t i = 0; i < spec.size(); i++) { + const std::string conn = + _tree + ->access<std::string>(root / spec[i].db_name / "rx_frontends" + / spec[i].sd_name / "connection") + .get(); + if (i == 0 and (conn == "QI" or conn == "Q")) + fe_swapped = true; _mbc[which_mb].rx_dsps[i]->set_mux(conn, fe_swapped); } _mbc[which_mb].rx_fe->set_mux(fe_swapped); - //compute the new occupancy and resize + // compute the new occupancy and resize _mbc[which_mb].rx_chan_occ = spec.size(); - size_t nchan = 0; - for(const std::string &mb: _mbc.keys()) nchan += _mbc[mb].rx_chan_occ; + size_t nchan = 0; + for (const std::string& mb : _mbc.keys()) + nchan += _mbc[mb].rx_chan_occ; } -void usrp2_impl::update_tx_subdev_spec(const std::string &which_mb, const subdev_spec_t &spec){ +void usrp2_impl::update_tx_subdev_spec( + const std::string& which_mb, const subdev_spec_t& spec) +{ fs_path root = "/mboards/" + which_mb + "/dboards"; - //sanity checking + // sanity checking validate_subdev_spec(_tree, spec, "tx", which_mb); - //set the mux for this spec - const std::string conn = _tree->access<std::string>(root / spec[0].db_name / "tx_frontends" / spec[0].sd_name / "connection").get(); + // set the mux for this spec + const std::string conn = + _tree + ->access<std::string>( + root / spec[0].db_name / "tx_frontends" / spec[0].sd_name / "connection") + .get(); _mbc[which_mb].tx_fe->set_mux(conn); - //compute the new occupancy and resize + // compute the new occupancy and resize _mbc[which_mb].tx_chan_occ = spec.size(); - size_t nchan = 0; - for(const std::string &mb: _mbc.keys()) nchan += _mbc[mb].tx_chan_occ; + size_t nchan = 0; + for (const std::string& mb : _mbc.keys()) + nchan += _mbc[mb].tx_chan_occ; } /*********************************************************************** * Async Data **********************************************************************/ -bool usrp2_impl::recv_async_msg( - async_metadata_t &async_metadata, double timeout -){ - boost::this_thread::disable_interruption di; //disable because the wait can throw +bool usrp2_impl::recv_async_msg(async_metadata_t& async_metadata, double timeout) +{ + boost::this_thread::disable_interruption di; // disable because the wait can throw return _io_impl->async_msg_fifo.pop_with_timed_wait(async_metadata, timeout); } @@ -355,120 +403,132 @@ bool usrp2_impl::recv_async_msg( * Stream destination programmer **********************************************************************/ void usrp2_impl::program_stream_dest( - zero_copy_if::sptr &xport, const uhd::stream_args_t &args -){ - //perform an initial flush of transport - while (xport->get_recv_buff(0.0)){} + zero_copy_if::sptr& xport, const uhd::stream_args_t& args) +{ + // perform an initial flush of transport + while (xport->get_recv_buff(0.0)) { + } - //program the stream command + // program the stream command usrp2_stream_ctrl_t stream_ctrl = usrp2_stream_ctrl_t(); - stream_ctrl.sequence = uhd::htonx(uint32_t(0 /* don't care seq num */)); - stream_ctrl.vrt_hdr = uhd::htonx(uint32_t(USRP2_INVALID_VRT_HEADER)); + stream_ctrl.sequence = uhd::htonx(uint32_t(0 /* don't care seq num */)); + stream_ctrl.vrt_hdr = uhd::htonx(uint32_t(USRP2_INVALID_VRT_HEADER)); - //user has provided an alternative address and port for destination - if (args.args.has_key("addr") and args.args.has_key("port")){ - UHD_LOGGER_INFO("USRP2") << boost::format( - "Programming streaming destination for custom address. " - "IPv4 Address: %s, UDP Port: %s" - ) % args.args["addr"] % args.args["port"]; + // user has provided an alternative address and port for destination + if (args.args.has_key("addr") and args.args.has_key("port")) { + UHD_LOGGER_INFO("USRP2") + << boost::format("Programming streaming destination for custom address. " + "IPv4 Address: %s, UDP Port: %s") + % args.args["addr"] % args.args["port"]; asio::io_service io_service; asio::ip::udp::resolver resolver(io_service); - asio::ip::udp::resolver::query query(asio::ip::udp::v4(), args.args["addr"], args.args["port"]); + asio::ip::udp::resolver::query query( + asio::ip::udp::v4(), args.args["addr"], args.args["port"]); asio::ip::udp::endpoint endpoint = *resolver.resolve(query); stream_ctrl.ip_addr = uhd::htonx(uint32_t(endpoint.address().to_v4().to_ulong())); stream_ctrl.udp_port = uhd::htonx(uint32_t(endpoint.port())); - for (size_t i = 0; i < 3; i++){ + for (size_t i = 0; i < 3; i++) { UHD_LOGGER_INFO("USRP2") << "ARP attempt " << i; managed_send_buffer::sptr send_buff = xport->get_send_buff(); - std::memcpy(send_buff->cast<void *>(), &stream_ctrl, sizeof(stream_ctrl)); + std::memcpy(send_buff->cast<void*>(), &stream_ctrl, sizeof(stream_ctrl)); send_buff->commit(sizeof(stream_ctrl)); send_buff.reset(); std::this_thread::sleep_for(std::chrono::milliseconds(300)); managed_recv_buffer::sptr recv_buff = xport->get_recv_buff(0.0); - if (recv_buff and recv_buff->size() >= sizeof(uint32_t)){ - const uint32_t result = uhd::ntohx(recv_buff->cast<const uint32_t *>()[0]); - if (result == 0){ + if (recv_buff and recv_buff->size() >= sizeof(uint32_t)) { + const uint32_t result = uhd::ntohx(recv_buff->cast<const uint32_t*>()[0]); + if (result == 0) { UHD_LOGGER_INFO("USRP2") << "Success! "; return; } } } - throw uhd::runtime_error("Device failed to ARP when programming alternative streaming destination."); + throw uhd::runtime_error( + "Device failed to ARP when programming alternative streaming destination."); } - else{ - //send the partial stream control without destination + else { + // send the partial stream control without destination managed_send_buffer::sptr send_buff = xport->get_send_buff(); - std::memcpy(send_buff->cast<void *>(), &stream_ctrl, sizeof(stream_ctrl)); - send_buff->commit(sizeof(stream_ctrl)/2); + std::memcpy(send_buff->cast<void*>(), &stream_ctrl, sizeof(stream_ctrl)); + send_buff->commit(sizeof(stream_ctrl) / 2); } } /*********************************************************************** * Receive streamer **********************************************************************/ -rx_streamer::sptr usrp2_impl::get_rx_stream(const uhd::stream_args_t &args_){ +rx_streamer::sptr usrp2_impl::get_rx_stream(const uhd::stream_args_t& args_) +{ stream_args_t args = args_; - //setup defaults for unspecified values - args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; - args.channels = args.channels.empty()? std::vector<size_t>(1, 0) : args.channels; - - //calculate packet size - static const size_t hdr_size = 0 - + vrt::max_if_hdr_words32*sizeof(uint32_t) - + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - - sizeof(vrt::if_packet_info_t().cid) //no class id ever used - - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used - ; - const size_t bpp = _mbc[_mbc.keys().front()].rx_dsp_xports[0]->get_recv_frame_size() - hdr_size; + // setup defaults for unspecified values + args.otw_format = args.otw_format.empty() ? "sc16" : args.otw_format; + args.channels = args.channels.empty() ? std::vector<size_t>(1, 0) : args.channels; + + // calculate packet size + static const size_t hdr_size = + 0 + vrt::max_if_hdr_words32 * sizeof(uint32_t) + + sizeof(vrt::if_packet_info_t().tlr) // forced to have trailer + - sizeof(vrt::if_packet_info_t().cid) // no class id ever used + - sizeof(vrt::if_packet_info_t().tsi) // no int time ever used + ; + const size_t bpp = + _mbc[_mbc.keys().front()].rx_dsp_xports[0]->get_recv_frame_size() - hdr_size; const size_t bpi = convert::get_bytes_per_item(args.otw_format); - const size_t spp = args.args.cast<size_t>("spp", bpp/bpi); + const size_t spp = args.args.cast<size_t>("spp", bpp / bpi); - //make the new streamer given the samples per packet - std::shared_ptr<sph::recv_packet_streamer> my_streamer = std::make_shared<sph::recv_packet_streamer>(spp); + // make the new streamer given the samples per packet + std::shared_ptr<sph::recv_packet_streamer> my_streamer = + std::make_shared<sph::recv_packet_streamer>(spp); - //init some streamer stuff + // init some streamer stuff my_streamer->resize(args.channels.size()); my_streamer->set_vrt_unpacker(&vrt::if_hdr_unpack_be); - //set the converter + // set the converter uhd::convert::id_type id; - id.input_format = args.otw_format + "_item32_be"; - id.num_inputs = 1; + id.input_format = args.otw_format + "_item32_be"; + id.num_inputs = 1; id.output_format = args.cpu_format; - id.num_outputs = 1; + id.num_outputs = 1; my_streamer->set_converter(id); - //bind callbacks for the handler - for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++){ - const size_t chan = args.channels[chan_i]; + // bind callbacks for the handler + for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++) { + const size_t chan = args.channels[chan_i]; size_t num_chan_so_far = 0; - for(const std::string &mb: _mbc.keys()){ + for (const std::string& mb : _mbc.keys()) { num_chan_so_far += _mbc[mb].rx_chan_occ; - if (chan < num_chan_so_far){ + if (chan < num_chan_so_far) { const size_t dsp = chan + _mbc[mb].rx_chan_occ - num_chan_so_far; - _mbc[mb].rx_dsps[dsp]->set_nsamps_per_packet(spp); //seems to be a good place to set this + _mbc[mb].rx_dsps[dsp]->set_nsamps_per_packet( + spp); // seems to be a good place to set this _mbc[mb].rx_dsps[dsp]->setup(args); this->program_stream_dest(_mbc[mb].rx_dsp_xports[dsp], args); - my_streamer->set_xport_chan_get_buff(chan_i, std::bind( - &zero_copy_if::get_recv_buff, _mbc[mb].rx_dsp_xports[dsp], std::placeholders::_1 - ), true /*flush*/); - my_streamer->set_issue_stream_cmd(chan_i, std::bind( - &rx_dsp_core_200::issue_stream_command, _mbc[mb].rx_dsps[dsp], std::placeholders::_1)); - _mbc[mb].rx_streamers[dsp] = my_streamer; //store weak pointer + my_streamer->set_xport_chan_get_buff(chan_i, + std::bind(&zero_copy_if::get_recv_buff, + _mbc[mb].rx_dsp_xports[dsp], + std::placeholders::_1), + true /*flush*/); + my_streamer->set_issue_stream_cmd(chan_i, + std::bind(&rx_dsp_core_200::issue_stream_command, + _mbc[mb].rx_dsps[dsp], + std::placeholders::_1)); + _mbc[mb].rx_streamers[dsp] = my_streamer; // store weak pointer break; } } } - //set the packet threshold to be an entire socket buffer's worth - const size_t packets_per_sock_buff = size_t(50e6/_mbc[_mbc.keys().front()].rx_dsp_xports[0]->get_recv_frame_size()); + // set the packet threshold to be an entire socket buffer's worth + const size_t packets_per_sock_buff = + size_t(50e6 / _mbc[_mbc.keys().front()].rx_dsp_xports[0]->get_recv_frame_size()); my_streamer->set_alignment_failure_threshold(packets_per_sock_buff); - //sets all tick and samp rates on this streamer + // sets all tick and samp rates on this streamer this->update_rates(); return my_streamer; @@ -477,65 +537,74 @@ rx_streamer::sptr usrp2_impl::get_rx_stream(const uhd::stream_args_t &args_){ /*********************************************************************** * Transmit streamer **********************************************************************/ -tx_streamer::sptr usrp2_impl::get_tx_stream(const uhd::stream_args_t &args_){ +tx_streamer::sptr usrp2_impl::get_tx_stream(const uhd::stream_args_t& args_) +{ stream_args_t args = args_; - //setup defaults for unspecified values - args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; - args.channels = args.channels.empty()? std::vector<size_t>(1, 0) : args.channels; - - //calculate packet size - static const size_t hdr_size = 0 - + vrt_send_header_offset_words32*sizeof(uint32_t) - + vrt::max_if_hdr_words32*sizeof(uint32_t) - + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - - sizeof(vrt::if_packet_info_t().cid) //no class id ever used - - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used - - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used - ; - const size_t bpp = _mbc[_mbc.keys().front()].tx_dsp_xport->get_send_frame_size() - hdr_size; - const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); - - //make the new streamer given the samples per packet - std::shared_ptr<sph::send_packet_streamer> my_streamer = std::make_shared<sph::send_packet_streamer>(spp); - - //init some streamer stuff + // setup defaults for unspecified values + args.otw_format = args.otw_format.empty() ? "sc16" : args.otw_format; + args.channels = args.channels.empty() ? std::vector<size_t>(1, 0) : args.channels; + + // calculate packet size + static const size_t hdr_size = + 0 + vrt_send_header_offset_words32 * sizeof(uint32_t) + + vrt::max_if_hdr_words32 * sizeof(uint32_t) + + sizeof(vrt::if_packet_info_t().tlr) // forced to have trailer + - sizeof(vrt::if_packet_info_t().cid) // no class id ever used + - sizeof(vrt::if_packet_info_t().sid) // no stream id ever used + - sizeof(vrt::if_packet_info_t().tsi) // no int time ever used + ; + const size_t bpp = + _mbc[_mbc.keys().front()].tx_dsp_xport->get_send_frame_size() - hdr_size; + const size_t spp = bpp / convert::get_bytes_per_item(args.otw_format); + + // make the new streamer given the samples per packet + std::shared_ptr<sph::send_packet_streamer> my_streamer = + std::make_shared<sph::send_packet_streamer>(spp); + + // init some streamer stuff my_streamer->resize(args.channels.size()); my_streamer->set_vrt_packer(&vrt::if_hdr_pack_be, vrt_send_header_offset_words32); - //set the converter + // set the converter uhd::convert::id_type id; - id.input_format = args.cpu_format; - id.num_inputs = 1; + id.input_format = args.cpu_format; + id.num_inputs = 1; id.output_format = args.otw_format + "_item32_be"; - id.num_outputs = 1; + id.num_outputs = 1; my_streamer->set_converter(id); - //bind callbacks for the handler - for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++){ - const size_t chan = args.channels[chan_i]; + // bind callbacks for the handler + for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++) { + const size_t chan = args.channels[chan_i]; size_t num_chan_so_far = 0; - size_t abs = 0; - for(const std::string &mb: _mbc.keys()){ + size_t abs = 0; + for (const std::string& mb : _mbc.keys()) { num_chan_so_far += _mbc[mb].tx_chan_occ; - if (chan < num_chan_so_far){ + if (chan < num_chan_so_far) { const size_t dsp = chan + _mbc[mb].tx_chan_occ - num_chan_so_far; - if (not args.args.has_key("noclear")){ + if (not args.args.has_key("noclear")) { _io_impl->fc_mons[abs]->clear(); } _mbc[mb].tx_dsp->setup(args); - my_streamer->set_xport_chan_get_buff(chan_i, std::bind( - &usrp2_impl::io_impl::get_send_buff, _io_impl.get(), abs, std::placeholders::_1 - )); - my_streamer->set_async_receiver(std::bind(&bounded_buffer<async_metadata_t>::pop_with_timed_wait, &(_io_impl->async_msg_fifo), std::placeholders::_1, std::placeholders::_2)); - _mbc[mb].tx_streamers[dsp] = my_streamer; //store weak pointer + my_streamer->set_xport_chan_get_buff(chan_i, + std::bind(&usrp2_impl::io_impl::get_send_buff, + _io_impl.get(), + abs, + std::placeholders::_1)); + my_streamer->set_async_receiver( + std::bind(&bounded_buffer<async_metadata_t>::pop_with_timed_wait, + &(_io_impl->async_msg_fifo), + std::placeholders::_1, + std::placeholders::_2)); + _mbc[mb].tx_streamers[dsp] = my_streamer; // store weak pointer break; } - abs += 1; //assume 1 tx dsp + abs += 1; // assume 1 tx dsp } } - //sets all tick and samp rates on this streamer + // sets all tick and samp rates on this streamer this->update_rates(); return my_streamer; diff --git a/host/lib/usrp/usrp2/mb_eeprom.cpp b/host/lib/usrp/usrp2/mb_eeprom.cpp index bd91b527c..7bfe6159d 100644 --- a/host/lib/usrp/usrp2/mb_eeprom.cpp +++ b/host/lib/usrp/usrp2/mb_eeprom.cpp @@ -5,98 +5,105 @@ // #include "usrp2_impl.hpp" -#include <uhdlib/utils/eeprom_utils.hpp> -#include <uhd/usrp/mboard_eeprom.hpp> #include <uhd/types/byte_vector.hpp> #include <uhd/types/mac_addr.hpp> +#include <uhd/usrp/mboard_eeprom.hpp> +#include <uhdlib/utils/eeprom_utils.hpp> #include <boost/asio/ip/address_v4.hpp> namespace { - const uint8_t N200_EEPROM_ADDR = 0x50; - - struct n200_eeprom_map{ - uint16_t hardware; - uint8_t mac_addr[6]; - uint32_t subnet; - uint32_t ip_addr; - uint16_t _pad0; - uint16_t revision; - uint16_t product; - unsigned char _pad1; - unsigned char gpsdo; - unsigned char serial[SERIAL_LEN]; - unsigned char name[NAME_MAX_LEN]; - uint32_t gateway; - }; - - enum n200_gpsdo_type{ - N200_GPSDO_NONE = 0, - N200_GPSDO_INTERNAL = 1, - N200_GPSDO_ONBOARD = 2 - }; -} +const uint8_t N200_EEPROM_ADDR = 0x50; + +struct n200_eeprom_map +{ + uint16_t hardware; + uint8_t mac_addr[6]; + uint32_t subnet; + uint32_t ip_addr; + uint16_t _pad0; + uint16_t revision; + uint16_t product; + unsigned char _pad1; + unsigned char gpsdo; + unsigned char serial[SERIAL_LEN]; + unsigned char name[NAME_MAX_LEN]; + uint32_t gateway; +}; + +enum n200_gpsdo_type { + N200_GPSDO_NONE = 0, + N200_GPSDO_INTERNAL = 1, + N200_GPSDO_ONBOARD = 2 +}; +} // namespace using namespace uhd; using uhd::usrp::mboard_eeprom_t; -mboard_eeprom_t usrp2_impl::get_mb_eeprom(usrp2_iface &iface) +mboard_eeprom_t usrp2_impl::get_mb_eeprom(usrp2_iface& iface) { uhd::usrp::mboard_eeprom_t mb_eeprom; - //extract the hardware number + // extract the hardware number mb_eeprom["hardware"] = uint16_bytes_to_string( - iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, hardware), 2) - ); + iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, hardware), 2)); - //extract the revision number + // extract the revision number mb_eeprom["revision"] = uint16_bytes_to_string( - iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, revision), 2) - ); + iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, revision), 2)); - //extract the product code + // extract the product code mb_eeprom["product"] = uint16_bytes_to_string( - iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, product), 2) - ); + iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, product), 2)); - //extract the addresses - mb_eeprom["mac-addr"] = mac_addr_t::from_bytes(iface.read_eeprom( - N200_EEPROM_ADDR, offsetof(n200_eeprom_map, mac_addr), 6 - )).to_string(); + // extract the addresses + mb_eeprom["mac-addr"] = mac_addr_t::from_bytes( + iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, mac_addr), 6)) + .to_string(); boost::asio::ip::address_v4::bytes_type ip_addr_bytes; - byte_copy(iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, ip_addr), 4), ip_addr_bytes); + byte_copy(iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, ip_addr), 4), + ip_addr_bytes); mb_eeprom["ip-addr"] = boost::asio::ip::address_v4(ip_addr_bytes).to_string(); - byte_copy(iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, subnet), 4), ip_addr_bytes); + byte_copy(iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, subnet), 4), + ip_addr_bytes); mb_eeprom["subnet"] = boost::asio::ip::address_v4(ip_addr_bytes).to_string(); - byte_copy(iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, gateway), 4), ip_addr_bytes); + byte_copy(iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, gateway), 4), + ip_addr_bytes); mb_eeprom["gateway"] = boost::asio::ip::address_v4(ip_addr_bytes).to_string(); - //gpsdo capabilities - uint8_t gpsdo_byte = iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, gpsdo), 1).at(0); - switch(n200_gpsdo_type(gpsdo_byte)){ - case N200_GPSDO_INTERNAL: mb_eeprom["gpsdo"] = "internal"; break; - case N200_GPSDO_ONBOARD: mb_eeprom["gpsdo"] = "onboard"; break; - default: mb_eeprom["gpsdo"] = "none"; + // gpsdo capabilities + uint8_t gpsdo_byte = + iface.read_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, gpsdo), 1).at(0); + switch (n200_gpsdo_type(gpsdo_byte)) { + case N200_GPSDO_INTERNAL: + mb_eeprom["gpsdo"] = "internal"; + break; + case N200_GPSDO_ONBOARD: + mb_eeprom["gpsdo"] = "onboard"; + break; + default: + mb_eeprom["gpsdo"] = "none"; } - //extract the serial + // extract the serial mb_eeprom["serial"] = bytes_to_string(iface.read_eeprom( - N200_EEPROM_ADDR, offsetof(n200_eeprom_map, serial), SERIAL_LEN - )); + N200_EEPROM_ADDR, offsetof(n200_eeprom_map, serial), SERIAL_LEN)); - //extract the name + // extract the name mb_eeprom["name"] = bytes_to_string(iface.read_eeprom( - N200_EEPROM_ADDR, offsetof(n200_eeprom_map, name), NAME_MAX_LEN - )); - - //Empty serial correction: use the mac address to determine serial. - //Older usrp2 models don't have a serial burned into EEPROM. - //The lower mac address bits will function as the serial number. - if (mb_eeprom["serial"].empty()){ - byte_vector_t mac_addr_bytes = mac_addr_t::from_string(mb_eeprom["mac-addr"]).to_bytes(); - unsigned serial = mac_addr_bytes.at(5) | (unsigned(mac_addr_bytes.at(4) & 0x0f) << 8); + N200_EEPROM_ADDR, offsetof(n200_eeprom_map, name), NAME_MAX_LEN)); + + // Empty serial correction: use the mac address to determine serial. + // Older usrp2 models don't have a serial burned into EEPROM. + // The lower mac address bits will function as the serial number. + if (mb_eeprom["serial"].empty()) { + byte_vector_t mac_addr_bytes = + mac_addr_t::from_string(mb_eeprom["mac-addr"]).to_bytes(); + unsigned serial = mac_addr_bytes.at(5) + | (unsigned(mac_addr_bytes.at(4) & 0x0f) << 8); mb_eeprom["serial"] = std::to_string(serial); } @@ -104,72 +111,82 @@ mboard_eeprom_t usrp2_impl::get_mb_eeprom(usrp2_iface &iface) } -void usrp2_impl::set_mb_eeprom( - const std::string &mb, - const mboard_eeprom_t &mb_eeprom -) { - auto &iface = _mbc[mb].iface; - - //parse the revision number - if (mb_eeprom.has_key("hardware")) iface->write_eeprom( - N200_EEPROM_ADDR, offsetof(n200_eeprom_map, hardware), - string_to_uint16_bytes(mb_eeprom["hardware"]) - ); - - //parse the revision number - if (mb_eeprom.has_key("revision")) iface->write_eeprom( - N200_EEPROM_ADDR, offsetof(n200_eeprom_map, revision), - string_to_uint16_bytes(mb_eeprom["revision"]) - ); - - //parse the product code - if (mb_eeprom.has_key("product")) iface->write_eeprom( - N200_EEPROM_ADDR, offsetof(n200_eeprom_map, product), - string_to_uint16_bytes(mb_eeprom["product"]) - ); - - //store the addresses - if (mb_eeprom.has_key("mac-addr")) iface->write_eeprom( - N200_EEPROM_ADDR, offsetof(n200_eeprom_map, mac_addr), - mac_addr_t::from_string(mb_eeprom["mac-addr"]).to_bytes() - ); - - if (mb_eeprom.has_key("ip-addr")){ +void usrp2_impl::set_mb_eeprom(const std::string& mb, const mboard_eeprom_t& mb_eeprom) +{ + auto& iface = _mbc[mb].iface; + + // parse the revision number + if (mb_eeprom.has_key("hardware")) + iface->write_eeprom(N200_EEPROM_ADDR, + offsetof(n200_eeprom_map, hardware), + string_to_uint16_bytes(mb_eeprom["hardware"])); + + // parse the revision number + if (mb_eeprom.has_key("revision")) + iface->write_eeprom(N200_EEPROM_ADDR, + offsetof(n200_eeprom_map, revision), + string_to_uint16_bytes(mb_eeprom["revision"])); + + // parse the product code + if (mb_eeprom.has_key("product")) + iface->write_eeprom(N200_EEPROM_ADDR, + offsetof(n200_eeprom_map, product), + string_to_uint16_bytes(mb_eeprom["product"])); + + // store the addresses + if (mb_eeprom.has_key("mac-addr")) + iface->write_eeprom(N200_EEPROM_ADDR, + offsetof(n200_eeprom_map, mac_addr), + mac_addr_t::from_string(mb_eeprom["mac-addr"]).to_bytes()); + + if (mb_eeprom.has_key("ip-addr")) { byte_vector_t ip_addr_bytes(4); - byte_copy(boost::asio::ip::address_v4::from_string(mb_eeprom["ip-addr"]).to_bytes(), ip_addr_bytes); - iface->write_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, ip_addr), ip_addr_bytes); + byte_copy( + boost::asio::ip::address_v4::from_string(mb_eeprom["ip-addr"]).to_bytes(), + ip_addr_bytes); + iface->write_eeprom( + N200_EEPROM_ADDR, offsetof(n200_eeprom_map, ip_addr), ip_addr_bytes); } - if (mb_eeprom.has_key("subnet")){ + if (mb_eeprom.has_key("subnet")) { byte_vector_t ip_addr_bytes(4); - byte_copy(boost::asio::ip::address_v4::from_string(mb_eeprom["subnet"]).to_bytes(), ip_addr_bytes); - iface->write_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, subnet), ip_addr_bytes); + byte_copy( + boost::asio::ip::address_v4::from_string(mb_eeprom["subnet"]).to_bytes(), + ip_addr_bytes); + iface->write_eeprom( + N200_EEPROM_ADDR, offsetof(n200_eeprom_map, subnet), ip_addr_bytes); } - if (mb_eeprom.has_key("gateway")){ + if (mb_eeprom.has_key("gateway")) { byte_vector_t ip_addr_bytes(4); - byte_copy(boost::asio::ip::address_v4::from_string(mb_eeprom["gateway"]).to_bytes(), ip_addr_bytes); - iface->write_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, gateway), ip_addr_bytes); + byte_copy( + boost::asio::ip::address_v4::from_string(mb_eeprom["gateway"]).to_bytes(), + ip_addr_bytes); + iface->write_eeprom( + N200_EEPROM_ADDR, offsetof(n200_eeprom_map, gateway), ip_addr_bytes); } - //gpsdo capabilities - if (mb_eeprom.has_key("gpsdo")){ + // gpsdo capabilities + if (mb_eeprom.has_key("gpsdo")) { uint8_t gpsdo_byte = N200_GPSDO_NONE; - if (mb_eeprom["gpsdo"] == "internal") gpsdo_byte = N200_GPSDO_INTERNAL; - if (mb_eeprom["gpsdo"] == "onboard") gpsdo_byte = N200_GPSDO_ONBOARD; - iface->write_eeprom(N200_EEPROM_ADDR, offsetof(n200_eeprom_map, gpsdo), byte_vector_t(1, gpsdo_byte)); + if (mb_eeprom["gpsdo"] == "internal") + gpsdo_byte = N200_GPSDO_INTERNAL; + if (mb_eeprom["gpsdo"] == "onboard") + gpsdo_byte = N200_GPSDO_ONBOARD; + iface->write_eeprom(N200_EEPROM_ADDR, + offsetof(n200_eeprom_map, gpsdo), + byte_vector_t(1, gpsdo_byte)); } - //store the serial - if (mb_eeprom.has_key("serial")) iface->write_eeprom( - N200_EEPROM_ADDR, offsetof(n200_eeprom_map, serial), - string_to_bytes(mb_eeprom["serial"], SERIAL_LEN) - ); - - //store the name - if (mb_eeprom.has_key("name")) iface->write_eeprom( - N200_EEPROM_ADDR, offsetof(n200_eeprom_map, name), - string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN) - ); + // store the serial + if (mb_eeprom.has_key("serial")) + iface->write_eeprom(N200_EEPROM_ADDR, + offsetof(n200_eeprom_map, serial), + string_to_bytes(mb_eeprom["serial"], SERIAL_LEN)); + + // store the name + if (mb_eeprom.has_key("name")) + iface->write_eeprom(N200_EEPROM_ADDR, + offsetof(n200_eeprom_map, name), + string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN)); } - diff --git a/host/lib/usrp/usrp2/n200_image_loader.cpp b/host/lib/usrp/usrp2/n200_image_loader.cpp index 36da357e4..55b441c8b 100644 --- a/host/lib/usrp/usrp2/n200_image_loader.cpp +++ b/host/lib/usrp/usrp2/n200_image_loader.cpp @@ -5,30 +5,27 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <cstring> -#include <iostream> -#include <fstream> - -#include <boost/asio/ip/address_v4.hpp> -#include <boost/assign.hpp> -#include <boost/filesystem.hpp> -#include <boost/format.hpp> -#include <boost/thread.hpp> -#include <boost/algorithm/string/erase.hpp> - +#include "fw_common.h" +#include "usrp2_iface.hpp" +#include "usrp2_impl.hpp" #include <uhd/config.hpp> -#include <uhd/image_loader.hpp> #include <uhd/exception.hpp> +#include <uhd/image_loader.hpp> #include <uhd/transport/if_addrs.hpp> #include <uhd/transport/udp_simple.hpp> +#include <uhd/types/dict.hpp> #include <uhd/utils/byteswap.hpp> #include <uhd/utils/paths.hpp> #include <uhd/utils/static.hpp> -#include <uhd/types/dict.hpp> - -#include "fw_common.h" -#include "usrp2_iface.hpp" -#include "usrp2_impl.hpp" +#include <boost/algorithm/string/erase.hpp> +#include <boost/asio/ip/address_v4.hpp> +#include <boost/assign.hpp> +#include <boost/filesystem.hpp> +#include <boost/format.hpp> +#include <boost/thread.hpp> +#include <cstring> +#include <fstream> +#include <iostream> typedef boost::asio::ip::address_v4 ip_v4; @@ -48,12 +45,12 @@ using namespace uhd::transport; #define UDP_TIMEOUT 0.5 #define N200_FW_MAX_SIZE_BYTES 31744 -#define N200_PROD_FW_IMAGE_ADDR 0x00300000 -#define N200_SAFE_FW_IMAGE_ADDR 0x003F0000 +#define N200_PROD_FW_IMAGE_ADDR 0x00300000 +#define N200_SAFE_FW_IMAGE_ADDR 0x003F0000 #define N200_FPGA_MAX_SIZE_BYTES 1572864 -#define N200_PROD_FPGA_IMAGE_ADDR 0x00180000 -#define N200_SAFE_FPGA_IMAGE_ADDR 0x00000000 +#define N200_PROD_FPGA_IMAGE_ADDR 0x00180000 +#define N200_SAFE_FPGA_IMAGE_ADDR 0x00000000 /* * Packet codes @@ -62,7 +59,7 @@ typedef enum { UNKNOWN = ' ', N200_QUERY = 'a', - N200_ACK = 'A', + N200_ACK = 'A', GET_FLASH_INFO_CMD = 'f', GET_FLASH_INFO_ACK = 'F', @@ -71,8 +68,8 @@ typedef enum { ERASE_FLASH_ACK = 'E', CHECK_ERASING_DONE_CMD = 'd', - DONE_ERASING_ACK = 'D', - NOT_DONE_ERASING_ACK = 'B', + DONE_ERASING_ACK = 'D', + NOT_DONE_ERASING_ACK = 'B', WRITE_FLASH_CMD = 'w', WRITE_FLASH_ACK = 'W', @@ -90,30 +87,30 @@ typedef enum { /* * Mapping revision numbers to names */ -static const uhd::dict<uint32_t, std::string> n200_filename_map = boost::assign::map_list_of - (0, "n2xx") // Is an N-Series, but the EEPROM value is invalid - (0xa, "n200_r3") - (0x100a, "n200_r4") - (0x10a, "n210_r3") - (0x110a, "n210_r4") -; +static const uhd::dict<uint32_t, std::string> n200_filename_map = + boost::assign::map_list_of( + 0, "n2xx") // Is an N-Series, but the EEPROM value is invalid + (0xa, "n200_r3")(0x100a, "n200_r4")(0x10a, "n210_r3")(0x110a, "n210_r4"); /* * Packet structure */ -typedef struct { +typedef struct +{ uint32_t proto_ver; uint32_t id; uint32_t seq; union { uint32_t ip_addr; uint32_t hw_rev; - struct { + struct + { uint32_t flash_addr; uint32_t length; - uint8_t data[256]; + uint8_t data[256]; } flash_args; - struct { + struct + { uint32_t sector_size_bytes; uint32_t memory_size_bytes; } flash_info_args; @@ -123,90 +120,97 @@ typedef struct { /* * N-Series burn session */ -typedef struct { - bool fw; - bool overwrite_safe; - bool reset; +typedef struct +{ + bool fw; + bool overwrite_safe; + bool reset; uhd::device_addr_t dev_addr; - std::string burn_type; - std::string filepath; - uint8_t data_in[udp_simple::mtu]; - uint32_t size; - uint32_t max_size; - uint32_t flash_addr; - udp_simple::sptr xport; + std::string burn_type; + std::string filepath; + uint8_t data_in[udp_simple::mtu]; + uint32_t size; + uint32_t max_size; + uint32_t flash_addr; + udp_simple::sptr xport; } n200_session_t; /*********************************************************************** * uhd::image_loader functionality **********************************************************************/ -static void print_usrp2_error(const image_loader::image_loader_args_t &image_loader_args){ - #ifdef UHD_PLATFORM_WIN32 +static void print_usrp2_error(const image_loader::image_loader_args_t& image_loader_args) +{ +#ifdef UHD_PLATFORM_WIN32 std::string usrp2_card_burner_gui = "\""; - const std::string nl = " ^\n "; - #else + const std::string nl = " ^\n "; +#else std::string usrp2_card_burner_gui = "sudo \""; - const std::string nl = " \\\n "; - #endif + const std::string nl = " \\\n "; +#endif usrp2_card_burner_gui += find_utility("usrp2_card_burner_gui.py"); usrp2_card_burner_gui += "\""; - if(image_loader_args.load_firmware){ - usrp2_card_burner_gui += str(boost::format("%s--fw=\"%s\"") - % nl + if (image_loader_args.load_firmware) { + usrp2_card_burner_gui += str(boost::format("%s--fw=\"%s\"") % nl % ((image_loader_args.firmware_path == "") - ? find_image_path("usrp2_fw.bin") - : image_loader_args.firmware_path)); + ? find_image_path("usrp2_fw.bin") + : image_loader_args.firmware_path)); } - if(image_loader_args.load_fpga){ - usrp2_card_burner_gui += str(boost::format("%s--fpga=\"%s\"") - % nl - % ((image_loader_args.fpga_path == "") - ? find_image_path("usrp2_fpga.bin") - : image_loader_args.fpga_path)); + if (image_loader_args.load_fpga) { + usrp2_card_burner_gui += + str(boost::format("%s--fpga=\"%s\"") % nl + % ((image_loader_args.fpga_path == "") ? find_image_path("usrp2_fpga.bin") + : image_loader_args.fpga_path)); } - throw uhd::runtime_error(str(boost::format("The specified device is a USRP2, which is not supported by this utility.\n" - "Instead, plug the device's SD card into your machine and run this command:\n\n" - "%s" - ) % usrp2_card_burner_gui)); + throw uhd::runtime_error(str( + boost::format( + "The specified device is a USRP2, which is not supported by this utility.\n" + "Instead, plug the device's SD card into your machine and run this " + "command:\n\n" + "%s") + % usrp2_card_burner_gui)); } /* * Ethernet communication functions */ static UHD_INLINE size_t n200_send_and_recv(udp_simple::sptr xport, - n200_fw_update_id_t pkt_code, - n200_fw_update_data_t *pkt_out, - uint8_t* data){ + n200_fw_update_id_t pkt_code, + n200_fw_update_data_t* pkt_out, + uint8_t* data) +{ pkt_out->proto_ver = htonx<uint32_t>(USRP2_FW_COMPAT_NUM); - pkt_out->id = htonx<uint32_t>(pkt_code); + pkt_out->id = htonx<uint32_t>(pkt_code); xport->send(boost::asio::buffer(pkt_out, sizeof(*pkt_out))); return xport->recv(boost::asio::buffer(data, udp_simple::mtu), UDP_TIMEOUT); } -static UHD_INLINE bool n200_response_matches(const n200_fw_update_data_t *pkt_in, - n200_fw_update_id_t pkt_code, - size_t len){ - return (len > offsetof(n200_fw_update_data_t, data) and - ntohl(pkt_in->id) == (unsigned)pkt_code); +static UHD_INLINE bool n200_response_matches( + const n200_fw_update_data_t* pkt_in, n200_fw_update_id_t pkt_code, size_t len) +{ + return (len > offsetof(n200_fw_update_data_t, data) + and ntohl(pkt_in->id) == (unsigned)pkt_code); } -static uhd::device_addr_t n200_find(const image_loader::image_loader_args_t &image_loader_args){ - bool user_specified = image_loader_args.args.has_key("addr") or - image_loader_args.args.has_key("serial") or - image_loader_args.args.has_key("name"); +static uhd::device_addr_t n200_find( + const image_loader::image_loader_args_t& image_loader_args) +{ + bool user_specified = image_loader_args.args.has_key("addr") + or image_loader_args.args.has_key("serial") + or image_loader_args.args.has_key("name"); uhd::device_addrs_t found = usrp2_find(image_loader_args.args); - if(found.size() > 0){ + if (found.size() > 0) { uhd::device_addrs_t n200_found; udp_simple::sptr rev_xport; n200_fw_update_data_t pkt_out; uint8_t data_in[udp_simple::mtu]; - const n200_fw_update_data_t *pkt_in = reinterpret_cast<const n200_fw_update_data_t*>(data_in); + const n200_fw_update_data_t* pkt_in = + reinterpret_cast<const n200_fw_update_data_t*>(data_in); size_t len = 0; /* @@ -215,45 +219,43 @@ static uhd::device_addr_t n200_find(const image_loader::image_loader_args_t &ima * this query. If the user supplied specific arguments that * led to a USRP2, throw an error. */ - for(const uhd::device_addr_t &dev: found){ + for (const uhd::device_addr_t& dev : found) { rev_xport = udp_simple::make_connected( - dev.get("addr"), - BOOST_STRINGIZE(N200_UDP_FW_UPDATE_PORT) - ); + dev.get("addr"), BOOST_STRINGIZE(N200_UDP_FW_UPDATE_PORT)); len = n200_send_and_recv(rev_xport, GET_HW_REV_CMD, &pkt_out, data_in); - if(n200_response_matches(pkt_in, GET_HW_REV_ACK, len)){ - uint32_t rev = ntohl(pkt_in->data.hw_rev); + if (n200_response_matches(pkt_in, GET_HW_REV_ACK, len)) { + uint32_t rev = ntohl(pkt_in->data.hw_rev); std::string hw_rev = n200_filename_map.get(rev, "n2xx"); n200_found.push_back(dev); - n200_found[n200_found.size()-1]["hw_rev"] = hw_rev; - } - else if(len > offsetof(n200_fw_update_data_t, data) and ntohl(pkt_in->id) != GET_HW_REV_ACK){ - throw uhd::runtime_error(str(boost::format("Received invalid reply %d from device.") - % ntohl(pkt_in->id))); - } - else if(user_specified){ + n200_found[n200_found.size() - 1]["hw_rev"] = hw_rev; + } else if (len > offsetof(n200_fw_update_data_t, data) + and ntohl(pkt_in->id) != GET_HW_REV_ACK) { + throw uhd::runtime_error( + str(boost::format("Received invalid reply %d from device.") + % ntohl(pkt_in->id))); + } else if (user_specified) { // At this point, we haven't received any response, so assume it's a USRP2 print_usrp2_error(image_loader_args); } } // At this point, we should have a single N-Series device - if(n200_found.size() == 1){ + if (n200_found.size() == 1) { return n200_found[0]; - } - else if(n200_found.size() > 1){ - std::string err_msg = "Could not resolve given args to a single N-Series device.\n" - "Applicable devices:\n"; + } else if (n200_found.size() > 1) { + std::string err_msg = + "Could not resolve given args to a single N-Series device.\n" + "Applicable devices:\n"; - for(const uhd::device_addr_t &dev: n200_found){ - err_msg += str(boost::format("* %s (addr=%s)\n") - % dev.get("hw_rev") + for (const uhd::device_addr_t& dev : n200_found) { + err_msg += str(boost::format("* %s (addr=%s)\n") % dev.get("hw_rev") % dev.get("addr")); } - err_msg += "\nSpecify one of these devices with the given args to load an image onto it."; + err_msg += "\nSpecify one of these devices with the given args to load an " + "image onto it."; throw uhd::runtime_error(err_msg); } @@ -265,47 +267,53 @@ static uhd::device_addr_t n200_find(const image_loader::image_loader_args_t &ima /* * Validate and read firmware image */ -static void n200_validate_firmware_image(n200_session_t &session){ - if(not fs::exists(session.filepath)){ - throw uhd::runtime_error(str(boost::format("Could not find image at path \"%s\".") - % session.filepath)); +static void n200_validate_firmware_image(n200_session_t& session) +{ + if (not fs::exists(session.filepath)) { + throw uhd::runtime_error(str( + boost::format("Could not find image at path \"%s\".") % session.filepath)); } session.size = fs::file_size(session.filepath); session.max_size = N200_FW_MAX_SIZE_BYTES; - if(session.size > session.max_size){ - throw uhd::runtime_error(str(boost::format("The specified firmware image is too large: %d vs. %d") - % session.size % session.max_size)); + if (session.size > session.max_size) { + throw uhd::runtime_error( + str(boost::format("The specified firmware image is too large: %d vs. %d") + % session.size % session.max_size)); } // File must have proper header std::ifstream image_file(session.filepath.c_str(), std::ios::binary); uint8_t test_bytes[4]; image_file.seekg(0, std::ios::beg); - image_file.read((char*)test_bytes,4); + image_file.read((char*)test_bytes, 4); image_file.close(); - for(int i = 0; i < 4; i++) if(test_bytes[i] != 11){ - throw uhd::runtime_error(str(boost::format("The file at path \"%s\" is not a valid firmware image.") - % session.filepath)); - } + for (int i = 0; i < 4; i++) + if (test_bytes[i] != 11) { + throw uhd::runtime_error(str( + boost::format("The file at path \"%s\" is not a valid firmware image.") + % session.filepath)); + } } /* * Validate and validate FPGA image */ -static void n200_validate_fpga_image(n200_session_t &session){ - if(not fs::exists(session.filepath)){ - throw uhd::runtime_error(str(boost::format("Could not find image at path \"%s\".") - % session.filepath)); +static void n200_validate_fpga_image(n200_session_t& session) +{ + if (not fs::exists(session.filepath)) { + throw uhd::runtime_error(str( + boost::format("Could not find image at path \"%s\".") % session.filepath)); } session.size = fs::file_size(session.filepath); session.max_size = N200_FPGA_MAX_SIZE_BYTES; - if(session.size > session.max_size){ - throw uhd::runtime_error(str(boost::format("The specified FPGA image is too large: %d vs. %d") - % session.size % session.max_size)); + if (session.size > session.max_size) { + throw uhd::runtime_error( + str(boost::format("The specified FPGA image is too large: %d vs. %d") + % session.size % session.max_size)); } // File must have proper header @@ -314,18 +322,19 @@ static void n200_validate_fpga_image(n200_session_t &session){ image_file.seekg(0, std::ios::beg); image_file.read((char*)test_bytes, 63); bool is_good = false; - for(int i = 0; i < 62; i++){ - if(test_bytes[i] == 255) continue; - else if(test_bytes[i] == 170 and - test_bytes[i+1] == 153){ + for (int i = 0; i < 62; i++) { + if (test_bytes[i] == 255) + continue; + else if (test_bytes[i] == 170 and test_bytes[i + 1] == 153) { is_good = true; break; } } image_file.close(); - if(not is_good){ - throw uhd::runtime_error(str(boost::format("The file at path \"%s\" is not a valid FPGA image.") - % session.filepath)); + if (not is_good) { + throw uhd::runtime_error( + str(boost::format("The file at path \"%s\" is not a valid FPGA image.") + % session.filepath)); } } @@ -333,12 +342,11 @@ static void n200_validate_fpga_image(n200_session_t &session){ * Set up a session for burning an N-Series image. This session info * will be passed into the erase, burn, and verify functions. */ -static void n200_setup_session(n200_session_t &session, - const image_loader::image_loader_args_t &image_loader_args, - bool fw){ - - - session.fw = fw; +static void n200_setup_session(n200_session_t& session, + const image_loader::image_loader_args_t& image_loader_args, + bool fw) +{ + session.fw = fw; session.reset = image_loader_args.args.has_key("reset"); /* @@ -347,156 +355,162 @@ static void n200_setup_session(n200_session_t &session, * EEPROM or is otherwise unable to provide its revision, this is * impossible, and the user must manually provide a firmware file. */ - if((session.fw and image_loader_args.firmware_path == "") or - image_loader_args.fpga_path == ""){ - if(session.dev_addr["hw_rev"] == "n2xx"){ + if ((session.fw and image_loader_args.firmware_path == "") + or image_loader_args.fpga_path == "") { + if (session.dev_addr["hw_rev"] == "n2xx") { throw uhd::runtime_error("This device's revision cannot be determined. " "You must manually specify a filepath."); + } else { + session.filepath = + session.fw ? find_image_path( + str(boost::format("usrp_%s_fw.bin") + % erase_tail_copy(session.dev_addr["hw_rev"], 3))) + : find_image_path(str(boost::format("usrp_%s_fpga.bin") + % session.dev_addr["hw_rev"])); } - else{ - session.filepath = session.fw ? find_image_path(str(boost::format("usrp_%s_fw.bin") - % erase_tail_copy(session.dev_addr["hw_rev"],3))) - : find_image_path(str(boost::format("usrp_%s_fpga.bin") - % session.dev_addr["hw_rev"])); - } - } - else{ + } else { session.filepath = session.fw ? image_loader_args.firmware_path : image_loader_args.fpga_path; } - if(session.fw) n200_validate_firmware_image(session); - else n200_validate_fpga_image(session); + if (session.fw) + n200_validate_firmware_image(session); + else + n200_validate_fpga_image(session); session.overwrite_safe = image_loader_args.args.has_key("overwrite-safe"); - if(session.overwrite_safe){ + if (session.overwrite_safe) { session.flash_addr = session.fw ? N200_SAFE_FW_IMAGE_ADDR : N200_SAFE_FPGA_IMAGE_ADDR; - session.burn_type = session.fw ? "firmware safe" - : "FPGA safe"; - } - else{ + session.burn_type = session.fw ? "firmware safe" : "FPGA safe"; + } else { session.flash_addr = session.fw ? N200_PROD_FW_IMAGE_ADDR : N200_PROD_FPGA_IMAGE_ADDR; - session.burn_type = session.fw ? "firmware" - : "FPGA"; + session.burn_type = session.fw ? "firmware" : "FPGA"; } - session.xport = udp_simple::make_connected(session.dev_addr["addr"], - BOOST_STRINGIZE(N200_UDP_FW_UPDATE_PORT)); + session.xport = udp_simple::make_connected( + session.dev_addr["addr"], BOOST_STRINGIZE(N200_UDP_FW_UPDATE_PORT)); } -static void n200_erase_image(n200_session_t &session){ - +static void n200_erase_image(n200_session_t& session) +{ // UDP receive buffer n200_fw_update_data_t pkt_out; - const n200_fw_update_data_t *pkt_in = reinterpret_cast<const n200_fw_update_data_t*>(session.data_in); + const n200_fw_update_data_t* pkt_in = + reinterpret_cast<const n200_fw_update_data_t*>(session.data_in); // Setting up UDP packet pkt_out.data.flash_args.flash_addr = htonx<uint32_t>(session.flash_addr); - pkt_out.data.flash_args.length = htonx<uint32_t>(session.size); + pkt_out.data.flash_args.length = htonx<uint32_t>(session.size); // Begin erasing - size_t len = n200_send_and_recv(session.xport, ERASE_FLASH_CMD, &pkt_out, session.data_in); - if(n200_response_matches(pkt_in, ERASE_FLASH_ACK, len)){ - std::cout << boost::format("-- Erasing %s image...") % session.burn_type << std::flush; - } - else if(len < offsetof(n200_fw_update_data_t, data)){ + size_t len = + n200_send_and_recv(session.xport, ERASE_FLASH_CMD, &pkt_out, session.data_in); + if (n200_response_matches(pkt_in, ERASE_FLASH_ACK, len)) { + std::cout << boost::format("-- Erasing %s image...") % session.burn_type + << std::flush; + } else if (len < offsetof(n200_fw_update_data_t, data)) { std::cout << "failed." << std::endl; throw uhd::runtime_error("Timed out waiting for reply from device."); - } - else if(ntohl(pkt_in->id) != ERASE_FLASH_ACK){ + } else if (ntohl(pkt_in->id) != ERASE_FLASH_ACK) { std::cout << "failed." << std::endl; - throw uhd::runtime_error(str(boost::format("Received invalid reply %d from device.\n") - % ntohl(pkt_in->id))); - } - else{ + throw uhd::runtime_error( + str(boost::format("Received invalid reply %d from device.\n") + % ntohl(pkt_in->id))); + } else { std::cout << "failed." << std::endl; throw uhd::runtime_error("Did not receive response from device."); } // Check for erase completion - while(true){ - len = n200_send_and_recv(session.xport, CHECK_ERASING_DONE_CMD, &pkt_out, session.data_in); - if(n200_response_matches(pkt_in, DONE_ERASING_ACK, len)){ + while (true) { + len = n200_send_and_recv( + session.xport, CHECK_ERASING_DONE_CMD, &pkt_out, session.data_in); + if (n200_response_matches(pkt_in, DONE_ERASING_ACK, len)) { std::cout << "successful." << std::endl; break; - } - else if(len < offsetof(n200_fw_update_data_t, data)){ + } else if (len < offsetof(n200_fw_update_data_t, data)) { std::cout << "failed." << std::endl; throw uhd::runtime_error("Timed out waiting for reply from device."); - } - else if(ntohl(pkt_in->id) != NOT_DONE_ERASING_ACK){ + } else if (ntohl(pkt_in->id) != NOT_DONE_ERASING_ACK) { std::cout << "failed." << std::endl; - throw uhd::runtime_error(str(boost::format("Received invalid reply %d from device.\n") - % ntohl(pkt_in->id))); + throw uhd::runtime_error( + str(boost::format("Received invalid reply %d from device.\n") + % ntohl(pkt_in->id))); } } } -static void n200_write_image(n200_session_t &session){ - +static void n200_write_image(n200_session_t& session) +{ // UDP receive buffer n200_fw_update_data_t pkt_out; - const n200_fw_update_data_t *pkt_in = reinterpret_cast<const n200_fw_update_data_t*>(session.data_in); + const n200_fw_update_data_t* pkt_in = + reinterpret_cast<const n200_fw_update_data_t*>(session.data_in); size_t len = 0; // Write image std::ifstream image(session.filepath.c_str(), std::ios::binary); - uint32_t current_addr = session.flash_addr; + uint32_t current_addr = session.flash_addr; pkt_out.data.flash_args.length = htonx<uint32_t>(N200_FLASH_DATA_PACKET_SIZE); - for(size_t i = 0; i < ((session.size/N200_FLASH_DATA_PACKET_SIZE)+1); i++){ + for (size_t i = 0; i < ((session.size / N200_FLASH_DATA_PACKET_SIZE) + 1); i++) { pkt_out.data.flash_args.flash_addr = htonx<uint32_t>(current_addr); memset(pkt_out.data.flash_args.data, 0x0, N200_FLASH_DATA_PACKET_SIZE); image.read((char*)pkt_out.data.flash_args.data, N200_FLASH_DATA_PACKET_SIZE); - len = n200_send_and_recv(session.xport, WRITE_FLASH_CMD, &pkt_out, session.data_in); - if(n200_response_matches(pkt_in, WRITE_FLASH_ACK, len)){ - std::cout << boost::format("\r-- Writing %s image (%d%%)") - % session.burn_type - % int((double(current_addr-session.flash_addr)/double(session.size))*100) + len = + n200_send_and_recv(session.xport, WRITE_FLASH_CMD, &pkt_out, session.data_in); + if (n200_response_matches(pkt_in, WRITE_FLASH_ACK, len)) { + std::cout << boost::format("\r-- Writing %s image (%d%%)") % session.burn_type + % int((double(current_addr - session.flash_addr) + / double(session.size)) + * 100) << std::flush; - } - else if(len < offsetof(n200_fw_update_data_t, data)){ + } else if (len < offsetof(n200_fw_update_data_t, data)) { image.close(); std::cout << boost::format("\r--Writing %s image..failed at %d%%.") % session.burn_type - % int((double(current_addr-session.flash_addr)/double(session.size))*100) + % int((double(current_addr - session.flash_addr) + / double(session.size)) + * 100) << std::endl; throw uhd::runtime_error("Timed out waiting for reply from device."); - } - else if(ntohl(pkt_in->id) != WRITE_FLASH_ACK){ + } else if (ntohl(pkt_in->id) != WRITE_FLASH_ACK) { image.close(); std::cout << boost::format("\r--Writing %s image..failed at %d%%.") % session.burn_type - % int((double(current_addr-session.flash_addr)/double(session.size))*100) + % int((double(current_addr - session.flash_addr) + / double(session.size)) + * 100) << std::endl; - throw uhd::runtime_error(str(boost::format("Received invalid reply %d from device.\n") - % ntohl(pkt_in->id))); + throw uhd::runtime_error( + str(boost::format("Received invalid reply %d from device.\n") + % ntohl(pkt_in->id))); } current_addr += N200_FLASH_DATA_PACKET_SIZE; } - std::cout << boost::format("\r-- Writing %s image...successful.") - % session.burn_type + std::cout << boost::format("\r-- Writing %s image...successful.") % session.burn_type << std::endl; image.close(); } -static void n200_verify_image(n200_session_t &session){ - +static void n200_verify_image(n200_session_t& session) +{ // UDP receive buffer n200_fw_update_data_t pkt_out; - const n200_fw_update_data_t *pkt_in = reinterpret_cast<const n200_fw_update_data_t*>(session.data_in); + const n200_fw_update_data_t* pkt_in = + reinterpret_cast<const n200_fw_update_data_t*>(session.data_in); size_t len = 0; // Read and verify image std::ifstream image(session.filepath.c_str(), std::ios::binary); uint8_t image_part[N200_FLASH_DATA_PACKET_SIZE]; - uint32_t current_addr = session.flash_addr; + uint32_t current_addr = session.flash_addr; pkt_out.data.flash_args.length = htonx<uint32_t>(N200_FLASH_DATA_PACKET_SIZE); - uint16_t cmp_len = 0; - for(size_t i = 0; i < ((session.size/N200_FLASH_DATA_PACKET_SIZE)+1); i++){ + uint16_t cmp_len = 0; + for (size_t i = 0; i < ((session.size / N200_FLASH_DATA_PACKET_SIZE) + 1); i++) { memset(image_part, 0x0, N200_FLASH_DATA_PACKET_SIZE); memset((void*)pkt_in->data.flash_args.data, 0x0, N200_FLASH_DATA_PACKET_SIZE); @@ -504,57 +518,66 @@ static void n200_verify_image(n200_session_t &session){ image.read((char*)image_part, N200_FLASH_DATA_PACKET_SIZE); cmp_len = image.gcount(); - len = n200_send_and_recv(session.xport, READ_FLASH_CMD, &pkt_out, session.data_in); - if(n200_response_matches(pkt_in, READ_FLASH_ACK, len)){ + len = + n200_send_and_recv(session.xport, READ_FLASH_CMD, &pkt_out, session.data_in); + if (n200_response_matches(pkt_in, READ_FLASH_ACK, len)) { std::cout << boost::format("\r-- Verifying %s image (%d%%)") % session.burn_type - % int((double(current_addr-session.flash_addr)/double(session.size))*100) + % int((double(current_addr - session.flash_addr) + / double(session.size)) + * 100) << std::flush; - if(memcmp(image_part, pkt_in->data.flash_args.data, cmp_len)){ + if (memcmp(image_part, pkt_in->data.flash_args.data, cmp_len)) { std::cout << boost::format("\r-- Verifying %s image...failed at %d%%.") % session.burn_type - % int((double(current_addr-session.flash_addr)/double(session.size))*100) + % int((double(current_addr - session.flash_addr) + / double(session.size)) + * 100) << std::endl; - throw uhd::runtime_error(str(boost::format("Failed to verify %s image.") - % session.burn_type)); + throw uhd::runtime_error( + str(boost::format("Failed to verify %s image.") % session.burn_type)); } - } - else if(len < offsetof(n200_fw_update_data_t, data)){ + } else if (len < offsetof(n200_fw_update_data_t, data)) { image.close(); std::cout << boost::format("\r-- Verifying %s image...failed at %d%%.") % session.burn_type - % int((double(current_addr-session.flash_addr)/double(session.size))*100) + % int((double(current_addr - session.flash_addr) + / double(session.size)) + * 100) << std::endl; throw uhd::runtime_error("Timed out waiting for reply from device."); - } - else if(ntohl(pkt_in->id) != READ_FLASH_ACK){ + } else if (ntohl(pkt_in->id) != READ_FLASH_ACK) { image.close(); std::cout << boost::format("\r-- Verifying %s image...failed at %d%%.") % session.burn_type - % int((double(current_addr-session.flash_addr)/double(session.size))*100) + % int((double(current_addr - session.flash_addr) + / double(session.size)) + * 100) << std::endl; - throw uhd::runtime_error(str(boost::format("Received invalid reply %d from device.\n") - % ntohl(pkt_in->id))); + throw uhd::runtime_error( + str(boost::format("Received invalid reply %d from device.\n") + % ntohl(pkt_in->id))); } current_addr += N200_FLASH_DATA_PACKET_SIZE; } - std::cout << boost::format("\r-- Verifying %s image...successful.") % session.burn_type + std::cout << boost::format("\r-- Verifying %s image...successful.") + % session.burn_type << std::endl; image.close(); } -static void n200_reset(n200_session_t &session){ - +static void n200_reset(n200_session_t& session) +{ // UDP receive buffer n200_fw_update_data_t pkt_out; // There should be no response std::cout << "-- Resetting device..." << std::flush; size_t len = n200_send_and_recv(session.xport, RESET_CMD, &pkt_out, session.data_in); - if(len > 0){ + if (len > 0) { std::cout << "failed." << std::endl; throw uhd::runtime_error("Failed to reset N200."); } @@ -562,20 +585,22 @@ static void n200_reset(n200_session_t &session){ } // n210_r4 -> N210 r4 -static std::string nice_name(const std::string &fw_rev){ +static std::string nice_name(const std::string& fw_rev) +{ std::string ret = fw_rev; - ret[0] = ::toupper(ret[0]); + ret[0] = ::toupper(ret[0]); size_t pos = 0; - if((pos = fw_rev.find("_")) != std::string::npos){ + if ((pos = fw_rev.find("_")) != std::string::npos) { ret[pos] = ' '; } return ret; } -static bool n200_image_loader(const image_loader::image_loader_args_t &image_loader_args){ - if(!image_loader_args.load_firmware and !image_loader_args.load_fpga){ +static bool n200_image_loader(const image_loader::image_loader_args_t& image_loader_args) +{ + if (!image_loader_args.load_firmware and !image_loader_args.load_fpga) { return false; } @@ -583,43 +608,36 @@ static bool n200_image_loader(const image_loader::image_loader_args_t &image_loa // This will throw if specific args lead to a USRP2 n200_session_t session; session.dev_addr = n200_find(image_loader_args); - if(session.dev_addr.size() == 0){ + if (session.dev_addr.size() == 0) { return false; } std::cout << boost::format("Unit: USRP %s (%s, %s)") - % nice_name(session.dev_addr.get("hw_rev")) - % session.dev_addr.get("serial") - % session.dev_addr.get("addr") - << std::endl; + % nice_name(session.dev_addr.get("hw_rev")) + % session.dev_addr.get("serial") % session.dev_addr.get("addr") + << std::endl; - if(image_loader_args.load_firmware){ - n200_setup_session(session, - image_loader_args, - true - ); + if (image_loader_args.load_firmware) { + n200_setup_session(session, image_loader_args, true); std::cout << "Firmware image: " << session.filepath << std::endl; n200_erase_image(session); n200_write_image(session); n200_verify_image(session); - if(session.reset and !image_loader_args.load_fpga){ + if (session.reset and !image_loader_args.load_fpga) { n200_reset(session); } } - if(image_loader_args.load_fpga){ - n200_setup_session(session, - image_loader_args, - false - ); + if (image_loader_args.load_fpga) { + n200_setup_session(session, image_loader_args, false); std::cout << "FPGA image: " << session.filepath << std::endl; n200_erase_image(session); n200_write_image(session); n200_verify_image(session); - if(session.reset){ + if (session.reset) { n200_reset(session); } } @@ -627,10 +645,13 @@ static bool n200_image_loader(const image_loader::image_loader_args_t &image_loa return true; } -UHD_STATIC_BLOCK(register_n200_image_loader){ - std::string recovery_instructions = "Aborting. Your USRP-N Series unit will likely be unusable.\n" - "Refer to http://files.ettus.com/manual/page_usrp2.html#usrp2_loadflash_brick\n" - "for details on restoring your device."; +UHD_STATIC_BLOCK(register_n200_image_loader) +{ + std::string recovery_instructions = + "Aborting. Your USRP-N Series unit will likely be unusable.\n" + "Refer to http://files.ettus.com/manual/page_usrp2.html#usrp2_loadflash_brick\n" + "for details on restoring your device."; - image_loader::register_image_loader("usrp2", n200_image_loader, recovery_instructions); + image_loader::register_image_loader( + "usrp2", n200_image_loader, recovery_instructions); } diff --git a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp index ac58decc0..c85bdf35d 100644 --- a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp @@ -10,78 +10,84 @@ #include "usrp2_iface.hpp" -class usrp2_clk_regs_t { +class usrp2_clk_regs_t +{ public: - usrp2_clk_regs_t(void): - test(0), - fpga(0), - adc(0), - dac(0), - serdes(0), - exp(0), - tx_db(0), - rx_db(0) {} + usrp2_clk_regs_t(void) + : test(0), fpga(0), adc(0), dac(0), serdes(0), exp(0), tx_db(0), rx_db(0) + { + } - usrp2_clk_regs_t(usrp2_iface::rev_type rev) { - fpga = adc = serdes = exp = tx_db = 0; - test = 0; - fpga = 1; - dac = 3; + usrp2_clk_regs_t(usrp2_iface::rev_type rev) + { + fpga = adc = serdes = exp = tx_db = 0; + test = 0; + fpga = 1; + dac = 3; - switch(rev) { - case usrp2_iface::USRP2_REV3: - exp = 2; - adc = 4; - serdes = 2; - tx_db = 6; - break; - case usrp2_iface::USRP2_REV4: - exp = 5; - adc = 4; - serdes = 2; - tx_db = 6; - break; - case usrp2_iface::USRP_N200: - case usrp2_iface::USRP_N210: - case usrp2_iface::USRP_N200_R4: - case usrp2_iface::USRP_N210_R4: - exp = 6; - adc = 2; - serdes = 4; - tx_db = 5; - break; - case usrp2_iface::USRP_NXXX: - //dont throw, it may be unitialized - break; - } + switch (rev) { + case usrp2_iface::USRP2_REV3: + exp = 2; + adc = 4; + serdes = 2; + tx_db = 6; + break; + case usrp2_iface::USRP2_REV4: + exp = 5; + adc = 4; + serdes = 2; + tx_db = 6; + break; + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + case usrp2_iface::USRP_N200_R4: + case usrp2_iface::USRP_N210_R4: + exp = 6; + adc = 2; + serdes = 4; + tx_db = 5; + break; + case usrp2_iface::USRP_NXXX: + // dont throw, it may be unitialized + break; + } - rx_db = 7; - } + rx_db = 7; + } - static int output(int clknum) { return 0x3C + clknum; } - static int div_lo(int clknum) { return 0x48 + 2 * clknum; } - static int div_hi(int clknum) { return 0x49 + 2 * clknum; } + static int output(int clknum) + { + return 0x3C + clknum; + } + static int div_lo(int clknum) + { + return 0x48 + 2 * clknum; + } + static int div_hi(int clknum) + { + return 0x49 + 2 * clknum; + } - const static int acounter = 0x04; - const static int bcounter_msb = 0x05; - const static int bcounter_lsb = 0x06; - const static int pll_1 = 0x07; - const static int pll_2 = 0x08; - const static int pll_3 = 0x09; - const static int pll_4 = 0x0A; - const static int ref_counter_msb = 0x0B; - const static int ref_counter_lsb = 0x0C; - const static int pll_5 = 0x0D; - const static int update = 0x5A; + const static int acounter = 0x04; + const static int bcounter_msb = 0x05; + const static int bcounter_lsb = 0x06; + const static int pll_1 = 0x07; + const static int pll_2 = 0x08; + const static int pll_3 = 0x09; + const static int pll_4 = 0x0A; + const static int ref_counter_msb = 0x0B; + const static int ref_counter_lsb = 0x0C; + const static int pll_5 = 0x0D; + const static int update = 0x5A; - int test; - int fpga; - int adc; - int dac; - int serdes; - int exp; - int tx_db; - int rx_db; + int test; + int fpga; + int adc; + int dac; + int serdes; + int exp; + int tx_db; + int rx_db; }; -#endif //INCLUDED_USRP2_CLK_REGS_HPP +#endif // INCLUDED_USRP2_CLK_REGS_HPP diff --git a/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp index 0c0a21851..ca3a79ca5 100644 --- a/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp +++ b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp @@ -5,24 +5,24 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include "usrp2_fifo_ctrl.hpp" #include "usrp2_regs.hpp" #include <uhd/exception.hpp> +#include <uhd/transport/vrt_if_packet.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/safe_call.hpp> -#include <uhd/transport/vrt_if_packet.hpp> -#include "usrp2_fifo_ctrl.hpp" -#include <boost/thread/mutex.hpp> -#include <boost/thread/thread.hpp> #include <boost/asio.hpp> //htonl #include <boost/format.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> using namespace uhd; using namespace uhd::transport; -static const size_t POKE32_CMD = (1 << 8); -static const size_t PEEK32_CMD = 0; +static const size_t POKE32_CMD = (1 << 8); +static const size_t PEEK32_CMD = 0; static const double ACK_TIMEOUT = 0.5; -static const double MASSIVE_TIMEOUT = 10.0; //for when we wait on a timed command +static const double MASSIVE_TIMEOUT = 10.0; // for when we wait on a timed command static const uint32_t MAX_SEQS_OUT = 63; #define SPI_DIV SR_SPI_CORE + 0 @@ -32,43 +32,44 @@ static const uint32_t MAX_SEQS_OUT = 63; // spi clock rate = master_clock/(div+1)/2 (10MHz in this case) #define SPI_DIVIDER 4 -class usrp2_fifo_ctrl_impl : public usrp2_fifo_ctrl{ +class usrp2_fifo_ctrl_impl : public usrp2_fifo_ctrl +{ public: - - usrp2_fifo_ctrl_impl(zero_copy_if::sptr xport): - _xport(xport), - _seq_out(0), - _seq_ack(0), - _timeout(ACK_TIMEOUT) + usrp2_fifo_ctrl_impl(zero_copy_if::sptr xport) + : _xport(xport), _seq_out(0), _seq_ack(0), _timeout(ACK_TIMEOUT) { - while (_xport->get_recv_buff(0.0)){} //flush + while (_xport->get_recv_buff(0.0)) { + } // flush this->set_time(uhd::time_spec_t(0.0)); - this->set_tick_rate(1.0); //something possible but bogus + this->set_tick_rate(1.0); // something possible but bogus this->init_spi(); } - ~usrp2_fifo_ctrl_impl(void){ - _timeout = ACK_TIMEOUT; //reset timeout to something small + ~usrp2_fifo_ctrl_impl(void) + { + _timeout = ACK_TIMEOUT; // reset timeout to something small UHD_SAFE_CALL( - this->peek32(0); //dummy peek with the purpose of ack'ing all packets + this->peek32(0); // dummy peek with the purpose of ack'ing all packets ) } /******************************************************************* * Peek and poke 32 bit implementation ******************************************************************/ - void poke32(const wb_addr_type addr, const uint32_t data){ + void poke32(const wb_addr_type addr, const uint32_t data) + { boost::mutex::scoped_lock lock(_mutex); - this->send_pkt((addr - SETTING_REGS_BASE)/4, data, POKE32_CMD); + this->send_pkt((addr - SETTING_REGS_BASE) / 4, data, POKE32_CMD); - this->wait_for_ack(_seq_out-MAX_SEQS_OUT); + this->wait_for_ack(_seq_out - MAX_SEQS_OUT); } - uint32_t peek32(const wb_addr_type addr){ + uint32_t peek32(const wb_addr_type addr) + { boost::mutex::scoped_lock lock(_mutex); - this->send_pkt((addr - READBACK_BASE)/4, 0, PEEK32_CMD); + this->send_pkt((addr - READBACK_BASE) / 4, 0, PEEK32_CMD); return this->wait_for_ack(_seq_out); } @@ -76,58 +77,62 @@ public: /******************************************************************* * Peek and poke 16 bit not implemented ******************************************************************/ - void poke16(const wb_addr_type, const uint16_t){ + void poke16(const wb_addr_type, const uint16_t) + { throw uhd::not_implemented_error("poke16 not implemented in fifo ctrl module"); } - uint16_t peek16(const wb_addr_type){ + uint16_t peek16(const wb_addr_type) + { throw uhd::not_implemented_error("peek16 not implemented in fifo ctrl module"); } /******************************************************************* * FIFO controlled SPI implementation ******************************************************************/ - void init_spi(void){ + void init_spi(void) + { boost::mutex::scoped_lock lock(_mutex); this->send_pkt(SPI_DIV, SPI_DIVIDER, POKE32_CMD); - this->wait_for_ack(_seq_out-MAX_SEQS_OUT); + this->wait_for_ack(_seq_out - MAX_SEQS_OUT); _ctrl_word_cache = 0; // force update first time around } - uint32_t transact_spi( - int which_slave, - const spi_config_t &config, + uint32_t transact_spi(int which_slave, + const spi_config_t& config, uint32_t data, size_t num_bits, - bool readback - ){ + bool readback) + { boost::mutex::scoped_lock lock(_mutex); - //load control word + // load control word uint32_t ctrl_word = 0; ctrl_word |= ((which_slave & 0xffffff) << 0); ctrl_word |= ((num_bits & 0x3ff) << 24); - if (config.mosi_edge == spi_config_t::EDGE_FALL) ctrl_word |= (1 << 31); - if (config.miso_edge == spi_config_t::EDGE_RISE) ctrl_word |= (1 << 30); + if (config.mosi_edge == spi_config_t::EDGE_FALL) + ctrl_word |= (1 << 31); + if (config.miso_edge == spi_config_t::EDGE_RISE) + ctrl_word |= (1 << 30); - //load data word (must be in upper bits) + // load data word (must be in upper bits) const uint32_t data_out = data << (32 - num_bits); - //conditionally send control word - if (_ctrl_word_cache != ctrl_word){ + // conditionally send control word + if (_ctrl_word_cache != ctrl_word) { this->send_pkt(SPI_CTRL, ctrl_word, POKE32_CMD); - this->wait_for_ack(_seq_out-MAX_SEQS_OUT); + this->wait_for_ack(_seq_out - MAX_SEQS_OUT); _ctrl_word_cache = ctrl_word; } - //send data word + // send data word this->send_pkt(SPI_DATA, data_out, POKE32_CMD); - this->wait_for_ack(_seq_out-MAX_SEQS_OUT); + this->wait_for_ack(_seq_out - MAX_SEQS_OUT); - //conditional readback - if (readback){ + // conditional readback + if (readback) { this->send_pkt(SPI_READBACK, 0, PEEK32_CMD); return this->wait_for_ack(_seq_out); } @@ -138,11 +143,13 @@ public: /******************************************************************* * Update methods for time ******************************************************************/ - void set_time(const uhd::time_spec_t &time){ + void set_time(const uhd::time_spec_t& time) + { boost::mutex::scoped_lock lock(_mutex); - _time = time; + _time = time; _use_time = _time != uhd::time_spec_t(0.0); - if (_use_time) _timeout = MASSIVE_TIMEOUT; //permanently sets larger timeout + if (_use_time) + _timeout = MASSIVE_TIMEOUT; // permanently sets larger timeout } uhd::time_spec_t get_time() @@ -151,72 +158,75 @@ public: return _time; } - void set_tick_rate(const double rate){ + void set_tick_rate(const double rate) + { boost::mutex::scoped_lock lock(_mutex); _tick_rate = rate; } private: - /******************************************************************* * Primary control and interaction private methods ******************************************************************/ - UHD_INLINE void send_pkt(wb_addr_type addr, uint32_t data, int cmd){ + UHD_INLINE void send_pkt(wb_addr_type addr, uint32_t data, int cmd) + { managed_send_buffer::sptr buff = _xport->get_send_buff(0.0); - if (not buff){ + if (not buff) { throw uhd::runtime_error("fifo ctrl timed out getting a send buffer"); } - uint32_t *trans = buff->cast<uint32_t *>(); - trans[0] = htonl(++_seq_out); - uint32_t *pkt = trans + 1; + uint32_t* trans = buff->cast<uint32_t*>(); + trans[0] = htonl(++_seq_out); + uint32_t* pkt = trans + 1; - //load packet info + // load packet info vrt::if_packet_info_t packet_info; - packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CONTEXT; + packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CONTEXT; packet_info.num_payload_words32 = 2; - packet_info.num_payload_bytes = packet_info.num_payload_words32*sizeof(uint32_t); + packet_info.num_payload_bytes = + packet_info.num_payload_words32 * sizeof(uint32_t); packet_info.packet_count = _seq_out; - packet_info.tsf = _time.to_ticks(_tick_rate); - packet_info.sob = false; - packet_info.eob = false; - packet_info.has_sid = false; - packet_info.has_cid = false; - packet_info.has_tsi = false; - packet_info.has_tsf = _use_time; - packet_info.has_tlr = false; - - //load header + packet_info.tsf = _time.to_ticks(_tick_rate); + packet_info.sob = false; + packet_info.eob = false; + packet_info.has_sid = false; + packet_info.has_cid = false; + packet_info.has_tsi = false; + packet_info.has_tsf = _use_time; + packet_info.has_tlr = false; + + // load header vrt::if_hdr_pack_be(pkt, packet_info); - //load payload - const uint32_t ctrl_word = (addr & 0xff) | cmd | (_seq_out << 16); - pkt[packet_info.num_header_words32+0] = htonl(ctrl_word); - pkt[packet_info.num_header_words32+1] = htonl(data); + // load payload + const uint32_t ctrl_word = (addr & 0xff) | cmd | (_seq_out << 16); + pkt[packet_info.num_header_words32 + 0] = htonl(ctrl_word); + pkt[packet_info.num_header_words32 + 1] = htonl(data); - //send the buffer over the interface - buff->commit(sizeof(uint32_t)*(packet_info.num_packet_words32+1)); + // send the buffer over the interface + buff->commit(sizeof(uint32_t) * (packet_info.num_packet_words32 + 1)); } - UHD_INLINE bool wraparound_lt16(const int16_t i0, const int16_t i1){ - if (((i0 ^ i1) & 0x8000) == 0) //same sign bits + UHD_INLINE bool wraparound_lt16(const int16_t i0, const int16_t i1) + { + if (((i0 ^ i1) & 0x8000) == 0) // same sign bits return uint16_t(i0) < uint16_t(i1); return int16_t(i1 - i0) > 0; } - UHD_INLINE uint32_t wait_for_ack(const uint16_t seq_to_ack){ - - while (wraparound_lt16(_seq_ack, seq_to_ack)){ + UHD_INLINE uint32_t wait_for_ack(const uint16_t seq_to_ack) + { + while (wraparound_lt16(_seq_ack, seq_to_ack)) { managed_recv_buffer::sptr buff = _xport->get_recv_buff(_timeout); - if (not buff){ + if (not buff) { throw uhd::runtime_error("fifo ctrl timed out looking for acks"); } - const uint32_t *pkt = buff->cast<const uint32_t *>(); + const uint32_t* pkt = buff->cast<const uint32_t*>(); vrt::if_packet_info_t packet_info; - packet_info.num_packet_words32 = buff->size()/sizeof(uint32_t); + packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t); vrt::if_hdr_unpack_be(pkt, packet_info); - _seq_ack = ntohl(pkt[packet_info.num_header_words32+0]) >> 16; - if (_seq_ack == seq_to_ack){ - return ntohl(pkt[packet_info.num_header_words32+1]); + _seq_ack = ntohl(pkt[packet_info.num_header_words32 + 0]) >> 16; + if (_seq_ack == seq_to_ack) { + return ntohl(pkt[packet_info.num_header_words32 + 1]); } } @@ -235,6 +245,7 @@ private: }; -usrp2_fifo_ctrl::sptr usrp2_fifo_ctrl::make(zero_copy_if::sptr xport){ +usrp2_fifo_ctrl::sptr usrp2_fifo_ctrl::make(zero_copy_if::sptr xport) +{ return sptr(new usrp2_fifo_ctrl_impl(xport)); } diff --git a/host/lib/usrp/usrp2/usrp2_fifo_ctrl.hpp b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.hpp index cbb243a79..5f8cdb264 100644 --- a/host/lib/usrp/usrp2/usrp2_fifo_ctrl.hpp +++ b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.hpp @@ -8,12 +8,12 @@ #ifndef INCLUDED_USRP2_FIFO_CTRL_HPP #define INCLUDED_USRP2_FIFO_CTRL_HPP -#include <uhd/types/time_spec.hpp> -#include <uhd/types/serial.hpp> #include <uhd/transport/zero_copy.hpp> -#include <memory> -#include <boost/utility.hpp> +#include <uhd/types/serial.hpp> +#include <uhd/types/time_spec.hpp> #include <uhd/types/wb_iface.hpp> +#include <boost/utility.hpp> +#include <memory> #include <string> /*! diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 962ead769..029d2b30a 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -36,13 +36,12 @@ namespace fs = boost::filesystem; static const double CTRL_RECV_TIMEOUT = 1.0; static const size_t CTRL_RECV_RETRIES = 3; -//custom timeout error for retry logic to catch/retry +// custom timeout error for retry logic to catch/retry struct timeout_error : uhd::runtime_error { - timeout_error(const std::string &what): - uhd::runtime_error(what) + timeout_error(const std::string& what) : uhd::runtime_error(what) { - //NOP + // NOP } }; @@ -51,24 +50,25 @@ static const uint32_t MIN_PROTO_COMPAT_I2C = 7; // The register compat number must reflect the protocol compatibility // and the compatibility of the register mapping (more likely to change). static const uint32_t MIN_PROTO_COMPAT_REG = 10; -//static const uint32_t MIN_PROTO_COMPAT_UART = 7; +// static const uint32_t MIN_PROTO_COMPAT_UART = 7; -class usrp2_iface_impl : public usrp2_iface{ +class usrp2_iface_impl : public usrp2_iface +{ public: -/*********************************************************************** - * Structors - **********************************************************************/ - usrp2_iface_impl(udp_simple::sptr ctrl_transport): - _ctrl_transport(ctrl_transport), - _ctrl_seq_num(0), - _protocol_compat(0) //initialized below... + /*********************************************************************** + * Structors + **********************************************************************/ + usrp2_iface_impl(udp_simple::sptr ctrl_transport) + : _ctrl_transport(ctrl_transport) + , _ctrl_seq_num(0) + , _protocol_compat(0) // initialized below... { - //Obtain the firmware's compat number. - //Save the response compat number for communication. - //TODO can choose to reject certain older compat numbers + // Obtain the firmware's compat number. + // Save the response compat number for communication. + // TODO can choose to reject certain older compat numbers usrp2_ctrl_data_t ctrl_data = usrp2_ctrl_data_t(); - ctrl_data.id = htonl(USRP2_CTRL_ID_WAZZUP_BRO); - ctrl_data = ctrl_send_and_recv(ctrl_data, 0, ~0); + ctrl_data.id = htonl(USRP2_CTRL_ID_WAZZUP_BRO); + ctrl_data = ctrl_send_and_recv(ctrl_data, 0, ~0); if (ntohl(ctrl_data.id) != USRP2_CTRL_ID_WAZZUP_DUDE) throw uhd::runtime_error("firmware not responding"); _protocol_compat = ntohl(ctrl_data.proto_ver); @@ -76,71 +76,82 @@ public: mb_eeprom = usrp2_impl::get_mb_eeprom(*this); } - ~usrp2_iface_impl(void){UHD_SAFE_CALL( - this->lock_device(false); - )} + ~usrp2_iface_impl(void) + { + UHD_SAFE_CALL(this->lock_device(false);) + } -/*********************************************************************** - * Device locking - **********************************************************************/ + /*********************************************************************** + * Device locking + **********************************************************************/ - void lock_device(bool lock){ - if (lock){ + void lock_device(bool lock) + { + if (lock) { this->pokefw(U2_FW_REG_LOCK_GPID, get_process_hash()); _lock_task = task::make(std::bind(&usrp2_iface_impl::lock_task, this)); - } - else{ - _lock_task.reset(); //shutdown the task - this->pokefw(U2_FW_REG_LOCK_TIME, 0); //unlock + } else { + _lock_task.reset(); // shutdown the task + this->pokefw(U2_FW_REG_LOCK_TIME, 0); // unlock } } - bool is_device_locked(void){ - //never assume lock with fpga image mismatch - if ((this->peek32(U2_REG_COMPAT_NUM_RB) >> 16) != USRP2_FPGA_COMPAT_NUM) return false; + bool is_device_locked(void) + { + // never assume lock with fpga image mismatch + if ((this->peek32(U2_REG_COMPAT_NUM_RB) >> 16) != USRP2_FPGA_COMPAT_NUM) + return false; uint32_t lock_time = this->peekfw(U2_FW_REG_LOCK_TIME); uint32_t lock_gpid = this->peekfw(U2_FW_REG_LOCK_GPID); - //may not be the right tick rate, but this is ok for locking purposes - const uint32_t lock_timeout_time = uint32_t(3*100e6); + // may not be the right tick rate, but this is ok for locking purposes + const uint32_t lock_timeout_time = uint32_t(3 * 100e6); - //if the difference is larger, assume not locked anymore - if ((lock_time & 1) == 0) return false; //bit0 says unlocked + // if the difference is larger, assume not locked anymore + if ((lock_time & 1) == 0) + return false; // bit0 says unlocked const uint32_t time_diff = this->get_curr_time() - lock_time; - if (time_diff >= lock_timeout_time) return false; + if (time_diff >= lock_timeout_time) + return false; - //otherwise only lock if the device hash is different that ours + // otherwise only lock if the device hash is different that ours return lock_gpid != get_process_hash(); } - void lock_task(void){ - //re-lock in task + void lock_task(void) + { + // re-lock in task this->pokefw(U2_FW_REG_LOCK_TIME, this->get_curr_time()); - //sleep for a bit + // sleep for a bit std::this_thread::sleep_for(std::chrono::milliseconds(1500)); } - uint32_t get_curr_time(void){ - return this->peek32(U2_REG_TIME64_LO_RB_IMM) | 1; //bit 1 says locked + uint32_t get_curr_time(void) + { + return this->peek32(U2_REG_TIME64_LO_RB_IMM) | 1; // bit 1 says locked } -/*********************************************************************** - * Peek and Poke - **********************************************************************/ - void poke32(const wb_addr_type addr, const uint32_t data){ + /*********************************************************************** + * Peek and Poke + **********************************************************************/ + void poke32(const wb_addr_type addr, const uint32_t data) + { this->get_reg<uint32_t, USRP2_REG_ACTION_FPGA_POKE32>(addr, data); } - uint32_t peek32(const wb_addr_type addr){ + uint32_t peek32(const wb_addr_type addr) + { return this->get_reg<uint32_t, USRP2_REG_ACTION_FPGA_PEEK32>(addr); } - void poke16(const wb_addr_type addr, const uint16_t data){ + void poke16(const wb_addr_type addr, const uint16_t data) + { this->get_reg<uint16_t, USRP2_REG_ACTION_FPGA_POKE16>(addr, data); } - uint16_t peek16(const wb_addr_type addr){ + uint16_t peek16(const wb_addr_type addr) + { return this->get_reg<uint16_t, USRP2_REG_ACTION_FPGA_PEEK16>(addr); } @@ -155,236 +166,294 @@ public: } template <class T, usrp2_reg_action_t action> - T get_reg(wb_addr_type addr, T data = 0){ - //setup the out data - usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t(); - out_data.id = htonl(USRP2_CTRL_ID_GET_THIS_REGISTER_FOR_ME_BRO); - out_data.data.reg_args.addr = htonl(addr); - out_data.data.reg_args.data = htonl(uint32_t(data)); + T get_reg(wb_addr_type addr, T data = 0) + { + // setup the out data + usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t(); + out_data.id = htonl(USRP2_CTRL_ID_GET_THIS_REGISTER_FOR_ME_BRO); + out_data.data.reg_args.addr = htonl(addr); + out_data.data.reg_args.data = htonl(uint32_t(data)); out_data.data.reg_args.action = action; - //send and recv - usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_REG); + // send and recv + usrp2_ctrl_data_t in_data = + this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_REG); UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_OMG_GOT_REGISTER_SO_BAD_DUDE); return T(ntohl(in_data.data.reg_args.data)); } -/*********************************************************************** - * SPI - **********************************************************************/ - uint32_t transact_spi( - int which_slave, - const spi_config_t &config, + /*********************************************************************** + * SPI + **********************************************************************/ + uint32_t transact_spi(int which_slave, + const spi_config_t& config, uint32_t data, size_t num_bits, - bool readback - ){ - static const uhd::dict<spi_config_t::edge_t, int> spi_edge_to_otw = boost::assign::map_list_of - (spi_config_t::EDGE_RISE, USRP2_CLK_EDGE_RISE) - (spi_config_t::EDGE_FALL, USRP2_CLK_EDGE_FALL) - ; - - //setup the out data - usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t(); - out_data.id = htonl(USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO); - out_data.data.spi_args.dev = htonl(which_slave); + bool readback) + { + static const uhd::dict<spi_config_t::edge_t, int> spi_edge_to_otw = + boost::assign::map_list_of(spi_config_t::EDGE_RISE, USRP2_CLK_EDGE_RISE)( + spi_config_t::EDGE_FALL, USRP2_CLK_EDGE_FALL); + + // setup the out data + usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t(); + out_data.id = htonl(USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO); + out_data.data.spi_args.dev = htonl(which_slave); out_data.data.spi_args.miso_edge = spi_edge_to_otw[config.miso_edge]; out_data.data.spi_args.mosi_edge = spi_edge_to_otw[config.mosi_edge]; - out_data.data.spi_args.readback = (readback)? 1 : 0; - out_data.data.spi_args.num_bits = num_bits; - out_data.data.spi_args.data = htonl(data); + out_data.data.spi_args.readback = (readback) ? 1 : 0; + out_data.data.spi_args.num_bits = num_bits; + out_data.data.spi_args.data = htonl(data); - //send and recv - usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_SPI); + // send and recv + usrp2_ctrl_data_t in_data = + this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_SPI); UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE); return ntohl(in_data.data.spi_args.data); } -/*********************************************************************** - * I2C - **********************************************************************/ - void write_i2c(uint16_t addr, const byte_vector_t &buf){ - //setup the out data - usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t(); - out_data.id = htonl(USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO); - out_data.data.i2c_args.addr = uint8_t(addr); + /*********************************************************************** + * I2C + **********************************************************************/ + void write_i2c(uint16_t addr, const byte_vector_t& buf) + { + // setup the out data + usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t(); + out_data.id = htonl(USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO); + out_data.data.i2c_args.addr = uint8_t(addr); out_data.data.i2c_args.bytes = buf.size(); - //limitation of i2c transaction size + // limitation of i2c transaction size UHD_ASSERT_THROW(buf.size() <= sizeof(out_data.data.i2c_args.data)); - //copy in the data + // copy in the data std::copy(buf.begin(), buf.end(), out_data.data.i2c_args.data); - //send and recv - usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_I2C); + // send and recv + usrp2_ctrl_data_t in_data = + this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_I2C); UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE); } - byte_vector_t read_i2c(uint16_t addr, size_t num_bytes){ - //setup the out data - usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t(); - out_data.id = htonl(USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO); - out_data.data.i2c_args.addr = uint8_t(addr); + byte_vector_t read_i2c(uint16_t addr, size_t num_bytes) + { + // setup the out data + usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t(); + out_data.id = htonl(USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO); + out_data.data.i2c_args.addr = uint8_t(addr); out_data.data.i2c_args.bytes = num_bytes; - //limitation of i2c transaction size + // limitation of i2c transaction size UHD_ASSERT_THROW(num_bytes <= sizeof(out_data.data.i2c_args.data)); - //send and recv - usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_I2C); + // send and recv + usrp2_ctrl_data_t in_data = + this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_I2C); UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE); UHD_ASSERT_THROW(in_data.data.i2c_args.bytes == num_bytes); - //copy out the data + // copy out the data byte_vector_t result(num_bytes); - std::copy(in_data.data.i2c_args.data, in_data.data.i2c_args.data + num_bytes, result.begin()); + std::copy(in_data.data.i2c_args.data, + in_data.data.i2c_args.data + num_bytes, + result.begin()); return result; } -/*********************************************************************** - * Send/Recv over control - **********************************************************************/ - usrp2_ctrl_data_t ctrl_send_and_recv( - const usrp2_ctrl_data_t &out_data, + /*********************************************************************** + * Send/Recv over control + **********************************************************************/ + usrp2_ctrl_data_t ctrl_send_and_recv(const usrp2_ctrl_data_t& out_data, uint32_t lo = USRP2_FW_COMPAT_NUM, - uint32_t hi = USRP2_FW_COMPAT_NUM - ){ + uint32_t hi = USRP2_FW_COMPAT_NUM) + { boost::mutex::scoped_lock lock(_ctrl_mutex); - for (size_t i = 0; i < CTRL_RECV_RETRIES; i++){ - try{ - return ctrl_send_and_recv_internal(out_data, lo, hi, CTRL_RECV_TIMEOUT/CTRL_RECV_RETRIES); - } - catch(const timeout_error &e){ + for (size_t i = 0; i < CTRL_RECV_RETRIES; i++) { + try { + return ctrl_send_and_recv_internal( + out_data, lo, hi, CTRL_RECV_TIMEOUT / CTRL_RECV_RETRIES); + } catch (const timeout_error& e) { UHD_LOGGER_ERROR("USRP2") - << "Control packet attempt " << i - << ", sequence number " << _ctrl_seq_num - << ":\n" << e.what() ; + << "Control packet attempt " << i << ", sequence number " + << _ctrl_seq_num << ":\n" + << e.what(); } } throw uhd::runtime_error("link dead: timeout waiting for control packet ACK"); } usrp2_ctrl_data_t ctrl_send_and_recv_internal( - const usrp2_ctrl_data_t &out_data, - uint32_t lo, uint32_t hi, - const double timeout - ){ - //fill in the seq number and send + const usrp2_ctrl_data_t& out_data, uint32_t lo, uint32_t hi, const double timeout) + { + // fill in the seq number and send usrp2_ctrl_data_t out_copy = out_data; - out_copy.proto_ver = htonl(_protocol_compat); - out_copy.seq = htonl(++_ctrl_seq_num); + out_copy.proto_ver = htonl(_protocol_compat); + out_copy.seq = htonl(++_ctrl_seq_num); _ctrl_transport->send(boost::asio::buffer(&out_copy, sizeof(usrp2_ctrl_data_t))); - //loop until we get the packet or timeout - uint8_t usrp2_ctrl_data_in_mem[udp_simple::mtu]; //allocate max bytes for recv - const usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast<const usrp2_ctrl_data_t *>(usrp2_ctrl_data_in_mem); - while(true){ - size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem), timeout); + // loop until we get the packet or timeout + uint8_t usrp2_ctrl_data_in_mem[udp_simple::mtu]; // allocate max bytes for recv + const usrp2_ctrl_data_t* ctrl_data_in = + reinterpret_cast<const usrp2_ctrl_data_t*>(usrp2_ctrl_data_in_mem); + while (true) { + size_t len = _ctrl_transport->recv( + boost::asio::buffer(usrp2_ctrl_data_in_mem), timeout); uint32_t compat = ntohl(ctrl_data_in->proto_ver); - if(len >= sizeof(uint32_t) and (hi < compat or lo > compat)){ - throw uhd::runtime_error(str(boost::format( - "\nPlease update the firmware and FPGA images for your device.\n" - "See the application notes for USRP2/N-Series for instructions.\n" - "Expected protocol compatibility number %s, but got %d:\n" - "The firmware build is not compatible with the host code build.\n" - "%s\n" - ) % ((lo == hi)? (boost::format("%d") % hi) : (boost::format("[%d to %d]") % lo % hi)) - % compat % this->images_warn_help_message())); + if (len >= sizeof(uint32_t) and (hi < compat or lo > compat)) { + throw uhd::runtime_error(str( + boost::format( + "\nPlease update the firmware and FPGA images for your device.\n" + "See the application notes for USRP2/N-Series for instructions.\n" + "Expected protocol compatibility number %s, but got %d:\n" + "The firmware build is not compatible with the host code build.\n" + "%s\n") + % ((lo == hi) ? (boost::format("%d") % hi) + : (boost::format("[%d to %d]") % lo % hi)) + % compat % this->images_warn_help_message())); } - if (len >= sizeof(usrp2_ctrl_data_t) and ntohl(ctrl_data_in->seq) == _ctrl_seq_num){ + if (len >= sizeof(usrp2_ctrl_data_t) + and ntohl(ctrl_data_in->seq) == _ctrl_seq_num) { return *ctrl_data_in; } - if (len == 0) break; //timeout - //didnt get seq or bad packet, continue looking... + if (len == 0) + break; // timeout + // didnt get seq or bad packet, continue looking... } throw timeout_error("no control response, possible packet loss"); } - rev_type get_rev(void){ + rev_type get_rev(void) + { std::string hw = mb_eeprom["hardware"]; - if (hw.empty()) return USRP_NXXX; - switch (boost::lexical_cast<uint16_t>(hw)){ - case 0x0300: - case 0x0301: return USRP2_REV3; - case 0x0400: return USRP2_REV4; - case 0x0A00: return USRP_N200; - case 0x0A01: return USRP_N210; - case 0x0A10: return USRP_N200_R4; - case 0x0A11: return USRP_N210_R4; + if (hw.empty()) + return USRP_NXXX; + switch (boost::lexical_cast<uint16_t>(hw)) { + case 0x0300: + case 0x0301: + return USRP2_REV3; + case 0x0400: + return USRP2_REV4; + case 0x0A00: + return USRP_N200; + case 0x0A01: + return USRP_N210; + case 0x0A10: + return USRP_N200_R4; + case 0x0A11: + return USRP_N210_R4; } - return USRP_NXXX; //unknown type + return USRP_NXXX; // unknown type } - const std::string get_cname(void){ - switch(this->get_rev()){ - case USRP2_REV3: return "USRP2 r3"; - case USRP2_REV4: return "USRP2 r4"; - case USRP_N200: return "N200"; - case USRP_N210: return "N210"; - case USRP_N200_R4: return "N200r4"; - case USRP_N210_R4: return "N210r4"; - case USRP_NXXX: return "N???"; + const std::string get_cname(void) + { + switch (this->get_rev()) { + case USRP2_REV3: + return "USRP2 r3"; + case USRP2_REV4: + return "USRP2 r4"; + case USRP_N200: + return "N200"; + case USRP_N210: + return "N210"; + case USRP_N200_R4: + return "N200r4"; + case USRP_N210_R4: + return "N210r4"; + case USRP_NXXX: + return "N???"; } UHD_THROW_INVALID_CODE_PATH(); } - const std::string get_fw_version_string(void){ - uint32_t minor = this->get_reg<uint32_t, USRP2_REG_ACTION_FW_PEEK32>(U2_FW_REG_VER_MINOR); + const std::string get_fw_version_string(void) + { + uint32_t minor = + this->get_reg<uint32_t, USRP2_REG_ACTION_FW_PEEK32>(U2_FW_REG_VER_MINOR); return str(boost::format("%u.%u") % _protocol_compat % minor); } - std::string images_warn_help_message(void){ - //determine the images names + std::string images_warn_help_message(void) + { + // determine the images names std::string fw_image, fpga_image; - switch(this->get_rev()){ - case USRP2_REV3: fpga_image = "usrp2_fpga.bin"; fw_image = "usrp2_fw.bin"; break; - case USRP2_REV4: fpga_image = "usrp2_fpga.bin"; fw_image = "usrp2_fw.bin"; break; - case USRP_N200: fpga_image = "usrp_n200_r2_fpga.bin"; fw_image = "usrp_n200_fw.bin"; break; - case USRP_N210: fpga_image = "usrp_n210_r2_fpga.bin"; fw_image = "usrp_n210_fw.bin"; break; - case USRP_N200_R4: fpga_image = "usrp_n200_r4_fpga.bin"; fw_image = "usrp_n200_fw.bin"; break; - case USRP_N210_R4: fpga_image = "usrp_n210_r4_fpga.bin"; fw_image = "usrp_n210_fw.bin"; break; - default: break; + switch (this->get_rev()) { + case USRP2_REV3: + fpga_image = "usrp2_fpga.bin"; + fw_image = "usrp2_fw.bin"; + break; + case USRP2_REV4: + fpga_image = "usrp2_fpga.bin"; + fw_image = "usrp2_fw.bin"; + break; + case USRP_N200: + fpga_image = "usrp_n200_r2_fpga.bin"; + fw_image = "usrp_n200_fw.bin"; + break; + case USRP_N210: + fpga_image = "usrp_n210_r2_fpga.bin"; + fw_image = "usrp_n210_fw.bin"; + break; + case USRP_N200_R4: + fpga_image = "usrp_n200_r4_fpga.bin"; + fw_image = "usrp_n200_fw.bin"; + break; + case USRP_N210_R4: + fpga_image = "usrp_n210_r4_fpga.bin"; + fw_image = "usrp_n210_fw.bin"; + break; + default: + break; } - if (fw_image.empty() or fpga_image.empty()) return ""; + if (fw_image.empty() or fpga_image.empty()) + return ""; - //does your platform use sudo? + // does your platform use sudo? std::string sudo; - #if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_MACOS) - sudo = "sudo "; - #endif +#if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_MACOS) + sudo = "sudo "; +#endif - //look up the real FS path to the images + // look up the real FS path to the images std::string fw_image_path, fpga_image_path; - try{ - fw_image_path = uhd::find_image_path(fw_image); + try { + fw_image_path = uhd::find_image_path(fw_image); fpga_image_path = uhd::find_image_path(fpga_image); - } - catch(const std::exception &){ - return str(boost::format("Could not find %s and %s in your images path!\n%s") % fw_image % fpga_image % print_utility_error("uhd_images_downloader.py")); + } catch (const std::exception&) { + return str(boost::format("Could not find %s and %s in your images path!\n%s") + % fw_image % fpga_image + % print_utility_error("uhd_images_downloader.py")); } - //escape char for multi-line cmd + newline + indent? - #ifdef UHD_PLATFORM_WIN32 - const std::string ml = "^\n "; - #else - const std::string ml = "\\\n "; - #endif +// escape char for multi-line cmd + newline + indent? +#ifdef UHD_PLATFORM_WIN32 + const std::string ml = "^\n "; +#else + const std::string ml = "\\\n "; +#endif - //create the burner commands - if (this->get_rev() == USRP2_REV3 or this->get_rev() == USRP2_REV4){ + // create the burner commands + if (this->get_rev() == USRP2_REV3 or this->get_rev() == USRP2_REV4) { const std::string card_burner = uhd::find_utility("usrp2_card_burner_gui.py"); - const std::string card_burner_cmd = str(boost::format(" %s\"%s\" %s--fpga=\"%s\" %s--fw=\"%s\"") % sudo % card_burner % ml % fpga_image_path % ml % fw_image_path); - return str(boost::format("%s\n%s") % print_utility_error("uhd_images_downloader.py") % card_burner_cmd); - } - else{ + const std::string card_burner_cmd = + str(boost::format(" %s\"%s\" %s--fpga=\"%s\" %s--fw=\"%s\"") % sudo + % card_burner % ml % fpga_image_path % ml % fw_image_path); + return str(boost::format("%s\n%s") + % print_utility_error("uhd_images_downloader.py") + % card_burner_cmd); + } else { const std::string addr = _ctrl_transport->get_recv_addr(); - const std::string image_loader_path = (fs::path(uhd::get_pkg_path()) / "bin" / "uhd_image_loader").string(); - const std::string image_loader_cmd = str(boost::format(" \"%s\" %s--args=\"type=usrp2,addr=%s\"") % image_loader_path % ml % addr); - return str(boost::format("%s\n%s") % print_utility_error("uhd_images_downloader.py") % image_loader_cmd); + const std::string image_loader_path = + (fs::path(uhd::get_pkg_path()) / "bin" / "uhd_image_loader").string(); + const std::string image_loader_cmd = + str(boost::format(" \"%s\" %s--args=\"type=usrp2,addr=%s\"") + % image_loader_path % ml % addr); + return str(boost::format("%s\n%s") + % print_utility_error("uhd_images_downloader.py") + % image_loader_cmd); } } @@ -399,22 +468,22 @@ public: } private: - //this lovely lady makes it all possible + // this lovely lady makes it all possible udp_simple::sptr _ctrl_transport; - //used in send/recv + // used in send/recv boost::mutex _ctrl_mutex; uint32_t _ctrl_seq_num; uint32_t _protocol_compat; - //lock thread stuff + // lock thread stuff task::sptr _lock_task; }; /*********************************************************************** * Public make function for usrp2 interface **********************************************************************/ -usrp2_iface::sptr usrp2_iface::make(udp_simple::sptr ctrl_transport){ +usrp2_iface::sptr usrp2_iface::make(udp_simple::sptr ctrl_transport) +{ return usrp2_iface::sptr(new usrp2_iface_impl(ctrl_transport)); } - diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp index b602dab53..8d1700974 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.hpp +++ b/host/lib/usrp/usrp2/usrp2_iface.hpp @@ -8,14 +8,14 @@ #ifndef INCLUDED_USRP2_IFACE_HPP #define INCLUDED_USRP2_IFACE_HPP +#include "usrp2_regs.hpp" #include <uhd/transport/udp_simple.hpp> #include <uhd/types/serial.hpp> +#include <uhd/types/wb_iface.hpp> #include <uhd/usrp/mboard_eeprom.hpp> -#include <memory> #include <boost/utility.hpp> #include <functional> -#include "usrp2_regs.hpp" -#include <uhd/types/wb_iface.hpp> +#include <memory> #include <string> /*! @@ -23,7 +23,9 @@ * Provides a set of functions to implementation layer. * Including spi, peek, poke, control... */ -class usrp2_iface : public uhd::timed_wb_iface, public uhd::spi_iface, public uhd::i2c_iface +class usrp2_iface : public uhd::timed_wb_iface, + public uhd::spi_iface, + public uhd::i2c_iface { public: typedef std::shared_ptr<usrp2_iface> sptr; @@ -42,13 +44,13 @@ public: //! The list of possible revision types enum rev_type { - USRP2_REV3 = 3, - USRP2_REV4 = 4, - USRP_N200 = 200, + USRP2_REV3 = 3, + USRP2_REV4 = 4, + USRP_N200 = 200, USRP_N200_R4 = 201, - USRP_N210 = 210, + USRP_N210 = 210, USRP_N210_R4 = 211, - USRP_NXXX = 0 + USRP_NXXX = 0 }; //! Get the revision type for this device @@ -69,7 +71,7 @@ public: //! Construct a helpful warning message for images virtual std::string images_warn_help_message(void) = 0; - //motherboard eeprom map structure + // motherboard eeprom map structure uhd::usrp::mboard_eeprom_t mb_eeprom; }; diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index fd35f3a1d..6fed1521a 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -26,151 +26,155 @@ using namespace uhd::usrp; using namespace uhd::transport; namespace asio = boost::asio; -//A reasonable number of frames for send/recv and async/sync +// A reasonable number of frames for send/recv and async/sync static const size_t DEFAULT_NUM_FRAMES = 32; /*********************************************************************** * Discovery over the udp transport **********************************************************************/ -device_addrs_t usrp2_find(const device_addr_t &hint_){ - //handle the multi-device discovery +device_addrs_t usrp2_find(const device_addr_t& hint_) +{ + // handle the multi-device discovery device_addrs_t hints = separate_device_addr(hint_); - if (hints.size() > 1){ + if (hints.size() > 1) { device_addrs_t found_devices; std::string error_msg; - for(const device_addr_t &hint_i: hints){ + for (const device_addr_t& hint_i : hints) { device_addrs_t found_devices_i = usrp2_find(hint_i); - if (found_devices_i.size() != 1) error_msg += str(boost::format( - "Could not resolve device hint \"%s\" to a single device." - ) % hint_i.to_string()); - else found_devices.push_back(found_devices_i[0]); + if (found_devices_i.size() != 1) + error_msg += + str(boost::format( + "Could not resolve device hint \"%s\" to a single device.") + % hint_i.to_string()); + else + found_devices.push_back(found_devices_i[0]); } - if (found_devices.empty()) return device_addrs_t(); - if (not error_msg.empty()) throw uhd::value_error(error_msg); + if (found_devices.empty()) + return device_addrs_t(); + if (not error_msg.empty()) + throw uhd::value_error(error_msg); return device_addrs_t(1, combine_device_addrs(found_devices)); } - //initialize the hint for a single device case + // initialize the hint for a single device case UHD_ASSERT_THROW(hints.size() <= 1); - hints.resize(1); //in case it was empty + hints.resize(1); // in case it was empty device_addr_t hint = hints[0]; device_addrs_t usrp2_addrs; - //return an empty list of addresses when type is set to non-usrp2 - if (hint.has_key("type") and hint["type"] != "usrp2") return usrp2_addrs; + // return an empty list of addresses when type is set to non-usrp2 + if (hint.has_key("type") and hint["type"] != "usrp2") + return usrp2_addrs; - //Return an empty list of addresses when a resource is specified, - //since a resource is intended for a different, non-USB, device. - if (hint.has_key("resource")) return usrp2_addrs; + // Return an empty list of addresses when a resource is specified, + // since a resource is intended for a different, non-USB, device. + if (hint.has_key("resource")) + return usrp2_addrs; - //if no address was specified, send a broadcast on each interface - if (not hint.has_key("addr")){ - for(const if_addrs_t &if_addrs: get_if_addrs()){ - //avoid the loopback device - if (if_addrs.inet == asio::ip::address_v4::loopback().to_string()) continue; + // if no address was specified, send a broadcast on each interface + if (not hint.has_key("addr")) { + for (const if_addrs_t& if_addrs : get_if_addrs()) { + // avoid the loopback device + if (if_addrs.inet == asio::ip::address_v4::loopback().to_string()) + continue; - //create a new hint with this broadcast address + // create a new hint with this broadcast address device_addr_t new_hint = hint; - new_hint["addr"] = if_addrs.bcast; + new_hint["addr"] = if_addrs.bcast; - //call discover with the new hint and append results + // call discover with the new hint and append results device_addrs_t new_usrp2_addrs = usrp2_find(new_hint); - usrp2_addrs.insert(usrp2_addrs.begin(), - new_usrp2_addrs.begin(), new_usrp2_addrs.end() - ); + usrp2_addrs.insert( + usrp2_addrs.begin(), new_usrp2_addrs.begin(), new_usrp2_addrs.end()); } return usrp2_addrs; } - //Create a UDP transport to communicate: - //Some devices will cause a throw when opened for a broadcast address. - //We print and recover so the caller can loop through all bcast addrs. + // Create a UDP transport to communicate: + // Some devices will cause a throw when opened for a broadcast address. + // We print and recover so the caller can loop through all bcast addrs. udp_simple::sptr udp_transport; - try{ - udp_transport = udp_simple::make_broadcast(hint["addr"], BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT)); - } - catch(const std::exception &e){ - UHD_LOGGER_ERROR("USRP2") << boost::format("Cannot open UDP transport on %s\n%s") % hint["addr"] % e.what() ; - return usrp2_addrs; //dont throw, but return empty address so caller can insert + try { + udp_transport = udp_simple::make_broadcast( + hint["addr"], BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT)); + } catch (const std::exception& e) { + UHD_LOGGER_ERROR("USRP2") << boost::format("Cannot open UDP transport on %s\n%s") + % hint["addr"] % e.what(); + return usrp2_addrs; // dont throw, but return empty address so caller can insert } - //send a hello control packet + // send a hello control packet usrp2_ctrl_data_t ctrl_data_out = usrp2_ctrl_data_t(); - ctrl_data_out.proto_ver = uhd::htonx<uint32_t>(USRP2_FW_COMPAT_NUM); - ctrl_data_out.id = uhd::htonx<uint32_t>(USRP2_CTRL_ID_WAZZUP_BRO); - try - { + ctrl_data_out.proto_ver = uhd::htonx<uint32_t>(USRP2_FW_COMPAT_NUM); + ctrl_data_out.id = uhd::htonx<uint32_t>(USRP2_CTRL_ID_WAZZUP_BRO); + try { udp_transport->send(boost::asio::buffer(&ctrl_data_out, sizeof(ctrl_data_out))); - } - catch(const std::exception &ex) - { - UHD_LOGGER_ERROR("USRP2") << "USRP2 Network discovery error " << ex.what() ; - } - catch(...) - { - UHD_LOGGER_ERROR("USRP2") << "USRP2 Network discovery unknown error " ; + } catch (const std::exception& ex) { + UHD_LOGGER_ERROR("USRP2") << "USRP2 Network discovery error " << ex.what(); + } catch (...) { + UHD_LOGGER_ERROR("USRP2") << "USRP2 Network discovery unknown error "; } - //loop and recieve until the timeout - uint8_t usrp2_ctrl_data_in_mem[udp_simple::mtu]; //allocate max bytes for recv - const usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast<const usrp2_ctrl_data_t *>(usrp2_ctrl_data_in_mem); - while(true){ + // loop and recieve until the timeout + uint8_t usrp2_ctrl_data_in_mem[udp_simple::mtu]; // allocate max bytes for recv + const usrp2_ctrl_data_t* ctrl_data_in = + reinterpret_cast<const usrp2_ctrl_data_t*>(usrp2_ctrl_data_in_mem); + while (true) { size_t len = udp_transport->recv(asio::buffer(usrp2_ctrl_data_in_mem)); - if (len > offsetof(usrp2_ctrl_data_t, data) and ntohl(ctrl_data_in->id) == USRP2_CTRL_ID_WAZZUP_DUDE){ - - //make a boost asio ipv4 with the raw addr in host byte order + if (len > offsetof(usrp2_ctrl_data_t, data) + and ntohl(ctrl_data_in->id) == USRP2_CTRL_ID_WAZZUP_DUDE) { + // make a boost asio ipv4 with the raw addr in host byte order device_addr_t new_addr; new_addr["type"] = "usrp2"; - //We used to get the address from the control packet. - //Now now uses the socket itself to yield the address. - //boost::asio::ip::address_v4 ip_addr(ntohl(ctrl_data_in->data.ip_addr)); - //new_addr["addr"] = ip_addr.to_string(); + // We used to get the address from the control packet. + // Now now uses the socket itself to yield the address. + // boost::asio::ip::address_v4 ip_addr(ntohl(ctrl_data_in->data.ip_addr)); + // new_addr["addr"] = ip_addr.to_string(); new_addr["addr"] = udp_transport->get_recv_addr(); - //Attempt a simple 2-way communication with a connected socket. - //Reason: Although the USRP will respond the broadcast above, - //we may not be able to communicate directly (non-broadcast). + // Attempt a simple 2-way communication with a connected socket. + // Reason: Although the USRP will respond the broadcast above, + // we may not be able to communicate directly (non-broadcast). udp_simple::sptr ctrl_xport = udp_simple::make_connected( - new_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT) - ); + new_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT)); ctrl_xport->send(boost::asio::buffer(&ctrl_data_out, sizeof(ctrl_data_out))); size_t len = ctrl_xport->recv(asio::buffer(usrp2_ctrl_data_in_mem)); - if (len > offsetof(usrp2_ctrl_data_t, data) and ntohl(ctrl_data_in->id) == USRP2_CTRL_ID_WAZZUP_DUDE){ - //found the device, open up for communication! - } - else{ - //otherwise we don't find it... + if (len > offsetof(usrp2_ctrl_data_t, data) + and ntohl(ctrl_data_in->id) == USRP2_CTRL_ID_WAZZUP_DUDE) { + // found the device, open up for communication! + } else { + // otherwise we don't find it... continue; } - //Attempt to read the name from the EEPROM and perform filtering. - //This operation can throw due to compatibility mismatch. - try{ + // Attempt to read the name from the EEPROM and perform filtering. + // This operation can throw due to compatibility mismatch. + try { usrp2_iface::sptr iface = usrp2_iface::make(ctrl_xport); - if (iface->is_device_locked()) continue; //ignore locked devices + if (iface->is_device_locked()) + continue; // ignore locked devices mboard_eeprom_t mb_eeprom = iface->mb_eeprom; - new_addr["name"] = mb_eeprom["name"]; - new_addr["serial"] = mb_eeprom["serial"]; - } - catch(const std::exception &){ - //set these values as empty string so the device may still be found - //and the filter's below can still operate on the discovered device - new_addr["name"] = ""; + new_addr["name"] = mb_eeprom["name"]; + new_addr["serial"] = mb_eeprom["serial"]; + } catch (const std::exception&) { + // set these values as empty string so the device may still be found + // and the filter's below can still operate on the discovered device + new_addr["name"] = ""; new_addr["serial"] = ""; } - //filter the discovered device below by matching optional keys - if ( - (not hint.has_key("name") or hint["name"] == new_addr["name"]) and - (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) - ){ + // filter the discovered device below by matching optional keys + if ((not hint.has_key("name") or hint["name"] == new_addr["name"]) + and (not hint.has_key("serial") + or hint["serial"] == new_addr["serial"])) { usrp2_addrs.push_back(new_addr); } - //dont break here, it will exit the while loop - //just continue on to the next loop iteration + // dont break here, it will exit the while loop + // just continue on to the next loop iteration } - if (len == 0) break; //timeout + if (len == 0) + break; // timeout } return usrp2_addrs; @@ -179,36 +183,39 @@ device_addrs_t usrp2_find(const device_addr_t &hint_){ /*********************************************************************** * Make **********************************************************************/ -static device::sptr usrp2_make(const device_addr_t &device_addr){ +static device::sptr usrp2_make(const device_addr_t& device_addr) +{ return device::sptr(new usrp2_impl(device_addr)); } -UHD_STATIC_BLOCK(register_usrp2_device){ +UHD_STATIC_BLOCK(register_usrp2_device) +{ device::register_device(&usrp2_find, &usrp2_make, device::USRP); } /*********************************************************************** * MTU Discovery **********************************************************************/ -struct mtu_result_t{ +struct mtu_result_t +{ size_t recv_mtu, send_mtu; }; -static mtu_result_t determine_mtu(const std::string &addr, const mtu_result_t &user_mtu){ - udp_simple::sptr udp_sock = udp_simple::make_connected( - addr, BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT) - ); +static mtu_result_t determine_mtu(const std::string& addr, const mtu_result_t& user_mtu) +{ + udp_simple::sptr udp_sock = + udp_simple::make_connected(addr, BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT)); - //The FPGA offers 4K buffers, and the user may manually request this. - //However, multiple simultaneous receives (2DSP slave + 2DSP master), - //require that buffering to be used internally, and this is a safe setting. + // The FPGA offers 4K buffers, and the user may manually request this. + // However, multiple simultaneous receives (2DSP slave + 2DSP master), + // require that buffering to be used internally, and this is a safe setting. std::vector<uint8_t> buffer(std::max(user_mtu.recv_mtu, user_mtu.send_mtu)); - usrp2_ctrl_data_t *ctrl_data = reinterpret_cast<usrp2_ctrl_data_t *>(&buffer.front()); - static const double echo_timeout = 0.020; //20 ms + usrp2_ctrl_data_t* ctrl_data = reinterpret_cast<usrp2_ctrl_data_t*>(&buffer.front()); + static const double echo_timeout = 0.020; // 20 ms - //test holler - check if its supported in this fw version - ctrl_data->id = htonl(USRP2_CTRL_ID_HOLLER_AT_ME_BRO); - ctrl_data->proto_ver = htonl(USRP2_FW_COMPAT_NUM); + // test holler - check if its supported in this fw version + ctrl_data->id = htonl(USRP2_CTRL_ID_HOLLER_AT_ME_BRO); + ctrl_data->proto_ver = htonl(USRP2_FW_COMPAT_NUM); ctrl_data->data.echo_args.len = htonl(sizeof(usrp2_ctrl_data_t)); udp_sock->send(boost::asio::buffer(buffer, sizeof(usrp2_ctrl_data_t))); udp_sock->recv(boost::asio::buffer(buffer), echo_timeout); @@ -218,36 +225,38 @@ static mtu_result_t determine_mtu(const std::string &addr, const mtu_result_t &u size_t min_recv_mtu = sizeof(usrp2_ctrl_data_t), max_recv_mtu = user_mtu.recv_mtu; size_t min_send_mtu = sizeof(usrp2_ctrl_data_t), max_send_mtu = user_mtu.send_mtu; - while (min_recv_mtu < max_recv_mtu){ + while (min_recv_mtu < max_recv_mtu) { + size_t test_mtu = (max_recv_mtu / 2 + min_recv_mtu / 2 + 3) & ~3; - size_t test_mtu = (max_recv_mtu/2 + min_recv_mtu/2 + 3) & ~3; - - ctrl_data->id = htonl(USRP2_CTRL_ID_HOLLER_AT_ME_BRO); - ctrl_data->proto_ver = htonl(USRP2_FW_COMPAT_NUM); + ctrl_data->id = htonl(USRP2_CTRL_ID_HOLLER_AT_ME_BRO); + ctrl_data->proto_ver = htonl(USRP2_FW_COMPAT_NUM); ctrl_data->data.echo_args.len = htonl(test_mtu); udp_sock->send(boost::asio::buffer(buffer, sizeof(usrp2_ctrl_data_t))); size_t len = udp_sock->recv(boost::asio::buffer(buffer), echo_timeout); - if (len >= test_mtu) min_recv_mtu = test_mtu; - else max_recv_mtu = test_mtu - 4; - + if (len >= test_mtu) + min_recv_mtu = test_mtu; + else + max_recv_mtu = test_mtu - 4; } - while (min_send_mtu < max_send_mtu){ - - size_t test_mtu = (max_send_mtu/2 + min_send_mtu/2 + 3) & ~3; + while (min_send_mtu < max_send_mtu) { + size_t test_mtu = (max_send_mtu / 2 + min_send_mtu / 2 + 3) & ~3; - ctrl_data->id = htonl(USRP2_CTRL_ID_HOLLER_AT_ME_BRO); - ctrl_data->proto_ver = htonl(USRP2_FW_COMPAT_NUM); + ctrl_data->id = htonl(USRP2_CTRL_ID_HOLLER_AT_ME_BRO); + ctrl_data->proto_ver = htonl(USRP2_FW_COMPAT_NUM); ctrl_data->data.echo_args.len = htonl(sizeof(usrp2_ctrl_data_t)); udp_sock->send(boost::asio::buffer(buffer, test_mtu)); size_t len = udp_sock->recv(boost::asio::buffer(buffer), echo_timeout); - if (len >= sizeof(usrp2_ctrl_data_t)) len = ntohl(ctrl_data->data.echo_args.len); + if (len >= sizeof(usrp2_ctrl_data_t)) + len = ntohl(ctrl_data->data.echo_args.len); - if (len >= test_mtu) min_send_mtu = test_mtu; - else max_send_mtu = test_mtu - 4; + if (len >= test_mtu) + min_send_mtu = test_mtu; + else + max_send_mtu = test_mtu - 4; } mtu_result_t mtu; @@ -259,17 +268,16 @@ static mtu_result_t determine_mtu(const std::string &addr, const mtu_result_t &u /*********************************************************************** * Helpers **********************************************************************/ -static zero_copy_if::sptr make_xport( - const std::string &addr, - const std::string &port, - const device_addr_t &hints, - const std::string &filter -){ - - //only copy hints that contain the filter word +static zero_copy_if::sptr make_xport(const std::string& addr, + const std::string& port, + const device_addr_t& hints, + const std::string& filter) +{ + // only copy hints that contain the filter word device_addr_t filtered_hints; - for(const std::string &key: hints.keys()){ - if (key.find(filter) == std::string::npos) continue; + for (const std::string& key : hints.keys()) { + if (key.find(filter) == std::string::npos) + continue; filtered_hints[key] = hints[key]; } @@ -279,17 +287,16 @@ static zero_copy_if::sptr make_xport( default_buff_args.num_send_frames = DEFAULT_NUM_FRAMES; default_buff_args.num_recv_frames = DEFAULT_NUM_FRAMES; - //make the transport object with the filtered hints + // make the transport object with the filtered hints udp_zero_copy::buff_params ignored_params; - zero_copy_if::sptr xport = udp_zero_copy::make(addr, port, default_buff_args, ignored_params, filtered_hints); - - //Send a small data packet so the usrp2 knows the udp source port. - //This setup must happen before further initialization occurs - //or the async update packets will cause ICMP destination unreachable. - static const uint32_t data[2] = { - uhd::htonx(uint32_t(0 /* don't care seq num */)), - uhd::htonx(uint32_t(USRP2_INVALID_VRT_HEADER)) - }; + zero_copy_if::sptr xport = udp_zero_copy::make( + addr, port, default_buff_args, ignored_params, filtered_hints); + + // Send a small data packet so the usrp2 knows the udp source port. + // This setup must happen before further initialization occurs + // or the async update packets will cause ICMP destination unreachable. + static const uint32_t data[2] = {uhd::htonx(uint32_t(0 /* don't care seq num */)), + uhd::htonx(uint32_t(USRP2_INVALID_VRT_HEADER))}; transport::managed_send_buffer::sptr send_buff = xport->get_send_buff(); std::memcpy(send_buff->cast<void*>(), &data, sizeof(data)); send_buff->commit(sizeof(data)); @@ -300,157 +307,161 @@ static zero_copy_if::sptr make_xport( /*********************************************************************** * Structors **********************************************************************/ -usrp2_impl::usrp2_impl(const device_addr_t &_device_addr) : - device_addr(_device_addr), - _pirate_task_exit(false) +usrp2_impl::usrp2_impl(const device_addr_t& _device_addr) + : device_addr(_device_addr), _pirate_task_exit(false) { UHD_LOGGER_INFO("USRP2") << "Opening a USRP2/N-Series device..."; - //setup the dsp transport hints (default to a large recv buff) - if (not device_addr.has_key("recv_buff_size")){ - #if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) - //limit buffer resize on macos or it will error - device_addr["recv_buff_size"] = "1e6"; - #elif defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) - //set to half-a-second of buffering at max rate - device_addr["recv_buff_size"] = "50e6"; - #endif + // setup the dsp transport hints (default to a large recv buff) + if (not device_addr.has_key("recv_buff_size")) { +#if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) + // limit buffer resize on macos or it will error + device_addr["recv_buff_size"] = "1e6"; +#elif defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) + // set to half-a-second of buffering at max rate + device_addr["recv_buff_size"] = "50e6"; +#endif } - if (not device_addr.has_key("send_buff_size")){ - //The buffer should be the size of the SRAM on the device, - //because we will never commit more than the SRAM can hold. + if (not device_addr.has_key("send_buff_size")) { + // The buffer should be the size of the SRAM on the device, + // because we will never commit more than the SRAM can hold. device_addr["send_buff_size"] = std::to_string(USRP2_SRAM_BYTES); } device_addrs_t device_args = separate_device_addr(device_addr); - //extract the user's requested MTU size or default + // extract the user's requested MTU size or default mtu_result_t user_mtu; - user_mtu.recv_mtu = size_t(device_addr.cast<double>("recv_frame_size", udp_simple::mtu)); - user_mtu.send_mtu = size_t(device_addr.cast<double>("send_frame_size", udp_simple::mtu)); + user_mtu.recv_mtu = + size_t(device_addr.cast<double>("recv_frame_size", udp_simple::mtu)); + user_mtu.send_mtu = + size_t(device_addr.cast<double>("send_frame_size", udp_simple::mtu)); - try{ - //calculate the minimum send and recv mtu of all devices + try { + // calculate the minimum send and recv mtu of all devices mtu_result_t mtu = determine_mtu(device_args[0]["addr"], user_mtu); - for (size_t i = 1; i < device_args.size(); i++){ + for (size_t i = 1; i < device_args.size(); i++) { mtu_result_t mtu_i = determine_mtu(device_args[i]["addr"], user_mtu); - mtu.recv_mtu = std::min(mtu.recv_mtu, mtu_i.recv_mtu); - mtu.send_mtu = std::min(mtu.send_mtu, mtu_i.send_mtu); + mtu.recv_mtu = std::min(mtu.recv_mtu, mtu_i.recv_mtu); + mtu.send_mtu = std::min(mtu.send_mtu, mtu_i.send_mtu); } device_addr["recv_frame_size"] = std::to_string(mtu.recv_mtu); device_addr["send_frame_size"] = std::to_string(mtu.send_mtu); - UHD_LOGGER_INFO("USRP2") << boost::format("Current recv frame size: %d bytes") % mtu.recv_mtu; - UHD_LOGGER_INFO("USRP2") << boost::format("Current send frame size: %d bytes") % mtu.send_mtu; - } - catch(const uhd::not_implemented_error &){ - //just ignore this error, makes older fw work... + UHD_LOGGER_INFO("USRP2") + << boost::format("Current recv frame size: %d bytes") % mtu.recv_mtu; + UHD_LOGGER_INFO("USRP2") + << boost::format("Current send frame size: %d bytes") % mtu.send_mtu; + } catch (const uhd::not_implemented_error&) { + // just ignore this error, makes older fw work... } - device_args = separate_device_addr(device_addr); //update args for new frame sizes + device_args = separate_device_addr(device_addr); // update args for new frame sizes //////////////////////////////////////////////////////////////////// // create controller objects and initialize the properties tree //////////////////////////////////////////////////////////////////// - _tree = property_tree::make(); - _type = device::USRP; + _tree = property_tree::make(); + _type = device::USRP; _ignore_cal_file = device_addr.has_key("ignore-cal-file"); _tree->create<std::string>("/name").set("USRP2 / N-Series Device"); - for (size_t mbi = 0; mbi < device_args.size(); mbi++){ + for (size_t mbi = 0; mbi < device_args.size(); mbi++) { const device_addr_t device_args_i = device_args[mbi]; - const std::string mb = std::to_string(mbi); - const std::string addr = device_args_i["addr"]; - const fs_path mb_path = "/mboards/" + mb; + const std::string mb = std::to_string(mbi); + const std::string addr = device_args_i["addr"]; + const fs_path mb_path = "/mboards/" + mb; //////////////////////////////////////////////////////////////// // create the iface that controls i2c, spi, uart, and wb //////////////////////////////////////////////////////////////// - _mbc[mb].iface = usrp2_iface::make(udp_simple::make_connected( - addr, BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT) - )); + _mbc[mb].iface = usrp2_iface::make( + udp_simple::make_connected(addr, BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT))); _tree->create<std::string>(mb_path / "name").set(_mbc[mb].iface->get_cname()); - _tree->create<std::string>(mb_path / "fw_version").set(_mbc[mb].iface->get_fw_version_string()); + _tree->create<std::string>(mb_path / "fw_version") + .set(_mbc[mb].iface->get_fw_version_string()); - //check the fpga compatibility number + // check the fpga compatibility number const uint32_t fpga_compat_num = _mbc[mb].iface->peek32(U2_REG_COMPAT_NUM_RB); - uint16_t fpga_major = fpga_compat_num >> 16, fpga_minor = fpga_compat_num & 0xffff; - if (fpga_major == 0){ //old version scheme + uint16_t fpga_major = fpga_compat_num >> 16, + fpga_minor = fpga_compat_num & 0xffff; + if (fpga_major == 0) { // old version scheme fpga_major = fpga_minor; fpga_minor = 0; } - int expected_fpga_compat_num = std::min(USRP2_FPGA_COMPAT_NUM, N200_FPGA_COMPAT_NUM); - switch (_mbc[mb].iface->get_rev()) - { - case usrp2_iface::USRP2_REV3: - case usrp2_iface::USRP2_REV4: - expected_fpga_compat_num = USRP2_FPGA_COMPAT_NUM; - break; - case usrp2_iface::USRP_N200: - case usrp2_iface::USRP_N200_R4: - case usrp2_iface::USRP_N210: - case usrp2_iface::USRP_N210_R4: - expected_fpga_compat_num = N200_FPGA_COMPAT_NUM; - break; - default: - // handle case where the MB EEPROM is not programmed - if (fpga_major == USRP2_FPGA_COMPAT_NUM or fpga_major == N200_FPGA_COMPAT_NUM) - { - UHD_LOGGER_WARNING("USRP2") << "Unable to identify device - assuming USRP2/N-Series device" ; - expected_fpga_compat_num = fpga_major; - } + int expected_fpga_compat_num = + std::min(USRP2_FPGA_COMPAT_NUM, N200_FPGA_COMPAT_NUM); + switch (_mbc[mb].iface->get_rev()) { + case usrp2_iface::USRP2_REV3: + case usrp2_iface::USRP2_REV4: + expected_fpga_compat_num = USRP2_FPGA_COMPAT_NUM; + break; + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N200_R4: + case usrp2_iface::USRP_N210: + case usrp2_iface::USRP_N210_R4: + expected_fpga_compat_num = N200_FPGA_COMPAT_NUM; + break; + default: + // handle case where the MB EEPROM is not programmed + if (fpga_major == USRP2_FPGA_COMPAT_NUM + or fpga_major == N200_FPGA_COMPAT_NUM) { + UHD_LOGGER_WARNING("USRP2") + << "Unable to identify device - assuming USRP2/N-Series device"; + expected_fpga_compat_num = fpga_major; + } } - if (fpga_major != expected_fpga_compat_num){ - throw uhd::runtime_error(str(boost::format( - "\nPlease update the firmware and FPGA images for your device.\n" - "See the application notes for USRP2/N-Series for instructions.\n" - "Expected FPGA compatibility number %d, but got %d:\n" - "The FPGA build is not compatible with the host code build.\n" - "%s\n" - ) % expected_fpga_compat_num % fpga_major % _mbc[mb].iface->images_warn_help_message())); + if (fpga_major != expected_fpga_compat_num) { + throw uhd::runtime_error( + str(boost::format( + "\nPlease update the firmware and FPGA images for your device.\n" + "See the application notes for USRP2/N-Series for instructions.\n" + "Expected FPGA compatibility number %d, but got %d:\n" + "The FPGA build is not compatible with the host code build.\n" + "%s\n") + % expected_fpga_compat_num % fpga_major + % _mbc[mb].iface->images_warn_help_message())); } - _tree->create<std::string>(mb_path / "fpga_version").set(str(boost::format("%u.%u") % fpga_major % fpga_minor)); + _tree->create<std::string>(mb_path / "fpga_version") + .set(str(boost::format("%u.%u") % fpga_major % fpga_minor)); - //lock the device/motherboard to this process + // lock the device/motherboard to this process _mbc[mb].iface->lock_device(true); //////////////////////////////////////////////////////////////// // construct transports for RX and TX DSPs //////////////////////////////////////////////////////////////// - UHD_LOGGER_TRACE("USRP2") << "Making transport for RX DSP0..." ; + UHD_LOGGER_TRACE("USRP2") << "Making transport for RX DSP0..."; _mbc[mb].rx_dsp_xports.push_back(make_xport( - addr, BOOST_STRINGIZE(USRP2_UDP_RX_DSP0_PORT), device_args_i, "recv" - )); - UHD_LOGGER_TRACE("USRP2") << "Making transport for RX DSP1..." ; + addr, BOOST_STRINGIZE(USRP2_UDP_RX_DSP0_PORT), device_args_i, "recv")); + UHD_LOGGER_TRACE("USRP2") << "Making transport for RX DSP1..."; _mbc[mb].rx_dsp_xports.push_back(make_xport( - addr, BOOST_STRINGIZE(USRP2_UDP_RX_DSP1_PORT), device_args_i, "recv" - )); - UHD_LOGGER_TRACE("USRP2") << "Making transport for TX DSP0..." ; + addr, BOOST_STRINGIZE(USRP2_UDP_RX_DSP1_PORT), device_args_i, "recv")); + UHD_LOGGER_TRACE("USRP2") << "Making transport for TX DSP0..."; _mbc[mb].tx_dsp_xport = make_xport( - addr, BOOST_STRINGIZE(USRP2_UDP_TX_DSP0_PORT), device_args_i, "send" - ); - UHD_LOGGER_TRACE("USRP2") << "Making transport for Control..." ; + addr, BOOST_STRINGIZE(USRP2_UDP_TX_DSP0_PORT), device_args_i, "send"); + UHD_LOGGER_TRACE("USRP2") << "Making transport for Control..."; _mbc[mb].fifo_ctrl_xport = make_xport( - addr, BOOST_STRINGIZE(USRP2_UDP_FIFO_CRTL_PORT), device_addr_t(), "" - ); - //set the filter on the router to take dsp data from this port - _mbc[mb].iface->poke32(U2_REG_ROUTER_CTRL_PORTS, (USRP2_UDP_FIFO_CRTL_PORT << 16) | USRP2_UDP_TX_DSP0_PORT); + addr, BOOST_STRINGIZE(USRP2_UDP_FIFO_CRTL_PORT), device_addr_t(), ""); + // set the filter on the router to take dsp data from this port + _mbc[mb].iface->poke32(U2_REG_ROUTER_CTRL_PORTS, + (USRP2_UDP_FIFO_CRTL_PORT << 16) | USRP2_UDP_TX_DSP0_PORT); - //create the fifo control interface for high speed register access + // create the fifo control interface for high speed register access _mbc[mb].fifo_ctrl = usrp2_fifo_ctrl::make(_mbc[mb].fifo_ctrl_xport); - switch(_mbc[mb].iface->get_rev()){ - case usrp2_iface::USRP_N200: - case usrp2_iface::USRP_N210: - case usrp2_iface::USRP_N200_R4: - case usrp2_iface::USRP_N210_R4: - _mbc[mb].wbiface = _mbc[mb].fifo_ctrl; - _mbc[mb].spiface = _mbc[mb].fifo_ctrl; - break; - default: - _mbc[mb].wbiface = _mbc[mb].iface; - _mbc[mb].spiface = _mbc[mb].iface; - break; + switch (_mbc[mb].iface->get_rev()) { + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + case usrp2_iface::USRP_N200_R4: + case usrp2_iface::USRP_N210_R4: + _mbc[mb].wbiface = _mbc[mb].fifo_ctrl; + _mbc[mb].spiface = _mbc[mb].fifo_ctrl; + break; + default: + _mbc[mb].wbiface = _mbc[mb].iface; + _mbc[mb].spiface = _mbc[mb].iface; + break; } _tree->create<double>(mb_path / "link_max_rate").set(USRP2_LINK_RATE_BPS); @@ -467,39 +478,51 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr) : //////////////////////////////////////////////////////////////// _mbc[mb].clock = usrp2_clock_ctrl::make(_mbc[mb].iface, _mbc[mb].spiface); _tree->create<double>(mb_path / "tick_rate") - .set_publisher(std::bind(&usrp2_clock_ctrl::get_master_clock_rate, _mbc[mb].clock)) - .add_coerced_subscriber(std::bind(&usrp2_impl::update_tick_rate, this, std::placeholders::_1)); + .set_publisher( + std::bind(&usrp2_clock_ctrl::get_master_clock_rate, _mbc[mb].clock)) + .add_coerced_subscriber( + std::bind(&usrp2_impl::update_tick_rate, this, std::placeholders::_1)); //////////////////////////////////////////////////////////////// // create codec control objects //////////////////////////////////////////////////////////////// const fs_path rx_codec_path = mb_path / "rx_codecs/A"; const fs_path tx_codec_path = mb_path / "tx_codecs/A"; - _tree->create<int>(rx_codec_path / "gains"); //phony property so this dir exists - _tree->create<int>(tx_codec_path / "gains"); //phony property so this dir exists + _tree->create<int>(rx_codec_path / "gains"); // phony property so this dir exists + _tree->create<int>(tx_codec_path / "gains"); // phony property so this dir exists _mbc[mb].codec = usrp2_codec_ctrl::make(_mbc[mb].iface, _mbc[mb].spiface); - switch(_mbc[mb].iface->get_rev()){ - case usrp2_iface::USRP_N200: - case usrp2_iface::USRP_N210: - case usrp2_iface::USRP_N200_R4: - case usrp2_iface::USRP_N210_R4:{ - _tree->create<std::string>(rx_codec_path / "name").set("ads62p44"); - _tree->create<meta_range_t>(rx_codec_path / "gains/digital/range").set(meta_range_t(0, 6.0, 0.5)); - _tree->create<double>(rx_codec_path / "gains/digital/value") - .add_coerced_subscriber(std::bind(&usrp2_codec_ctrl::set_rx_digital_gain, _mbc[mb].codec, std::placeholders::_1)).set(0); - _tree->create<meta_range_t>(rx_codec_path / "gains/fine/range").set(meta_range_t(0, 0.5, 0.05)); - _tree->create<double>(rx_codec_path / "gains/fine/value") - .add_coerced_subscriber(std::bind(&usrp2_codec_ctrl::set_rx_digital_fine_gain, _mbc[mb].codec, std::placeholders::_1)).set(0); - }break; - - case usrp2_iface::USRP2_REV3: - case usrp2_iface::USRP2_REV4: - _tree->create<std::string>(rx_codec_path / "name").set("ltc2284"); - break; - - case usrp2_iface::USRP_NXXX: - _tree->create<std::string>(rx_codec_path / "name").set("??????"); - break; + switch (_mbc[mb].iface->get_rev()) { + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + case usrp2_iface::USRP_N200_R4: + case usrp2_iface::USRP_N210_R4: { + _tree->create<std::string>(rx_codec_path / "name").set("ads62p44"); + _tree->create<meta_range_t>(rx_codec_path / "gains/digital/range") + .set(meta_range_t(0, 6.0, 0.5)); + _tree->create<double>(rx_codec_path / "gains/digital/value") + .add_coerced_subscriber( + std::bind(&usrp2_codec_ctrl::set_rx_digital_gain, + _mbc[mb].codec, + std::placeholders::_1)) + .set(0); + _tree->create<meta_range_t>(rx_codec_path / "gains/fine/range") + .set(meta_range_t(0, 0.5, 0.05)); + _tree->create<double>(rx_codec_path / "gains/fine/value") + .add_coerced_subscriber( + std::bind(&usrp2_codec_ctrl::set_rx_digital_fine_gain, + _mbc[mb].codec, + std::placeholders::_1)) + .set(0); + } break; + + case usrp2_iface::USRP2_REV3: + case usrp2_iface::USRP2_REV4: + _tree->create<std::string>(rx_codec_path / "name").set("ltc2284"); + break; + + case usrp2_iface::USRP_NXXX: + _tree->create<std::string>(rx_codec_path / "name").set("??????"); + break; } _tree->create<std::string>(tx_codec_path / "name").set("ad9777"); @@ -508,39 +531,35 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr) : //////////////////////////////////////////////////////////////////// static const uint32_t dont_look_for_gpsdo = 0x1234abcdul; - //disable check for internal GPSDO when not the following: - switch(_mbc[mb].iface->get_rev()){ - case usrp2_iface::USRP_N200: - case usrp2_iface::USRP_N210: - case usrp2_iface::USRP_N200_R4: - case usrp2_iface::USRP_N210_R4: - break; - default: - _mbc[mb].iface->pokefw(U2_FW_REG_HAS_GPSDO, dont_look_for_gpsdo); + // disable check for internal GPSDO when not the following: + switch (_mbc[mb].iface->get_rev()) { + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + case usrp2_iface::USRP_N200_R4: + case usrp2_iface::USRP_N210_R4: + break; + default: + _mbc[mb].iface->pokefw(U2_FW_REG_HAS_GPSDO, dont_look_for_gpsdo); } - //otherwise if not disabled, look for the internal GPSDO - if (_mbc[mb].iface->peekfw(U2_FW_REG_HAS_GPSDO) != dont_look_for_gpsdo) - { + // otherwise if not disabled, look for the internal GPSDO + if (_mbc[mb].iface->peekfw(U2_FW_REG_HAS_GPSDO) != dont_look_for_gpsdo) { UHD_LOGGER_INFO("USRP2") << "Detecting internal GPSDO.... "; - try{ - _mbc[mb].gps = gps_ctrl::make(udp_simple::make_uart(udp_simple::make_connected( - addr, BOOST_STRINGIZE(USRP2_UDP_UART_GPS_PORT) - ))); - } - catch(std::exception &e){ - UHD_LOGGER_ERROR("USRP2") << "An error occurred making GPSDO control: " << e.what() ; + try { + _mbc[mb].gps = + gps_ctrl::make(udp_simple::make_uart(udp_simple::make_connected( + addr, BOOST_STRINGIZE(USRP2_UDP_UART_GPS_PORT)))); + } catch (std::exception& e) { + UHD_LOGGER_ERROR("USRP2") + << "An error occurred making GPSDO control: " << e.what(); } - if (_mbc[mb].gps and _mbc[mb].gps->gps_detected()) - { - for(const std::string &name: _mbc[mb].gps->get_sensors()) - { + if (_mbc[mb].gps and _mbc[mb].gps->gps_detected()) { + for (const std::string& name : _mbc[mb].gps->get_sensors()) { _tree->create<sensor_value_t>(mb_path / "sensors" / name) - .set_publisher(std::bind(&gps_ctrl::get_sensor, _mbc[mb].gps, name)); + .set_publisher( + std::bind(&gps_ctrl::get_sensor, _mbc[mb].gps, name)); } - } - else - { + } else { _mbc[mb].iface->pokefw(U2_FW_REG_HAS_GPSDO, dont_look_for_gpsdo); } } @@ -556,116 +575,134 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr) : //////////////////////////////////////////////////////////////// // create frontend control objects //////////////////////////////////////////////////////////////// - _mbc[mb].rx_fe = rx_frontend_core_200::make( - _mbc[mb].wbiface, U2_REG_SR_ADDR(SR_RX_FRONT) - ); - _mbc[mb].tx_fe = tx_frontend_core_200::make( - _mbc[mb].wbiface, U2_REG_SR_ADDR(SR_TX_FRONT) - ); + _mbc[mb].rx_fe = + rx_frontend_core_200::make(_mbc[mb].wbiface, U2_REG_SR_ADDR(SR_RX_FRONT)); + _mbc[mb].tx_fe = + tx_frontend_core_200::make(_mbc[mb].wbiface, U2_REG_SR_ADDR(SR_TX_FRONT)); _tree->create<subdev_spec_t>(mb_path / "rx_subdev_spec") - .add_coerced_subscriber(std::bind(&usrp2_impl::update_rx_subdev_spec, this, mb, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &usrp2_impl::update_rx_subdev_spec, this, mb, std::placeholders::_1)); _tree->create<subdev_spec_t>(mb_path / "tx_subdev_spec") - .add_coerced_subscriber(std::bind(&usrp2_impl::update_tx_subdev_spec, this, mb, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &usrp2_impl::update_tx_subdev_spec, this, mb, std::placeholders::_1)); const fs_path rx_fe_path = mb_path / "rx_frontends" / "A"; const fs_path tx_fe_path = mb_path / "tx_frontends" / "A"; - _tree->create<std::complex<double> >(rx_fe_path / "dc_offset" / "value") - .set_coercer(std::bind(&rx_frontend_core_200::set_dc_offset, _mbc[mb].rx_fe, std::placeholders::_1)) + _tree->create<std::complex<double>>(rx_fe_path / "dc_offset" / "value") + .set_coercer(std::bind(&rx_frontend_core_200::set_dc_offset, + _mbc[mb].rx_fe, + std::placeholders::_1)) .set(std::complex<double>(0.0, 0.0)); _tree->create<bool>(rx_fe_path / "dc_offset" / "enable") - .add_coerced_subscriber(std::bind(&rx_frontend_core_200::set_dc_offset_auto, _mbc[mb].rx_fe, std::placeholders::_1)) + .add_coerced_subscriber(std::bind(&rx_frontend_core_200::set_dc_offset_auto, + _mbc[mb].rx_fe, + std::placeholders::_1)) .set(true); - _tree->create<std::complex<double> >(rx_fe_path / "iq_balance" / "value") - .add_coerced_subscriber(std::bind(&rx_frontend_core_200::set_iq_balance, _mbc[mb].rx_fe, std::placeholders::_1)) + _tree->create<std::complex<double>>(rx_fe_path / "iq_balance" / "value") + .add_coerced_subscriber(std::bind(&rx_frontend_core_200::set_iq_balance, + _mbc[mb].rx_fe, + std::placeholders::_1)) .set(std::complex<double>(0.0, 0.0)); - _tree->create<std::complex<double> >(tx_fe_path / "dc_offset" / "value") - .set_coercer(std::bind(&tx_frontend_core_200::set_dc_offset, _mbc[mb].tx_fe, std::placeholders::_1)) + _tree->create<std::complex<double>>(tx_fe_path / "dc_offset" / "value") + .set_coercer(std::bind(&tx_frontend_core_200::set_dc_offset, + _mbc[mb].tx_fe, + std::placeholders::_1)) .set(std::complex<double>(0.0, 0.0)); - _tree->create<std::complex<double> >(tx_fe_path / "iq_balance" / "value") - .add_coerced_subscriber(std::bind(&tx_frontend_core_200::set_iq_balance, _mbc[mb].tx_fe, std::placeholders::_1)) + _tree->create<std::complex<double>>(tx_fe_path / "iq_balance" / "value") + .add_coerced_subscriber(std::bind(&tx_frontend_core_200::set_iq_balance, + _mbc[mb].tx_fe, + std::placeholders::_1)) .set(std::complex<double>(0.0, 0.0)); //////////////////////////////////////////////////////////////// // create rx dsp control objects //////////////////////////////////////////////////////////////// - _mbc[mb].rx_dsps.push_back(rx_dsp_core_200::make( - _mbc[mb].wbiface, U2_REG_SR_ADDR(SR_RX_DSP0), U2_REG_SR_ADDR(SR_RX_CTRL0), USRP2_RX_SID_BASE + 0, true - )); - _mbc[mb].rx_dsps.push_back(rx_dsp_core_200::make( - _mbc[mb].wbiface, U2_REG_SR_ADDR(SR_RX_DSP1), U2_REG_SR_ADDR(SR_RX_CTRL1), USRP2_RX_SID_BASE + 1, true - )); - for (size_t dspno = 0; dspno < _mbc[mb].rx_dsps.size(); dspno++){ + _mbc[mb].rx_dsps.push_back(rx_dsp_core_200::make(_mbc[mb].wbiface, + U2_REG_SR_ADDR(SR_RX_DSP0), + U2_REG_SR_ADDR(SR_RX_CTRL0), + USRP2_RX_SID_BASE + 0, + true)); + _mbc[mb].rx_dsps.push_back(rx_dsp_core_200::make(_mbc[mb].wbiface, + U2_REG_SR_ADDR(SR_RX_DSP1), + U2_REG_SR_ADDR(SR_RX_CTRL1), + USRP2_RX_SID_BASE + 1, + true)); + for (size_t dspno = 0; dspno < _mbc[mb].rx_dsps.size(); dspno++) { _mbc[mb].rx_dsps[dspno]->set_link_rate(USRP2_LINK_RATE_BPS); _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber(std::bind(&rx_dsp_core_200::set_tick_rate, _mbc[mb].rx_dsps[dspno], std::placeholders::_1)); + .add_coerced_subscriber(std::bind(&rx_dsp_core_200::set_tick_rate, + _mbc[mb].rx_dsps[dspno], + std::placeholders::_1)); fs_path rx_dsp_path = mb_path / str(boost::format("rx_dsps/%u") % dspno); _tree->create<meta_range_t>(rx_dsp_path / "rate/range") - .set_publisher(std::bind(&rx_dsp_core_200::get_host_rates, _mbc[mb].rx_dsps[dspno])); + .set_publisher( + std::bind(&rx_dsp_core_200::get_host_rates, _mbc[mb].rx_dsps[dspno])); _tree->create<double>(rx_dsp_path / "rate/value") - .set(1e6) //some default - .set_coercer(std::bind(&rx_dsp_core_200::set_host_rate, _mbc[mb].rx_dsps[dspno], std::placeholders::_1)) - .add_coerced_subscriber(std::bind(&usrp2_impl::update_rx_samp_rate, this, mb, dspno, std::placeholders::_1)); + .set(1e6) // some default + .set_coercer(std::bind(&rx_dsp_core_200::set_host_rate, + _mbc[mb].rx_dsps[dspno], + std::placeholders::_1)) + .add_coerced_subscriber(std::bind(&usrp2_impl::update_rx_samp_rate, + this, + mb, + dspno, + std::placeholders::_1)); _tree->create<double>(rx_dsp_path / "freq/value") - .set_coercer(std::bind(&rx_dsp_core_200::set_freq, _mbc[mb].rx_dsps[dspno], std::placeholders::_1)); + .set_coercer(std::bind(&rx_dsp_core_200::set_freq, + _mbc[mb].rx_dsps[dspno], + std::placeholders::_1)); _tree->create<meta_range_t>(rx_dsp_path / "freq/range") - .set_publisher(std::bind(&rx_dsp_core_200::get_freq_range, _mbc[mb].rx_dsps[dspno])); + .set_publisher( + std::bind(&rx_dsp_core_200::get_freq_range, _mbc[mb].rx_dsps[dspno])); _tree->create<stream_cmd_t>(rx_dsp_path / "stream_cmd") - .add_coerced_subscriber(std::bind(&rx_dsp_core_200::issue_stream_command, _mbc[mb].rx_dsps[dspno], std::placeholders::_1)); + .add_coerced_subscriber(std::bind(&rx_dsp_core_200::issue_stream_command, + _mbc[mb].rx_dsps[dspno], + std::placeholders::_1)); } //////////////////////////////////////////////////////////////// // create tx dsp control objects //////////////////////////////////////////////////////////////// - _mbc[mb].tx_dsp = tx_dsp_core_200::make( - _mbc[mb].wbiface, + _mbc[mb].tx_dsp = tx_dsp_core_200::make(_mbc[mb].wbiface, U2_REG_SR_ADDR(SR_TX_DSP), U2_REG_SR_ADDR(SR_TX_CTRL), - USRP2_TX_ASYNC_SID - ); + USRP2_TX_ASYNC_SID); _mbc[mb].tx_dsp->set_link_rate(USRP2_LINK_RATE_BPS); { // This scope can be removed once we're able to do named captures - auto this_tx_dsp = _mbc[mb].tx_dsp; // This can then also go away - _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber([this_tx_dsp](const double rate){ - this_tx_dsp->set_tick_rate(rate); - }) - ; - _tree->create<meta_range_t>(mb_path / "tx_dsps/0/rate/range") - .set_publisher([this_tx_dsp](){ - return this_tx_dsp->get_host_rates(); - }) - ; - _tree->create<double>(mb_path / "tx_dsps/0/rate/value") - .set(1e6) //some default - .set_coercer([this_tx_dsp](const double rate){ - return this_tx_dsp->set_host_rate(rate); - }) - .add_coerced_subscriber([this, mb](const double rate){ - this->update_tx_samp_rate(mb, 0, rate); - }) - ; + auto this_tx_dsp = _mbc[mb].tx_dsp; // This can then also go away + _tree->access<double>(mb_path / "tick_rate") + .add_coerced_subscriber([this_tx_dsp](const double rate) { + this_tx_dsp->set_tick_rate(rate); + }); + _tree->create<meta_range_t>(mb_path / "tx_dsps/0/rate/range") + .set_publisher([this_tx_dsp]() { return this_tx_dsp->get_host_rates(); }); + _tree->create<double>(mb_path / "tx_dsps/0/rate/value") + .set(1e6) // some default + .set_coercer([this_tx_dsp](const double rate) { + return this_tx_dsp->set_host_rate(rate); + }) + .add_coerced_subscriber([this, mb](const double rate) { + this->update_tx_samp_rate(mb, 0, rate); + }); } // End of non-C++14 scope (to release reference to this_tx_dsp) _tree->create<double>(mb_path / "tx_dsps/0/freq/value") - .set_coercer([this, mb](const double rate){ + .set_coercer([this, mb](const double rate) { return this->set_tx_dsp_freq(mb, rate); - }) - ; + }); _tree->create<meta_range_t>(mb_path / "tx_dsps/0/freq/range") - .set_publisher([this, mb](){ - return this->get_tx_dsp_freq_range(mb); - }) - ; + .set_publisher([this, mb]() { return this->get_tx_dsp_freq_range(mb); }); - //setup dsp flow control - const double ups_per_sec = device_args_i.cast<double>("ups_per_sec", 20); + // setup dsp flow control + const double ups_per_sec = device_args_i.cast<double>("ups_per_sec", 20); const size_t send_frame_size = _mbc[mb].tx_dsp_xport->get_send_frame_size(); - const double ups_per_fifo = device_args_i.cast<double>("ups_per_fifo", 8.0); + const double ups_per_fifo = device_args_i.cast<double>("ups_per_fifo", 8.0); _mbc[mb].tx_dsp->set_updates( - (ups_per_sec > 0.0)? size_t(100e6/*approx tick rate*//ups_per_sec) : 0, - (ups_per_fifo > 0.0)? size_t(USRP2_SRAM_BYTES/ups_per_fifo/send_frame_size) : 0 - ); + (ups_per_sec > 0.0) ? size_t(100e6 /*approx tick rate*/ / ups_per_sec) : 0, + (ups_per_fifo > 0.0) + ? size_t(USRP2_SRAM_BYTES / ups_per_fifo / send_frame_size) + : 0); //////////////////////////////////////////////////////////////// // create time control objects @@ -675,26 +712,36 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr) : time64_rb_bases.rb_lo_now = U2_REG_TIME64_LO_RB_IMM; time64_rb_bases.rb_hi_pps = U2_REG_TIME64_HI_RB_PPS; time64_rb_bases.rb_lo_pps = U2_REG_TIME64_LO_RB_PPS; - _mbc[mb].time64 = time64_core_200::make( - _mbc[mb].wbiface, U2_REG_SR_ADDR(SR_TIME64), time64_rb_bases, mimo_clock_sync_delay_cycles - ); + _mbc[mb].time64 = time64_core_200::make(_mbc[mb].wbiface, + U2_REG_SR_ADDR(SR_TIME64), + time64_rb_bases, + mimo_clock_sync_delay_cycles); _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber(std::bind(&time64_core_200::set_tick_rate, _mbc[mb].time64, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &time64_core_200::set_tick_rate, _mbc[mb].time64, std::placeholders::_1)); _tree->create<time_spec_t>(mb_path / "time/now") .set_publisher(std::bind(&time64_core_200::get_time_now, _mbc[mb].time64)) - .add_coerced_subscriber(std::bind(&time64_core_200::set_time_now, _mbc[mb].time64, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &time64_core_200::set_time_now, _mbc[mb].time64, std::placeholders::_1)); _tree->create<time_spec_t>(mb_path / "time/pps") - .set_publisher(std::bind(&time64_core_200::get_time_last_pps, _mbc[mb].time64)) - .add_coerced_subscriber(std::bind(&time64_core_200::set_time_next_pps, _mbc[mb].time64, std::placeholders::_1)); - //setup time source props + .set_publisher( + std::bind(&time64_core_200::get_time_last_pps, _mbc[mb].time64)) + .add_coerced_subscriber(std::bind(&time64_core_200::set_time_next_pps, + _mbc[mb].time64, + std::placeholders::_1)); + // setup time source props _tree->create<std::string>(mb_path / "time_source/value") - .add_coerced_subscriber(std::bind(&time64_core_200::set_time_source, _mbc[mb].time64, std::placeholders::_1)) + .add_coerced_subscriber(std::bind(&time64_core_200::set_time_source, + _mbc[mb].time64, + std::placeholders::_1)) .set("none"); - _tree->create<std::vector<std::string> >(mb_path / "time_source/options") - .set_publisher(std::bind(&time64_core_200::get_time_sources, _mbc[mb].time64)); - //setup reference source props + _tree->create<std::vector<std::string>>(mb_path / "time_source/options") + .set_publisher( + std::bind(&time64_core_200::get_time_sources, _mbc[mb].time64)); + // setup reference source props _tree->create<std::string>(mb_path / "clock_source/value") - .add_coerced_subscriber(std::bind(&usrp2_impl::update_clock_source, this, mb, std::placeholders::_1)) + .add_coerced_subscriber(std::bind( + &usrp2_impl::update_clock_source, this, mb, std::placeholders::_1)) .set("internal"); std::vector<std::string> clock_sources{"internal", "external", "mimo"}; if (_mbc[mb].gps and _mbc[mb].gps->gps_detected()) { @@ -702,229 +749,269 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr) : } _tree->create<std::vector<std::string>>(mb_path / "clock_source/options") .set(clock_sources); - //plug timed commands into tree here - switch(_mbc[mb].iface->get_rev()){ - case usrp2_iface::USRP_N200: - case usrp2_iface::USRP_N210: - case usrp2_iface::USRP_N200_R4: - case usrp2_iface::USRP_N210_R4: - _tree->create<time_spec_t>(mb_path / "time/cmd") - .add_coerced_subscriber(std::bind(&usrp2_fifo_ctrl::set_time, _mbc[mb].fifo_ctrl, std::placeholders::_1)); - default: break; //otherwise, do not register + // plug timed commands into tree here + switch (_mbc[mb].iface->get_rev()) { + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + case usrp2_iface::USRP_N200_R4: + case usrp2_iface::USRP_N210_R4: + _tree->create<time_spec_t>(mb_path / "time/cmd") + .add_coerced_subscriber(std::bind(&usrp2_fifo_ctrl::set_time, + _mbc[mb].fifo_ctrl, + std::placeholders::_1)); + default: + break; // otherwise, do not register } _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber(std::bind(&usrp2_fifo_ctrl::set_tick_rate, _mbc[mb].fifo_ctrl, std::placeholders::_1)); + .add_coerced_subscriber(std::bind(&usrp2_fifo_ctrl::set_tick_rate, + _mbc[mb].fifo_ctrl, + std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // create user-defined control objects //////////////////////////////////////////////////////////////////// - _mbc[mb].user = user_settings_core_200::make(_mbc[mb].wbiface, U2_REG_SR_ADDR(SR_USER_REGS)); + _mbc[mb].user = + user_settings_core_200::make(_mbc[mb].wbiface, U2_REG_SR_ADDR(SR_USER_REGS)); _tree->create<user_settings_core_200::user_reg_t>(mb_path / "user/regs") - .add_coerced_subscriber(std::bind(&user_settings_core_200::set_reg, _mbc[mb].user, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &user_settings_core_200::set_reg, _mbc[mb].user, std::placeholders::_1)); //////////////////////////////////////////////////////////////// // create dboard control objects //////////////////////////////////////////////////////////////// - //read the dboard eeprom to extract the dboard ids + // read the dboard eeprom to extract the dboard ids dboard_eeprom_t rx_db_eeprom, tx_db_eeprom, gdb_eeprom; rx_db_eeprom.load(*_mbc[mb].iface, USRP2_I2C_ADDR_RX_DB); tx_db_eeprom.load(*_mbc[mb].iface, USRP2_I2C_ADDR_TX_DB); gdb_eeprom.load(*_mbc[mb].iface, USRP2_I2C_ADDR_TX_DB ^ 5); - //disable rx dc offset if LFRX - if (rx_db_eeprom.id == 0x000f) _tree->access<bool>(rx_fe_path / "dc_offset" / "enable").set(false); + // disable rx dc offset if LFRX + if (rx_db_eeprom.id == 0x000f) + _tree->access<bool>(rx_fe_path / "dc_offset" / "enable").set(false); - //create the properties and register subscribers + // create the properties and register subscribers _tree->create<dboard_eeprom_t>(mb_path / "dboards/A/rx_eeprom") .set(rx_db_eeprom) - .add_coerced_subscriber(std::bind(&usrp2_impl::set_db_eeprom, this, mb, "rx", std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &usrp2_impl::set_db_eeprom, this, mb, "rx", std::placeholders::_1)); _tree->create<dboard_eeprom_t>(mb_path / "dboards/A/tx_eeprom") .set(tx_db_eeprom) - .add_coerced_subscriber(std::bind(&usrp2_impl::set_db_eeprom, this, mb, "tx", std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &usrp2_impl::set_db_eeprom, this, mb, "tx", std::placeholders::_1)); _tree->create<dboard_eeprom_t>(mb_path / "dboards/A/gdb_eeprom") .set(gdb_eeprom) - .add_coerced_subscriber(std::bind(&usrp2_impl::set_db_eeprom, this, mb, "gdb", std::placeholders::_1)); - - //create a new dboard interface and manager - _mbc[mb].dboard_manager = dboard_manager::make( - rx_db_eeprom, tx_db_eeprom, gdb_eeprom, - make_usrp2_dboard_iface(_mbc[mb].wbiface, _mbc[mb].iface/*i2c*/, _mbc[mb].spiface, _mbc[mb].clock), - _tree->subtree(mb_path / "dboards/A") - ); - - //bind frontend corrections to the dboard freq props + .add_coerced_subscriber(std::bind( + &usrp2_impl::set_db_eeprom, this, mb, "gdb", std::placeholders::_1)); + + // create a new dboard interface and manager + _mbc[mb].dboard_manager = dboard_manager::make(rx_db_eeprom, + tx_db_eeprom, + gdb_eeprom, + make_usrp2_dboard_iface(_mbc[mb].wbiface, + _mbc[mb].iface /*i2c*/, + _mbc[mb].spiface, + _mbc[mb].clock), + _tree->subtree(mb_path / "dboards/A")); + + // bind frontend corrections to the dboard freq props const fs_path db_tx_fe_path = mb_path / "dboards" / "A" / "tx_frontends"; - for(const std::string &name: _tree->list(db_tx_fe_path)){ + for (const std::string& name : _tree->list(db_tx_fe_path)) { _tree->access<double>(db_tx_fe_path / name / "freq" / "value") - .add_coerced_subscriber(std::bind(&usrp2_impl::set_tx_fe_corrections, this, mb, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &usrp2_impl::set_tx_fe_corrections, this, mb, std::placeholders::_1)); } const fs_path db_rx_fe_path = mb_path / "dboards" / "A" / "rx_frontends"; - for(const std::string &name: _tree->list(db_rx_fe_path)){ + for (const std::string& name : _tree->list(db_rx_fe_path)) { _tree->access<double>(db_rx_fe_path / name / "freq" / "value") - .add_coerced_subscriber(std::bind(&usrp2_impl::set_rx_fe_corrections, this, mb, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &usrp2_impl::set_rx_fe_corrections, this, mb, std::placeholders::_1)); } } - //initialize io handling + // initialize io handling this->io_init(); - //do some post-init tasks + // do some post-init tasks this->update_rates(); - for(const std::string &mb: _mbc.keys()){ + for (const std::string& mb : _mbc.keys()) { fs_path root = "/mboards/" + mb; - //reset cordic rates and their properties to zero - for(const std::string &name: _tree->list(root / "rx_dsps")){ + // reset cordic rates and their properties to zero + for (const std::string& name : _tree->list(root / "rx_dsps")) { _tree->access<double>(root / "rx_dsps" / name / "freq" / "value").set(0.0); } - for(const std::string &name: _tree->list(root / "tx_dsps")){ + for (const std::string& name : _tree->list(root / "tx_dsps")) { _tree->access<double>(root / "tx_dsps" / name / "freq" / "value").set(0.0); } - _tree->access<subdev_spec_t>(root / "rx_subdev_spec").set(subdev_spec_t("A:" + _tree->list(root / "dboards/A/rx_frontends").at(0))); - _tree->access<subdev_spec_t>(root / "tx_subdev_spec").set(subdev_spec_t("A:" + _tree->list(root / "dboards/A/tx_frontends").at(0))); + _tree->access<subdev_spec_t>(root / "rx_subdev_spec") + .set( + subdev_spec_t("A:" + _tree->list(root / "dboards/A/rx_frontends").at(0))); + _tree->access<subdev_spec_t>(root / "tx_subdev_spec") + .set( + subdev_spec_t("A:" + _tree->list(root / "dboards/A/tx_frontends").at(0))); _tree->access<std::string>(root / "clock_source/value").set("internal"); _tree->access<std::string>(root / "time_source/value").set("none"); - //GPS installed: use external ref, time, and init time spec - if (_mbc[mb].gps and _mbc[mb].gps->gps_detected()){ + // GPS installed: use external ref, time, and init time spec + if (_mbc[mb].gps and _mbc[mb].gps->gps_detected()) { _mbc[mb].time64->enable_gpsdo(); - UHD_LOGGER_INFO("USRP2") << "Setting references to the internal GPSDO" ; + UHD_LOGGER_INFO("USRP2") << "Setting references to the internal GPSDO"; _tree->access<std::string>(root / "time_source/value").set("gpsdo"); _tree->access<std::string>(root / "clock_source/value").set("gpsdo"); } } - } -usrp2_impl::~usrp2_impl(void){UHD_SAFE_CALL( - _pirate_task_exit = true; - for(const std::string &mb: _mbc.keys()){ - _mbc[mb].tx_dsp->set_updates(0, 0); - } -)} +usrp2_impl::~usrp2_impl(void) +{ + UHD_SAFE_CALL(_pirate_task_exit = true; + for (const std::string& mb + : _mbc.keys()) { _mbc[mb].tx_dsp->set_updates(0, 0); }) +} -void usrp2_impl::set_db_eeprom(const std::string &mb, const std::string &type, const uhd::usrp::dboard_eeprom_t &db_eeprom){ - if (type == "rx") db_eeprom.store(*_mbc[mb].iface, USRP2_I2C_ADDR_RX_DB); - if (type == "tx") db_eeprom.store(*_mbc[mb].iface, USRP2_I2C_ADDR_TX_DB); - if (type == "gdb") db_eeprom.store(*_mbc[mb].iface, USRP2_I2C_ADDR_TX_DB ^ 5); +void usrp2_impl::set_db_eeprom(const std::string& mb, + const std::string& type, + const uhd::usrp::dboard_eeprom_t& db_eeprom) +{ + if (type == "rx") + db_eeprom.store(*_mbc[mb].iface, USRP2_I2C_ADDR_RX_DB); + if (type == "tx") + db_eeprom.store(*_mbc[mb].iface, USRP2_I2C_ADDR_TX_DB); + if (type == "gdb") + db_eeprom.store(*_mbc[mb].iface, USRP2_I2C_ADDR_TX_DB ^ 5); } -sensor_value_t usrp2_impl::get_mimo_locked(const std::string &mb){ - const bool lock = (_mbc[mb].wbiface->peek32(U2_REG_IRQ_RB) & (1<<10)) != 0; +sensor_value_t usrp2_impl::get_mimo_locked(const std::string& mb) +{ + const bool lock = (_mbc[mb].wbiface->peek32(U2_REG_IRQ_RB) & (1 << 10)) != 0; return sensor_value_t("MIMO", lock, "locked", "unlocked"); } -sensor_value_t usrp2_impl::get_ref_locked(const std::string &mb){ - const bool lock = (_mbc[mb].wbiface->peek32(U2_REG_IRQ_RB) & (1<<11)) != 0; +sensor_value_t usrp2_impl::get_ref_locked(const std::string& mb) +{ + const bool lock = (_mbc[mb].wbiface->peek32(U2_REG_IRQ_RB) & (1 << 11)) != 0; return sensor_value_t("Ref", lock, "locked", "unlocked"); } -void usrp2_impl::set_rx_fe_corrections(const std::string &mb, const double lo_freq){ - if(not _ignore_cal_file){ - apply_rx_fe_corrections(this->get_tree()->subtree("/mboards/" + mb), "A", lo_freq); +void usrp2_impl::set_rx_fe_corrections(const std::string& mb, const double lo_freq) +{ + if (not _ignore_cal_file) { + apply_rx_fe_corrections( + this->get_tree()->subtree("/mboards/" + mb), "A", lo_freq); } } -void usrp2_impl::set_tx_fe_corrections(const std::string &mb, const double lo_freq){ - if(not _ignore_cal_file){ - apply_tx_fe_corrections(this->get_tree()->subtree("/mboards/" + mb), "A", lo_freq); +void usrp2_impl::set_tx_fe_corrections(const std::string& mb, const double lo_freq) +{ + if (not _ignore_cal_file) { + apply_tx_fe_corrections( + this->get_tree()->subtree("/mboards/" + mb), "A", lo_freq); } } -double usrp2_impl::set_tx_dsp_freq( - const std::string &mb, - const double freq_ -) { - double new_freq = freq_; - const double tick_rate = - _tree->access<double>("/mboards/"+mb+"/tick_rate").get(); - - //calculate the DAC shift (multiples of rate) - const int sign = boost::math::sign(new_freq); - const int zone = std::min(boost::math::iround(new_freq/tick_rate), 2); - const double dac_shift = sign*zone*tick_rate; - new_freq -= dac_shift; //update FPGA DSP target freq +double usrp2_impl::set_tx_dsp_freq(const std::string& mb, const double freq_) +{ + double new_freq = freq_; + const double tick_rate = _tree->access<double>("/mboards/" + mb + "/tick_rate").get(); + + // calculate the DAC shift (multiples of rate) + const int sign = boost::math::sign(new_freq); + const int zone = std::min(boost::math::iround(new_freq / tick_rate), 2); + const double dac_shift = sign * zone * tick_rate; + new_freq -= dac_shift; // update FPGA DSP target freq UHD_LOG_TRACE("USRP2", - "DSP Tuning: Requested " + std::to_string(freq_/1e6) + " MHz, Using " - "Nyquist zone " + std::to_string(sign*zone) + ", leftover DSP tuning: " - + std::to_string(new_freq/1e6) + " MHz."); + "DSP Tuning: Requested " + std::to_string(freq_ / 1e6) + + " MHz, Using " + "Nyquist zone " + + std::to_string(sign * zone) + + ", leftover DSP tuning: " + std::to_string(new_freq / 1e6) + " MHz."); - //set the DAC shift (modulation mode) + // set the DAC shift (modulation mode) if (zone == 0) { - _mbc[mb].codec->set_tx_mod_mode(0); //no shift + _mbc[mb].codec->set_tx_mod_mode(0); // no shift } else { - _mbc[mb].codec->set_tx_mod_mode(sign*4/zone); //DAC interp = 4 + _mbc[mb].codec->set_tx_mod_mode(sign * 4 / zone); // DAC interp = 4 } - return _mbc[mb].tx_dsp->set_freq(new_freq) + dac_shift; //actual freq + return _mbc[mb].tx_dsp->set_freq(new_freq) + dac_shift; // actual freq } -meta_range_t usrp2_impl::get_tx_dsp_freq_range(const std::string &mb) +meta_range_t usrp2_impl::get_tx_dsp_freq_range(const std::string& mb) { - const double dac_rate = - _tree->access<double>("/mboards/" + mb + "/tick_rate").get() - * _mbc[mb].codec->get_tx_interpolation(); + const double dac_rate = _tree->access<double>("/mboards/" + mb + "/tick_rate").get() + * _mbc[mb].codec->get_tx_interpolation(); const auto dsp_range_step = _mbc[mb].tx_dsp->get_freq_range().step(); // The DSP tuning rate is the entire range of the DAC clock rate. The step // size is determined by the FPGA IP, however. - return meta_range_t( - -dac_rate / 2, - +dac_rate / 2, - dsp_range_step - ); + return meta_range_t(-dac_rate / 2, +dac_rate / 2, dsp_range_step); } #include <boost/math/special_functions/round.hpp> #include <boost/math/special_functions/sign.hpp> -void usrp2_impl::update_clock_source(const std::string &mb, const std::string &source){ - //NOTICE: U2_REG_MISC_CTRL_CLOCK is on the wb clock, and cannot be set from fifo_ctrl - //clock source ref 10mhz - switch(_mbc[mb].iface->get_rev()){ - case usrp2_iface::USRP_N200: - case usrp2_iface::USRP_N210: - case usrp2_iface::USRP_N200_R4: - case usrp2_iface::USRP_N210_R4: - if (source == "internal") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x12); - else if (source == "external") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C); - else if (source == "gpsdo") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C); - else if (source == "mimo") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15); - else throw uhd::value_error("unhandled clock configuration reference source: " + source); - _mbc[mb].clock->enable_external_ref(true); //USRP2P has an internal 10MHz TCXO - break; - - case usrp2_iface::USRP2_REV3: - case usrp2_iface::USRP2_REV4: - if (source == "internal") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x10); - else if (source == "external") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C); - else if (source == "mimo") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15); - else throw uhd::value_error("unhandled clock configuration reference source: " + source); - _mbc[mb].clock->enable_external_ref(source != "internal"); - break; - - case usrp2_iface::USRP_NXXX: break; - } - - //always drive the clock over serdes if not locking to it - _mbc[mb].clock->enable_mimo_clock_out(source != "mimo"); - - //set the mimo clock delay over the serdes - if (source != "mimo"){ - switch(_mbc[mb].iface->get_rev()){ +void usrp2_impl::update_clock_source(const std::string& mb, const std::string& source) +{ + // NOTICE: U2_REG_MISC_CTRL_CLOCK is on the wb clock, and cannot be set from fifo_ctrl + // clock source ref 10mhz + switch (_mbc[mb].iface->get_rev()) { case usrp2_iface::USRP_N200: case usrp2_iface::USRP_N210: case usrp2_iface::USRP_N200_R4: case usrp2_iface::USRP_N210_R4: - _mbc[mb].clock->set_mimo_clock_delay(mimo_clock_delay_usrp_n2xx); + if (source == "internal") + _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x12); + else if (source == "external") + _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C); + else if (source == "gpsdo") + _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C); + else if (source == "mimo") + _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15); + else + throw uhd::value_error( + "unhandled clock configuration reference source: " + source); + _mbc[mb].clock->enable_external_ref(true); // USRP2P has an internal 10MHz + // TCXO break; + case usrp2_iface::USRP2_REV3: case usrp2_iface::USRP2_REV4: - _mbc[mb].clock->set_mimo_clock_delay(mimo_clock_delay_usrp2_rev4); + if (source == "internal") + _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x10); + else if (source == "external") + _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C); + else if (source == "mimo") + _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15); + else + throw uhd::value_error( + "unhandled clock configuration reference source: " + source); + _mbc[mb].clock->enable_external_ref(source != "internal"); break; - default: break; //not handled + case usrp2_iface::USRP_NXXX: + break; + } + + // always drive the clock over serdes if not locking to it + _mbc[mb].clock->enable_mimo_clock_out(source != "mimo"); + + // set the mimo clock delay over the serdes + if (source != "mimo") { + switch (_mbc[mb].iface->get_rev()) { + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + case usrp2_iface::USRP_N200_R4: + case usrp2_iface::USRP_N210_R4: + _mbc[mb].clock->set_mimo_clock_delay(mimo_clock_delay_usrp_n2xx); + break; + + case usrp2_iface::USRP2_REV4: + _mbc[mb].clock->set_mimo_clock_delay(mimo_clock_delay_usrp2_rev4); + break; + + default: + break; // not handled } } } diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 9e4e507de..792c38a11 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -8,71 +8,71 @@ #ifndef INCLUDED_USRP2_IMPL_HPP #define INCLUDED_USRP2_IMPL_HPP -#include "usrp2_iface.hpp" -#include "usrp2_fifo_ctrl.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" -#include <uhdlib/usrp/cores/rx_frontend_core_200.hpp> -#include <uhdlib/usrp/cores/tx_frontend_core_200.hpp> -#include <uhdlib/usrp/cores/rx_dsp_core_200.hpp> -#include <uhdlib/usrp/cores/tx_dsp_core_200.hpp> -#include <uhdlib/usrp/cores/time64_core_200.hpp> -#include <uhdlib/usrp/cores/user_settings_core_200.hpp> -#include <uhdlib/usrp/cores/gpio_core_200.hpp> -#include <uhd/property_tree.hpp> -#include <uhd/usrp/gps_ctrl.hpp> +#include "usrp2_fifo_ctrl.hpp" +#include "usrp2_iface.hpp" #include <uhd/device.hpp> -#include <uhd/utils/pimpl.hpp> -#include <uhd/types/dict.hpp> -#include <uhd/types/stream_cmd.hpp> -#include <uhd/usrp/dboard_eeprom.hpp> -#include <uhd/transport/vrt_if_packet.hpp> +#include <uhd/property_tree.hpp> #include <uhd/transport/udp_simple.hpp> #include <uhd/transport/udp_zero_copy.hpp> +#include <uhd/transport/vrt_if_packet.hpp> #include <uhd/types/device_addr.hpp> +#include <uhd/types/dict.hpp> +#include <uhd/types/stream_cmd.hpp> +#include <uhd/usrp/dboard_eeprom.hpp> #include <uhd/usrp/dboard_manager.hpp> +#include <uhd/usrp/gps_ctrl.hpp> #include <uhd/usrp/subdev_spec.hpp> -#include <memory> -#include <functional> +#include <uhd/utils/pimpl.hpp> +#include <uhdlib/usrp/cores/gpio_core_200.hpp> +#include <uhdlib/usrp/cores/rx_dsp_core_200.hpp> +#include <uhdlib/usrp/cores/rx_frontend_core_200.hpp> +#include <uhdlib/usrp/cores/time64_core_200.hpp> +#include <uhdlib/usrp/cores/tx_dsp_core_200.hpp> +#include <uhdlib/usrp/cores/tx_frontend_core_200.hpp> +#include <uhdlib/usrp/cores/user_settings_core_200.hpp> #include <atomic> +#include <functional> +#include <memory> -static const double USRP2_LINK_RATE_BPS = 1000e6/8; -static const double mimo_clock_delay_usrp2_rev4 = 4.18e-9; -static const double mimo_clock_delay_usrp_n2xx = 4.10e-9; +static const double USRP2_LINK_RATE_BPS = 1000e6 / 8; +static const double mimo_clock_delay_usrp2_rev4 = 4.18e-9; +static const double mimo_clock_delay_usrp_n2xx = 4.10e-9; static const size_t mimo_clock_sync_delay_cycles = 138; -static const size_t USRP2_SRAM_BYTES = size_t(1 << 20); -static const uint32_t USRP2_TX_ASYNC_SID = 2; -static const uint32_t USRP2_RX_SID_BASE = 3; +static const size_t USRP2_SRAM_BYTES = size_t(1 << 20); +static const uint32_t USRP2_TX_ASYNC_SID = 2; +static const uint32_t USRP2_RX_SID_BASE = 3; -uhd::device_addrs_t usrp2_find(const uhd::device_addr_t &hint_); +uhd::device_addrs_t usrp2_find(const uhd::device_addr_t& hint_); //! Make a usrp2 dboard interface. -uhd::usrp::dboard_iface::sptr make_usrp2_dboard_iface( - uhd::timed_wb_iface::sptr wb_iface, +uhd::usrp::dboard_iface::sptr make_usrp2_dboard_iface(uhd::timed_wb_iface::sptr wb_iface, uhd::i2c_iface::sptr i2c_iface, uhd::spi_iface::sptr spi_iface, - usrp2_clock_ctrl::sptr clk_ctrl -); + usrp2_clock_ctrl::sptr clk_ctrl); /*! * USRP2 implementation guts: * The implementation details are encapsulated here. * Handles device properties and streaming... */ -class usrp2_impl : public uhd::device{ +class usrp2_impl : public uhd::device +{ public: - usrp2_impl(const uhd::device_addr_t &); + usrp2_impl(const uhd::device_addr_t&); ~usrp2_impl(void); - //the io interface - uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t &args); - uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t &args); - bool recv_async_msg(uhd::async_metadata_t &, double); + // the io interface + uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t& args); + uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t& args); + bool recv_async_msg(uhd::async_metadata_t&, double); - static uhd::usrp::mboard_eeprom_t get_mb_eeprom(usrp2_iface &); + static uhd::usrp::mboard_eeprom_t get_mb_eeprom(usrp2_iface&); private: - struct mb_container_type{ + struct mb_container_type + { usrp2_iface::sptr iface; usrp2_fifo_ctrl::sptr fifo_ctrl; uhd::spi_iface::sptr spiface; @@ -83,8 +83,8 @@ private: rx_frontend_core_200::sptr rx_fe; tx_frontend_core_200::sptr tx_fe; std::vector<rx_dsp_core_200::sptr> rx_dsps; - std::vector<std::weak_ptr<uhd::rx_streamer> > rx_streamers; - std::vector<std::weak_ptr<uhd::tx_streamer> > tx_streamers; + std::vector<std::weak_ptr<uhd::rx_streamer>> rx_streamers; + std::vector<std::weak_ptr<uhd::tx_streamer>> tx_streamers; tx_dsp_core_200::sptr tx_dsp; time64_core_200::sptr time64; user_settings_core_200::sptr user; @@ -93,36 +93,38 @@ private: uhd::transport::zero_copy_if::sptr fifo_ctrl_xport; uhd::usrp::dboard_manager::sptr dboard_manager; size_t rx_chan_occ, tx_chan_occ; - mb_container_type(void): rx_chan_occ(0), tx_chan_occ(0){} + mb_container_type(void) : rx_chan_occ(0), tx_chan_occ(0) {} }; uhd::dict<std::string, mb_container_type> _mbc; - void set_mb_eeprom(const std::string &, const uhd::usrp::mboard_eeprom_t &); - void set_db_eeprom(const std::string &, const std::string &, const uhd::usrp::dboard_eeprom_t &); + void set_mb_eeprom(const std::string&, const uhd::usrp::mboard_eeprom_t&); + void set_db_eeprom( + const std::string&, const std::string&, const uhd::usrp::dboard_eeprom_t&); - uhd::sensor_value_t get_mimo_locked(const std::string &); - uhd::sensor_value_t get_ref_locked(const std::string &); + uhd::sensor_value_t get_mimo_locked(const std::string&); + uhd::sensor_value_t get_ref_locked(const std::string&); - void set_rx_fe_corrections(const std::string &mb, const double); - void set_tx_fe_corrections(const std::string &mb, const double); + void set_rx_fe_corrections(const std::string& mb, const double); + void set_tx_fe_corrections(const std::string& mb, const double); bool _ignore_cal_file; - //io impl methods and members + // io impl methods and members uhd::device_addr_t device_addr; UHD_PIMPL_DECL(io_impl) _io_impl; std::atomic<bool> _pirate_task_exit; void io_init(void); void update_tick_rate(const double rate); - void update_rx_samp_rate(const std::string &, const size_t, const double rate); - void update_tx_samp_rate(const std::string &, const size_t, const double rate); + void update_rx_samp_rate(const std::string&, const size_t, const double rate); + void update_tx_samp_rate(const std::string&, const size_t, const double rate); void update_rates(void); - //update spec methods are coercers until we only accept db_name == A - void update_rx_subdev_spec(const std::string &, const uhd::usrp::subdev_spec_t &); - void update_tx_subdev_spec(const std::string &, const uhd::usrp::subdev_spec_t &); - double set_tx_dsp_freq(const std::string &, const double); - uhd::meta_range_t get_tx_dsp_freq_range(const std::string &); - void update_clock_source(const std::string &, const std::string &); - void program_stream_dest(uhd::transport::zero_copy_if::sptr &, const uhd::stream_args_t &); + // update spec methods are coercers until we only accept db_name == A + void update_rx_subdev_spec(const std::string&, const uhd::usrp::subdev_spec_t&); + void update_tx_subdev_spec(const std::string&, const uhd::usrp::subdev_spec_t&); + double set_tx_dsp_freq(const std::string&, const double); + uhd::meta_range_t get_tx_dsp_freq_range(const std::string&); + void update_clock_source(const std::string&, const std::string&); + void program_stream_dest( + uhd::transport::zero_copy_if::sptr&, const uhd::stream_args_t&); }; #endif /* INCLUDED_USRP2_IMPL_HPP */ diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index f26b33ecb..6fc973cdf 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -11,37 +11,37 @@ //////////////////////////////////////////////////////////////////////// // Define slave bases //////////////////////////////////////////////////////////////////////// -#define ROUTER_RAM_BASE 0x4000 -#define SPI_BASE 0x5000 -#define I2C_BASE 0x5400 -#define GPIO_BASE 0x5800 -#define READBACK_BASE 0x5C00 -#define ETH_BASE 0x6000 -#define SETTING_REGS_BASE 0x7000 -#define PIC_BASE 0x8000 -#define UART_BASE 0x8800 -#define ATR_BASE 0x8C00 +#define ROUTER_RAM_BASE 0x4000 +#define SPI_BASE 0x5000 +#define I2C_BASE 0x5400 +#define GPIO_BASE 0x5800 +#define READBACK_BASE 0x5C00 +#define ETH_BASE 0x6000 +#define SETTING_REGS_BASE 0x7000 +#define PIC_BASE 0x8000 +#define UART_BASE 0x8800 +#define ATR_BASE 0x8C00 //////////////////////////////////////////////////////////////////////// // Setting register offsets //////////////////////////////////////////////////////////////////////// -#define SR_MISC 0 // 7 regs -#define SR_USER_REGS 8 // 2 -#define SR_TIME64 10 // 6 -#define SR_BUF_POOL 16 // 4 -#define SR_SPI_CORE 20 // 3 -#define SR_RX_FRONT 24 // 5 -#define SR_RX_CTRL0 32 // 9 -#define SR_RX_DSP0 48 // 7 -#define SR_RX_CTRL1 80 // 9 -#define SR_RX_DSP1 96 // 7 +#define SR_MISC 0 // 7 regs +#define SR_USER_REGS 8 // 2 +#define SR_TIME64 10 // 6 +#define SR_BUF_POOL 16 // 4 +#define SR_SPI_CORE 20 // 3 +#define SR_RX_FRONT 24 // 5 +#define SR_RX_CTRL0 32 // 9 +#define SR_RX_DSP0 48 // 7 +#define SR_RX_CTRL1 80 // 9 +#define SR_RX_DSP1 96 // 7 -#define SR_TX_FRONT 128 // ? -#define SR_TX_CTRL 144 // 6 -#define SR_TX_DSP 160 // 5 +#define SR_TX_FRONT 128 // ? +#define SR_TX_CTRL 144 // 6 +#define SR_TX_DSP 160 // 5 -#define SR_GPIO 184 -#define SR_UDP_SM 192 // 64 +#define SR_GPIO 184 +#define SR_UDP_SM 192 // 64 #define U2_REG_SR_ADDR(sr) (SETTING_REGS_BASE + (4 * (sr))) @@ -51,15 +51,15 @@ // SPI Slave Constants //////////////////////////////////////////////// // Masks for controlling different peripherals -#define SPI_SS_AD9510 1 -#define SPI_SS_AD9777 2 -#define SPI_SS_RX_DAC 4 -#define SPI_SS_RX_ADC 8 -#define SPI_SS_RX_DB 16 -#define SPI_SS_TX_DAC 32 -#define SPI_SS_TX_ADC 64 -#define SPI_SS_TX_DB 128 -#define SPI_SS_ADS62P44 256 //for usrp2p +#define SPI_SS_AD9510 1 +#define SPI_SS_AD9777 2 +#define SPI_SS_RX_DAC 4 +#define SPI_SS_RX_ADC 8 +#define SPI_SS_RX_DB 16 +#define SPI_SS_TX_DAC 32 +#define SPI_SS_TX_ADC 64 +#define SPI_SS_TX_DB 128 +#define SPI_SS_ADS62P44 256 // for usrp2p ///////////////////////////////////////////////// // Misc Control @@ -77,21 +77,21 @@ #define U2_FLAG_MISC_CTRL_SERDES_ENABLE 8 #define U2_FLAG_MISC_CTRL_SERDES_PRBSEN 4 #define U2_FLAG_MISC_CTRL_SERDES_LOOPEN 2 -#define U2_FLAG_MISC_CTRL_SERDES_RXEN 1 +#define U2_FLAG_MISC_CTRL_SERDES_RXEN 1 -#define U2_FLAG_MISC_CTRL_ADC_ON 0x0F +#define U2_FLAG_MISC_CTRL_ADC_ON 0x0F #define U2_FLAG_MISC_CTRL_ADC_OFF 0x00 ///////////////////////////////////////////////// // Readback regs //////////////////////////////////////////////// -#define U2_REG_STATUS READBACK_BASE + 4*8 -#define U2_REG_GPIO_RB READBACK_BASE + 4*9 -#define U2_REG_TIME64_HI_RB_IMM READBACK_BASE + 4*10 -#define U2_REG_TIME64_LO_RB_IMM READBACK_BASE + 4*11 -#define U2_REG_COMPAT_NUM_RB READBACK_BASE + 4*12 -#define U2_REG_IRQ_RB READBACK_BASE + 4*13 -#define U2_REG_TIME64_HI_RB_PPS READBACK_BASE + 4*14 -#define U2_REG_TIME64_LO_RB_PPS READBACK_BASE + 4*15 +#define U2_REG_STATUS READBACK_BASE + 4 * 8 +#define U2_REG_GPIO_RB READBACK_BASE + 4 * 9 +#define U2_REG_TIME64_HI_RB_IMM READBACK_BASE + 4 * 10 +#define U2_REG_TIME64_LO_RB_IMM READBACK_BASE + 4 * 11 +#define U2_REG_COMPAT_NUM_RB READBACK_BASE + 4 * 12 +#define U2_REG_IRQ_RB READBACK_BASE + 4 * 13 +#define U2_REG_TIME64_HI_RB_PPS READBACK_BASE + 4 * 14 +#define U2_REG_TIME64_LO_RB_PPS READBACK_BASE + 4 * 15 #endif /* INCLUDED_USRP2_REGS_HPP */ diff --git a/host/lib/usrp/usrp_c.cpp b/host/lib/usrp/usrp_c.cpp index 9d1704181..e94b49fc8 100644 --- a/host/lib/usrp/usrp_c.cpp +++ b/host/lib/usrp/usrp_c.cpp @@ -7,40 +7,40 @@ /* C-Interface for multi_usrp */ -#include <uhd/utils/static.hpp> -#include <uhd/usrp/multi_usrp.hpp> - #include <uhd/error.h> +#include <uhd/usrp/multi_usrp.hpp> #include <uhd/usrp/usrp.h> - -#include <boost/thread/mutex.hpp> - +#include <uhd/utils/static.hpp> #include <string.h> +#include <boost/thread/mutex.hpp> #include <map> /**************************************************************************** * Helpers ***************************************************************************/ -uhd::stream_args_t stream_args_c_to_cpp(const uhd_stream_args_t *stream_args_c) +uhd::stream_args_t stream_args_c_to_cpp(const uhd_stream_args_t* stream_args_c) { std::string otw_format(stream_args_c->otw_format); std::string cpu_format(stream_args_c->cpu_format); std::string args(stream_args_c->args); - std::vector<size_t> channels(stream_args_c->channel_list, stream_args_c->channel_list + stream_args_c->n_channels); + std::vector<size_t> channels(stream_args_c->channel_list, + stream_args_c->channel_list + stream_args_c->n_channels); uhd::stream_args_t stream_args_cpp(cpu_format, otw_format); - stream_args_cpp.args = args; + stream_args_cpp.args = args; stream_args_cpp.channels = channels; return stream_args_cpp; } -uhd::stream_cmd_t stream_cmd_c_to_cpp(const uhd_stream_cmd_t *stream_cmd_c) +uhd::stream_cmd_t stream_cmd_c_to_cpp(const uhd_stream_cmd_t* stream_cmd_c) { - uhd::stream_cmd_t stream_cmd_cpp(uhd::stream_cmd_t::stream_mode_t(stream_cmd_c->stream_mode)); - stream_cmd_cpp.num_samps = stream_cmd_c->num_samps; - stream_cmd_cpp.stream_now = stream_cmd_c->stream_now; - stream_cmd_cpp.time_spec = uhd::time_spec_t(stream_cmd_c->time_spec_full_secs, stream_cmd_c->time_spec_frac_secs); + uhd::stream_cmd_t stream_cmd_cpp( + uhd::stream_cmd_t::stream_mode_t(stream_cmd_c->stream_mode)); + stream_cmd_cpp.num_samps = stream_cmd_c->num_samps; + stream_cmd_cpp.stream_now = stream_cmd_c->stream_now; + stream_cmd_cpp.time_spec = uhd::time_spec_t( + stream_cmd_c->time_spec_full_secs, stream_cmd_c->time_spec_frac_secs); return stream_cmd_cpp; } @@ -48,25 +48,29 @@ uhd::stream_cmd_t stream_cmd_c_to_cpp(const uhd_stream_cmd_t *stream_cmd_c) * Registry / Pointer Management ***************************************************************************/ /* Public structs */ -struct uhd_usrp { +struct uhd_usrp +{ size_t usrp_index; std::string last_error; }; -struct uhd_tx_streamer { +struct uhd_tx_streamer +{ size_t usrp_index; uhd::tx_streamer::sptr streamer; std::string last_error; }; -struct uhd_rx_streamer { +struct uhd_rx_streamer +{ size_t usrp_index; uhd::rx_streamer::sptr streamer; std::string last_error; }; /* Not public: We use this for our internal registry */ -struct usrp_ptr { +struct usrp_ptr +{ uhd::usrp::multi_usrp::sptr ptr; static size_t usrp_counter; }; @@ -83,264 +87,204 @@ UHD_SINGLETON_FCN(usrp_ptrs, get_usrp_ptrs); * RX Streamer ***************************************************************************/ static boost::mutex _rx_streamer_make_mutex; -uhd_error uhd_rx_streamer_make(uhd_rx_streamer_handle* h){ - UHD_SAFE_C( - boost::mutex::scoped_lock lock(_rx_streamer_make_mutex); - (*h) = new uhd_rx_streamer; - ) +uhd_error uhd_rx_streamer_make(uhd_rx_streamer_handle* h) +{ + UHD_SAFE_C(boost::mutex::scoped_lock lock(_rx_streamer_make_mutex); + (*h) = new uhd_rx_streamer;) } static boost::mutex _rx_streamer_free_mutex; -uhd_error uhd_rx_streamer_free(uhd_rx_streamer_handle* h){ - UHD_SAFE_C( - boost::mutex::scoped_lock lock(_rx_streamer_free_mutex); - delete (*h); - (*h) = NULL; - ) +uhd_error uhd_rx_streamer_free(uhd_rx_streamer_handle* h) +{ + UHD_SAFE_C(boost::mutex::scoped_lock lock(_rx_streamer_free_mutex); delete (*h); + (*h) = NULL;) } -uhd_error uhd_rx_streamer_num_channels(uhd_rx_streamer_handle h, - size_t *num_channels_out){ - UHD_SAFE_C_SAVE_ERROR(h, - *num_channels_out = h->streamer->get_num_channels(); - ) +uhd_error uhd_rx_streamer_num_channels(uhd_rx_streamer_handle h, size_t* num_channels_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *num_channels_out = h->streamer->get_num_channels();) } -uhd_error uhd_rx_streamer_max_num_samps(uhd_rx_streamer_handle h, - size_t *max_num_samps_out){ - UHD_SAFE_C_SAVE_ERROR(h, - *max_num_samps_out = h->streamer->get_max_num_samps(); - ) +uhd_error uhd_rx_streamer_max_num_samps( + uhd_rx_streamer_handle h, size_t* max_num_samps_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *max_num_samps_out = h->streamer->get_max_num_samps();) } -uhd_error uhd_rx_streamer_recv( - uhd_rx_streamer_handle h, - void **buffs, +uhd_error uhd_rx_streamer_recv(uhd_rx_streamer_handle h, + void** buffs, size_t samps_per_buff, - uhd_rx_metadata_handle *md, + uhd_rx_metadata_handle* md, double timeout, bool one_packet, - size_t *items_recvd -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::rx_streamer::buffs_type buffs_cpp(buffs, h->streamer->get_num_channels()); - *items_recvd = h->streamer->recv(buffs_cpp, samps_per_buff, (*md)->rx_metadata_cpp, timeout, one_packet); - ) + size_t* items_recvd) +{ + UHD_SAFE_C_SAVE_ERROR( + h, uhd::rx_streamer::buffs_type buffs_cpp(buffs, h->streamer->get_num_channels()); + *items_recvd = h->streamer->recv( + buffs_cpp, samps_per_buff, (*md)->rx_metadata_cpp, timeout, one_packet);) } uhd_error uhd_rx_streamer_issue_stream_cmd( - uhd_rx_streamer_handle h, - const uhd_stream_cmd_t *stream_cmd -){ - UHD_SAFE_C_SAVE_ERROR(h, - h->streamer->issue_stream_cmd(stream_cmd_c_to_cpp(stream_cmd)); - ) + uhd_rx_streamer_handle h, const uhd_stream_cmd_t* stream_cmd) +{ + UHD_SAFE_C_SAVE_ERROR( + h, h->streamer->issue_stream_cmd(stream_cmd_c_to_cpp(stream_cmd));) } uhd_error uhd_rx_streamer_last_error( - uhd_rx_streamer_handle h, - char* error_out, - size_t strbuffer_len -){ - UHD_SAFE_C( - memset(error_out, '\0', strbuffer_len); - strncpy(error_out, h->last_error.c_str(), strbuffer_len); - ) + uhd_rx_streamer_handle h, char* error_out, size_t strbuffer_len) +{ + UHD_SAFE_C(memset(error_out, '\0', strbuffer_len); + strncpy(error_out, h->last_error.c_str(), strbuffer_len);) } /**************************************************************************** * TX Streamer ***************************************************************************/ static boost::mutex _tx_streamer_make_mutex; -uhd_error uhd_tx_streamer_make( - uhd_tx_streamer_handle* h -){ - UHD_SAFE_C( - boost::mutex::scoped_lock lock(_tx_streamer_make_mutex); - (*h) = new uhd_tx_streamer; - ) +uhd_error uhd_tx_streamer_make(uhd_tx_streamer_handle* h) +{ + UHD_SAFE_C(boost::mutex::scoped_lock lock(_tx_streamer_make_mutex); + (*h) = new uhd_tx_streamer;) } static boost::mutex _tx_streamer_free_mutex; -uhd_error uhd_tx_streamer_free( - uhd_tx_streamer_handle* h -){ - UHD_SAFE_C( - boost::mutex::scoped_lock lock(_tx_streamer_free_mutex); - delete *h; - *h = NULL; - ) +uhd_error uhd_tx_streamer_free(uhd_tx_streamer_handle* h) +{ + UHD_SAFE_C(boost::mutex::scoped_lock lock(_tx_streamer_free_mutex); delete *h; + *h = NULL;) } -uhd_error uhd_tx_streamer_num_channels( - uhd_tx_streamer_handle h, - size_t *num_channels_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *num_channels_out = h->streamer->get_num_channels(); - ) +uhd_error uhd_tx_streamer_num_channels(uhd_tx_streamer_handle h, size_t* num_channels_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *num_channels_out = h->streamer->get_num_channels();) } uhd_error uhd_tx_streamer_max_num_samps( - uhd_tx_streamer_handle h, - size_t *max_num_samps_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *max_num_samps_out = h->streamer->get_max_num_samps(); - ) + uhd_tx_streamer_handle h, size_t* max_num_samps_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *max_num_samps_out = h->streamer->get_max_num_samps();) } -uhd_error uhd_tx_streamer_send( - uhd_tx_streamer_handle h, - const void **buffs, +uhd_error uhd_tx_streamer_send(uhd_tx_streamer_handle h, + const void** buffs, size_t samps_per_buff, - uhd_tx_metadata_handle *md, + uhd_tx_metadata_handle* md, double timeout, - size_t *items_sent -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::tx_streamer::buffs_type buffs_cpp(buffs, h->streamer->get_num_channels()); + size_t* items_sent) +{ + UHD_SAFE_C_SAVE_ERROR( + h, uhd::tx_streamer::buffs_type buffs_cpp(buffs, h->streamer->get_num_channels()); *items_sent = h->streamer->send( - buffs_cpp, - samps_per_buff, - (*md)->tx_metadata_cpp, - timeout - ); - ) + buffs_cpp, samps_per_buff, (*md)->tx_metadata_cpp, timeout);) } -uhd_error uhd_tx_streamer_recv_async_msg( - uhd_tx_streamer_handle h, - uhd_async_metadata_handle *md, +uhd_error uhd_tx_streamer_recv_async_msg(uhd_tx_streamer_handle h, + uhd_async_metadata_handle* md, const double timeout, - bool *valid -){ - UHD_SAFE_C_SAVE_ERROR(h, - *valid = h->streamer->recv_async_msg((*md)->async_metadata_cpp, timeout); - ) + bool* valid) +{ + UHD_SAFE_C_SAVE_ERROR( + h, *valid = h->streamer->recv_async_msg((*md)->async_metadata_cpp, timeout);) } uhd_error uhd_tx_streamer_last_error( - uhd_tx_streamer_handle h, - char* error_out, - size_t strbuffer_len -){ - UHD_SAFE_C( - memset(error_out, '\0', strbuffer_len); - strncpy(error_out, h->last_error.c_str(), strbuffer_len); - ) + uhd_tx_streamer_handle h, char* error_out, size_t strbuffer_len) +{ + UHD_SAFE_C(memset(error_out, '\0', strbuffer_len); + strncpy(error_out, h->last_error.c_str(), strbuffer_len);) } /**************************************************************************** * Generate / Destroy API calls ***************************************************************************/ static boost::mutex _usrp_find_mutex; -uhd_error uhd_usrp_find( - const char* args, - uhd_string_vector_handle *strings_out -){ +uhd_error uhd_usrp_find(const char* args, uhd_string_vector_handle* strings_out) +{ UHD_SAFE_C( boost::mutex::scoped_lock _lock(_usrp_find_mutex); - uhd::device_addrs_t devs = uhd::device::find(std::string(args), uhd::device::USRP); + uhd::device_addrs_t devs = + uhd::device::find(std::string(args), uhd::device::USRP); (*strings_out)->string_vector_cpp.clear(); - for(const uhd::device_addr_t &dev: devs){ - (*strings_out)->string_vector_cpp.push_back(dev.to_string()); - } - ) + for (const uhd::device_addr_t& dev + : devs) { (*strings_out)->string_vector_cpp.push_back(dev.to_string()); }) } static boost::mutex _usrp_make_mutex; -uhd_error uhd_usrp_make( - uhd_usrp_handle *h, - const char *args -){ - UHD_SAFE_C( - boost::mutex::scoped_lock lock(_usrp_make_mutex); +uhd_error uhd_usrp_make(uhd_usrp_handle* h, const char* args) +{ + UHD_SAFE_C(boost::mutex::scoped_lock lock(_usrp_make_mutex); - size_t usrp_count = usrp_ptr::usrp_counter; - usrp_ptr::usrp_counter++; + size_t usrp_count = usrp_ptr::usrp_counter; + usrp_ptr::usrp_counter++; - // Initialize USRP - uhd::device_addr_t device_addr(args); - usrp_ptr P; - P.ptr = uhd::usrp::multi_usrp::make(device_addr); + // Initialize USRP + uhd::device_addr_t device_addr(args); + usrp_ptr P; + P.ptr = uhd::usrp::multi_usrp::make(device_addr); - // Dump into registry - get_usrp_ptrs()[usrp_count] = P; + // Dump into registry + get_usrp_ptrs()[usrp_count] = P; - // Update handle - (*h) = new uhd_usrp; - (*h)->usrp_index = usrp_count; - ) + // Update handle + (*h) = new uhd_usrp; + (*h)->usrp_index = usrp_count;) } static boost::mutex _usrp_free_mutex; -uhd_error uhd_usrp_free( - uhd_usrp_handle *h -){ +uhd_error uhd_usrp_free(uhd_usrp_handle* h) +{ UHD_SAFE_C( boost::mutex::scoped_lock lock(_usrp_free_mutex); - if(!get_usrp_ptrs().count((*h)->usrp_index)){ - return UHD_ERROR_INVALID_DEVICE; - } + if (!get_usrp_ptrs().count((*h)->usrp_index)) { return UHD_ERROR_INVALID_DEVICE; } - get_usrp_ptrs().erase((*h)->usrp_index); + get_usrp_ptrs() + .erase((*h)->usrp_index); delete *h; - *h = NULL; - ) + *h = NULL;) } -uhd_error uhd_usrp_last_error( - uhd_usrp_handle h, - char* error_out, - size_t strbuffer_len -){ - UHD_SAFE_C( - memset(error_out, '\0', strbuffer_len); - strncpy(error_out, h->last_error.c_str(), strbuffer_len); - ) +uhd_error uhd_usrp_last_error(uhd_usrp_handle h, char* error_out, size_t strbuffer_len) +{ + UHD_SAFE_C(memset(error_out, '\0', strbuffer_len); + strncpy(error_out, h->last_error.c_str(), strbuffer_len);) } static boost::mutex _usrp_get_rx_stream_mutex; uhd_error uhd_usrp_get_rx_stream( - uhd_usrp_handle h_u, - uhd_stream_args_t *stream_args, - uhd_rx_streamer_handle h_s -){ - UHD_SAFE_C_SAVE_ERROR(h_s, - boost::mutex::scoped_lock lock(_usrp_get_rx_stream_mutex); - - if(!get_usrp_ptrs().count(h_u->usrp_index)){ + uhd_usrp_handle h_u, uhd_stream_args_t* stream_args, uhd_rx_streamer_handle h_s) +{ + UHD_SAFE_C_SAVE_ERROR( + h_s, boost::mutex::scoped_lock lock(_usrp_get_rx_stream_mutex); + + if (!get_usrp_ptrs().count(h_u->usrp_index)) { h_s->last_error = "Streamer's device is invalid or expired."; return UHD_ERROR_INVALID_DEVICE; } - usrp_ptr &usrp = get_usrp_ptrs()[h_u->usrp_index]; - h_s->streamer = usrp.ptr->get_rx_stream(stream_args_c_to_cpp(stream_args)); - h_s->usrp_index = h_u->usrp_index; - ) + usrp_ptr& usrp = get_usrp_ptrs()[h_u->usrp_index]; + h_s->streamer = usrp.ptr->get_rx_stream(stream_args_c_to_cpp(stream_args)); + h_s->usrp_index = h_u->usrp_index;) } static boost::mutex _usrp_get_tx_stream_mutex; uhd_error uhd_usrp_get_tx_stream( - uhd_usrp_handle h_u, - uhd_stream_args_t *stream_args, - uhd_tx_streamer_handle h_s -){ - UHD_SAFE_C_SAVE_ERROR(h_s, - boost::mutex::scoped_lock lock(_usrp_get_tx_stream_mutex); - - if(!get_usrp_ptrs().count(h_u->usrp_index)){ + uhd_usrp_handle h_u, uhd_stream_args_t* stream_args, uhd_tx_streamer_handle h_s) +{ + UHD_SAFE_C_SAVE_ERROR( + h_s, boost::mutex::scoped_lock lock(_usrp_get_tx_stream_mutex); + + if (!get_usrp_ptrs().count(h_u->usrp_index)) { h_s->last_error = "Streamer's device is invalid or expired."; return UHD_ERROR_INVALID_DEVICE; } - usrp_ptr &usrp = get_usrp_ptrs()[h_u->usrp_index]; - h_s->streamer = usrp.ptr->get_tx_stream(stream_args_c_to_cpp(stream_args)); - h_s->usrp_index = h_u->usrp_index; - ) + usrp_ptr& usrp = get_usrp_ptrs()[h_u->usrp_index]; + h_s->streamer = usrp.ptr->get_tx_stream(stream_args_c_to_cpp(stream_args)); + h_s->usrp_index = h_u->usrp_index;) } /**************************************************************************** @@ -351,12 +295,10 @@ uhd_error uhd_usrp_get_tx_stream( out->field = strdup(dict.get(BOOST_STRINGIZE(field)).c_str()) uhd_error uhd_usrp_get_rx_info( - uhd_usrp_handle h, - size_t chan, - uhd_usrp_rx_info_t *info_out -) { - UHD_SAFE_C_SAVE_ERROR(h, - uhd::dict<std::string, std::string> rx_info = USRP(h)->get_usrp_rx_info(chan); + uhd_usrp_handle h, size_t chan, uhd_usrp_rx_info_t* info_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, uhd::dict<std::string, std::string> rx_info = USRP(h)->get_usrp_rx_info(chan); COPY_INFO_FIELD(info_out, rx_info, mboard_id); COPY_INFO_FIELD(info_out, rx_info, mboard_name); @@ -365,17 +307,14 @@ uhd_error uhd_usrp_get_rx_info( COPY_INFO_FIELD(info_out, rx_info, rx_subdev_name); COPY_INFO_FIELD(info_out, rx_info, rx_subdev_spec); COPY_INFO_FIELD(info_out, rx_info, rx_serial); - COPY_INFO_FIELD(info_out, rx_info, rx_antenna); - ) + COPY_INFO_FIELD(info_out, rx_info, rx_antenna);) } uhd_error uhd_usrp_get_tx_info( - uhd_usrp_handle h, - size_t chan, - uhd_usrp_tx_info_t *info_out -) { - UHD_SAFE_C_SAVE_ERROR(h, - uhd::dict<std::string, std::string> tx_info = USRP(h)->get_usrp_tx_info(chan); + uhd_usrp_handle h, size_t chan, uhd_usrp_tx_info_t* info_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, uhd::dict<std::string, std::string> tx_info = USRP(h)->get_usrp_tx_info(chan); COPY_INFO_FIELD(info_out, tx_info, mboard_id); COPY_INFO_FIELD(info_out, tx_info, mboard_name); @@ -384,268 +323,178 @@ uhd_error uhd_usrp_get_tx_info( COPY_INFO_FIELD(info_out, tx_info, tx_subdev_name); COPY_INFO_FIELD(info_out, tx_info, tx_subdev_spec); COPY_INFO_FIELD(info_out, tx_info, tx_serial); - COPY_INFO_FIELD(info_out, tx_info, tx_antenna); - ) + COPY_INFO_FIELD(info_out, tx_info, tx_antenna);) } /**************************************************************************** * Motherboard methods ***************************************************************************/ -uhd_error uhd_usrp_set_master_clock_rate( - uhd_usrp_handle h, - double rate, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_master_clock_rate(rate, mboard); - ) +uhd_error uhd_usrp_set_master_clock_rate(uhd_usrp_handle h, double rate, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_master_clock_rate(rate, mboard);) } uhd_error uhd_usrp_get_master_clock_rate( - uhd_usrp_handle h, - size_t mboard, - double *clock_rate_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *clock_rate_out = USRP(h)->get_master_clock_rate(mboard); - ) + uhd_usrp_handle h, size_t mboard, double* clock_rate_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *clock_rate_out = USRP(h)->get_master_clock_rate(mboard);) } uhd_error uhd_usrp_get_pp_string( - uhd_usrp_handle h, - char* pp_string_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - strncpy(pp_string_out, USRP(h)->get_pp_string().c_str(), strbuffer_len); - ) + uhd_usrp_handle h, char* pp_string_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR( + h, strncpy(pp_string_out, USRP(h)->get_pp_string().c_str(), strbuffer_len);) } uhd_error uhd_usrp_get_mboard_name( - uhd_usrp_handle h, - size_t mboard, - char* mboard_name_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - strncpy(mboard_name_out, USRP(h)->get_mboard_name(mboard).c_str(), strbuffer_len); - ) + uhd_usrp_handle h, size_t mboard, char* mboard_name_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR( + h, + strncpy( + mboard_name_out, USRP(h)->get_mboard_name(mboard).c_str(), strbuffer_len);) } uhd_error uhd_usrp_get_time_now( - uhd_usrp_handle h, - size_t mboard, - int64_t *full_secs_out, - double *frac_secs_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::time_spec_t time_spec_cpp = USRP(h)->get_time_now(mboard); + uhd_usrp_handle h, size_t mboard, int64_t* full_secs_out, double* frac_secs_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, uhd::time_spec_t time_spec_cpp = USRP(h)->get_time_now(mboard); *full_secs_out = time_spec_cpp.get_full_secs(); - *frac_secs_out = time_spec_cpp.get_frac_secs(); - ) + *frac_secs_out = time_spec_cpp.get_frac_secs();) } uhd_error uhd_usrp_get_time_last_pps( - uhd_usrp_handle h, - size_t mboard, - int64_t *full_secs_out, - double *frac_secs_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::time_spec_t time_spec_cpp = USRP(h)->get_time_last_pps(mboard); + uhd_usrp_handle h, size_t mboard, int64_t* full_secs_out, double* frac_secs_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, uhd::time_spec_t time_spec_cpp = USRP(h)->get_time_last_pps(mboard); *full_secs_out = time_spec_cpp.get_full_secs(); - *frac_secs_out = time_spec_cpp.get_frac_secs(); - ) + *frac_secs_out = time_spec_cpp.get_frac_secs();) } uhd_error uhd_usrp_set_time_now( - uhd_usrp_handle h, - int64_t full_secs, - double frac_secs, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::time_spec_t time_spec_cpp(full_secs, frac_secs); - USRP(h)->set_time_now(time_spec_cpp, mboard); - ) + uhd_usrp_handle h, int64_t full_secs, double frac_secs, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR(h, uhd::time_spec_t time_spec_cpp(full_secs, frac_secs); + USRP(h)->set_time_now(time_spec_cpp, mboard);) } uhd_error uhd_usrp_set_time_next_pps( - uhd_usrp_handle h, - int64_t full_secs, - double frac_secs, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::time_spec_t time_spec_cpp(full_secs, frac_secs); - USRP(h)->set_time_next_pps(time_spec_cpp, mboard); - ) + uhd_usrp_handle h, int64_t full_secs, double frac_secs, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR(h, uhd::time_spec_t time_spec_cpp(full_secs, frac_secs); + USRP(h)->set_time_next_pps(time_spec_cpp, mboard);) } uhd_error uhd_usrp_set_time_unknown_pps( - uhd_usrp_handle h, - int64_t full_secs, - double frac_secs -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::time_spec_t time_spec_cpp(full_secs, frac_secs); - USRP(h)->set_time_unknown_pps(time_spec_cpp); - ) + uhd_usrp_handle h, int64_t full_secs, double frac_secs) +{ + UHD_SAFE_C_SAVE_ERROR(h, uhd::time_spec_t time_spec_cpp(full_secs, frac_secs); + USRP(h)->set_time_unknown_pps(time_spec_cpp);) } -uhd_error uhd_usrp_get_time_synchronized( - uhd_usrp_handle h, - bool *result_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *result_out = USRP(h)->get_time_synchronized(); - return UHD_ERROR_NONE; - ) +uhd_error uhd_usrp_get_time_synchronized(uhd_usrp_handle h, bool* result_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *result_out = USRP(h)->get_time_synchronized(); + return UHD_ERROR_NONE;) } uhd_error uhd_usrp_set_command_time( - uhd_usrp_handle h, - int64_t full_secs, - double frac_secs, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::time_spec_t time_spec_cpp(full_secs, frac_secs); - USRP(h)->set_command_time(time_spec_cpp, mboard); - ) + uhd_usrp_handle h, int64_t full_secs, double frac_secs, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR(h, uhd::time_spec_t time_spec_cpp(full_secs, frac_secs); + USRP(h)->set_command_time(time_spec_cpp, mboard);) } -uhd_error uhd_usrp_clear_command_time( - uhd_usrp_handle h, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->clear_command_time(mboard); - ) +uhd_error uhd_usrp_clear_command_time(uhd_usrp_handle h, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->clear_command_time(mboard);) } uhd_error uhd_usrp_set_time_source( - uhd_usrp_handle h, - const char* time_source, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_time_source(std::string(time_source), mboard); - ) + uhd_usrp_handle h, const char* time_source, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_time_source(std::string(time_source), mboard);) } uhd_error uhd_usrp_get_time_source( - uhd_usrp_handle h, - size_t mboard, - char* time_source_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - strncpy(time_source_out, USRP(h)->get_time_source(mboard).c_str(), strbuffer_len); - ) + uhd_usrp_handle h, size_t mboard, char* time_source_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR( + h, + strncpy( + time_source_out, USRP(h)->get_time_source(mboard).c_str(), strbuffer_len);) } uhd_error uhd_usrp_get_time_sources( - uhd_usrp_handle h, - size_t mboard, - uhd_string_vector_handle *time_sources_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - (*time_sources_out)->string_vector_cpp = USRP(h)->get_time_sources(mboard); - ) + uhd_usrp_handle h, size_t mboard, uhd_string_vector_handle* time_sources_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, (*time_sources_out)->string_vector_cpp = USRP(h)->get_time_sources(mboard);) } uhd_error uhd_usrp_set_clock_source( - uhd_usrp_handle h, - const char* clock_source, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_clock_source(std::string(clock_source), mboard); - ) + uhd_usrp_handle h, const char* clock_source, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR( + h, USRP(h)->set_clock_source(std::string(clock_source), mboard);) } uhd_error uhd_usrp_get_clock_source( - uhd_usrp_handle h, - size_t mboard, - char* clock_source_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - strncpy(clock_source_out, USRP(h)->get_clock_source(mboard).c_str(), strbuffer_len); - ) + uhd_usrp_handle h, size_t mboard, char* clock_source_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR( + h, + strncpy( + clock_source_out, USRP(h)->get_clock_source(mboard).c_str(), strbuffer_len);) } uhd_error uhd_usrp_get_clock_sources( - uhd_usrp_handle h, - size_t mboard, - uhd_string_vector_handle *clock_sources_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - (*clock_sources_out)->string_vector_cpp = USRP(h)->get_clock_sources(mboard); - ) + uhd_usrp_handle h, size_t mboard, uhd_string_vector_handle* clock_sources_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, (*clock_sources_out)->string_vector_cpp = USRP(h)->get_clock_sources(mboard);) } -uhd_error uhd_usrp_set_clock_source_out( - uhd_usrp_handle h, - bool enb, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_clock_source_out(enb, mboard); - ) +uhd_error uhd_usrp_set_clock_source_out(uhd_usrp_handle h, bool enb, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_clock_source_out(enb, mboard);) } -uhd_error uhd_usrp_set_time_source_out( - uhd_usrp_handle h, - bool enb, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_time_source_out(enb, mboard); - ) +uhd_error uhd_usrp_set_time_source_out(uhd_usrp_handle h, bool enb, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_time_source_out(enb, mboard);) } -uhd_error uhd_usrp_get_num_mboards( - uhd_usrp_handle h, - size_t *num_mboards_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *num_mboards_out = USRP(h)->get_num_mboards(); - ) +uhd_error uhd_usrp_get_num_mboards(uhd_usrp_handle h, size_t* num_mboards_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *num_mboards_out = USRP(h)->get_num_mboards();) } -uhd_error uhd_usrp_get_mboard_sensor( - uhd_usrp_handle h, +uhd_error uhd_usrp_get_mboard_sensor(uhd_usrp_handle h, const char* name, size_t mboard, - uhd_sensor_value_handle *sensor_value_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - delete (*sensor_value_out)->sensor_value_cpp; - (*sensor_value_out)->sensor_value_cpp = new uhd::sensor_value_t(USRP(h)->get_mboard_sensor(name, mboard)); - ) + uhd_sensor_value_handle* sensor_value_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, delete (*sensor_value_out)->sensor_value_cpp; + (*sensor_value_out)->sensor_value_cpp = new uhd::sensor_value_t( + USRP(h)->get_mboard_sensor(name, mboard));) } uhd_error uhd_usrp_get_mboard_sensor_names( - uhd_usrp_handle h, - size_t mboard, - uhd_string_vector_handle *mboard_sensor_names_out -){ + uhd_usrp_handle h, size_t mboard, uhd_string_vector_handle* mboard_sensor_names_out) +{ UHD_SAFE_C_SAVE_ERROR(h, - (*mboard_sensor_names_out)->string_vector_cpp = USRP(h)->get_mboard_sensor_names(mboard); - ) + (*mboard_sensor_names_out)->string_vector_cpp = + USRP(h)->get_mboard_sensor_names(mboard);) } uhd_error uhd_usrp_set_user_register( - uhd_usrp_handle h, - uint8_t addr, - uint32_t data, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_user_register(addr, data, mboard); - ) + uhd_usrp_handle h, uint8_t addr, uint32_t data, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_user_register(addr, data, mboard);) } /**************************************************************************** @@ -653,63 +502,57 @@ uhd_error uhd_usrp_set_user_register( ***************************************************************************/ uhd_error uhd_usrp_get_mboard_eeprom( - uhd_usrp_handle h, - uhd_mboard_eeprom_handle mb_eeprom, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::fs_path eeprom_path = str(boost::format("/mboards/%d/eeprom") - % mboard); + uhd_usrp_handle h, uhd_mboard_eeprom_handle mb_eeprom, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR( + h, uhd::fs_path eeprom_path = str(boost::format("/mboards/%d/eeprom") % mboard); uhd::property_tree::sptr ptree = USRP(h)->get_device()->get_tree(); - mb_eeprom->mboard_eeprom_cpp = ptree->access<uhd::usrp::mboard_eeprom_t>(eeprom_path).get(); - ) + mb_eeprom->mboard_eeprom_cpp = + ptree->access<uhd::usrp::mboard_eeprom_t>(eeprom_path).get();) } uhd_error uhd_usrp_set_mboard_eeprom( - uhd_usrp_handle h, - uhd_mboard_eeprom_handle mb_eeprom, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::fs_path eeprom_path = str(boost::format("/mboards/%d/eeprom") - % mboard); + uhd_usrp_handle h, uhd_mboard_eeprom_handle mb_eeprom, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR( + h, uhd::fs_path eeprom_path = str(boost::format("/mboards/%d/eeprom") % mboard); uhd::property_tree::sptr ptree = USRP(h)->get_device()->get_tree(); - ptree->access<uhd::usrp::mboard_eeprom_t>(eeprom_path).set(mb_eeprom->mboard_eeprom_cpp); - ) + ptree->access<uhd::usrp::mboard_eeprom_t>(eeprom_path) + .set(mb_eeprom->mboard_eeprom_cpp);) } -uhd_error uhd_usrp_get_dboard_eeprom( - uhd_usrp_handle h, +uhd_error uhd_usrp_get_dboard_eeprom(uhd_usrp_handle h, uhd_dboard_eeprom_handle db_eeprom, const char* unit, const char* slot, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::fs_path eeprom_path = str(boost::format("/mboards/%d/dboards/%s/%s_eeprom") - % mboard % slot % unit); + size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR( + h, + uhd::fs_path eeprom_path = + str(boost::format("/mboards/%d/dboards/%s/%s_eeprom") % mboard % slot % unit); uhd::property_tree::sptr ptree = USRP(h)->get_device()->get_tree(); - db_eeprom->dboard_eeprom_cpp = ptree->access<uhd::usrp::dboard_eeprom_t>(eeprom_path).get(); - ) + db_eeprom->dboard_eeprom_cpp = + ptree->access<uhd::usrp::dboard_eeprom_t>(eeprom_path).get();) } -uhd_error uhd_usrp_set_dboard_eeprom( - uhd_usrp_handle h, +uhd_error uhd_usrp_set_dboard_eeprom(uhd_usrp_handle h, uhd_dboard_eeprom_handle db_eeprom, const char* unit, const char* slot, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::fs_path eeprom_path = str(boost::format("/mboards/%d/dboards/%s/%s_eeprom") - % mboard % slot % unit); + size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR( + h, + uhd::fs_path eeprom_path = + str(boost::format("/mboards/%d/dboards/%s/%s_eeprom") % mboard % slot % unit); uhd::property_tree::sptr ptree = USRP(h)->get_device()->get_tree(); - ptree->access<uhd::usrp::dboard_eeprom_t>(eeprom_path).set(db_eeprom->dboard_eeprom_cpp); - ) + ptree->access<uhd::usrp::dboard_eeprom_t>(eeprom_path) + .set(db_eeprom->dboard_eeprom_cpp);) } /**************************************************************************** @@ -717,395 +560,252 @@ uhd_error uhd_usrp_set_dboard_eeprom( ***************************************************************************/ uhd_error uhd_usrp_set_rx_subdev_spec( - uhd_usrp_handle h, - uhd_subdev_spec_handle subdev_spec, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_rx_subdev_spec(subdev_spec->subdev_spec_cpp, mboard); - ) + uhd_usrp_handle h, uhd_subdev_spec_handle subdev_spec, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR( + h, USRP(h)->set_rx_subdev_spec(subdev_spec->subdev_spec_cpp, mboard);) } uhd_error uhd_usrp_get_rx_subdev_spec( - uhd_usrp_handle h, - size_t mboard, - uhd_subdev_spec_handle subdev_spec_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - subdev_spec_out->subdev_spec_cpp = USRP(h)->get_rx_subdev_spec(mboard); - ) + uhd_usrp_handle h, size_t mboard, uhd_subdev_spec_handle subdev_spec_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, subdev_spec_out->subdev_spec_cpp = USRP(h)->get_rx_subdev_spec(mboard);) } -uhd_error uhd_usrp_get_rx_num_channels( - uhd_usrp_handle h, - size_t *num_channels_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *num_channels_out = USRP(h)->get_rx_num_channels(); - ) +uhd_error uhd_usrp_get_rx_num_channels(uhd_usrp_handle h, size_t* num_channels_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *num_channels_out = USRP(h)->get_rx_num_channels();) } uhd_error uhd_usrp_get_rx_subdev_name( - uhd_usrp_handle h, - size_t chan, - char* rx_subdev_name_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string rx_subdev_name = USRP(h)->get_rx_subdev_name(chan); - strncpy(rx_subdev_name_out, rx_subdev_name.c_str(), strbuffer_len); - ) + uhd_usrp_handle h, size_t chan, char* rx_subdev_name_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR( + h, std::string rx_subdev_name = USRP(h)->get_rx_subdev_name(chan); + strncpy(rx_subdev_name_out, rx_subdev_name.c_str(), strbuffer_len);) } -uhd_error uhd_usrp_set_rx_rate( - uhd_usrp_handle h, - double rate, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_rx_rate(rate, chan); - ) +uhd_error uhd_usrp_set_rx_rate(uhd_usrp_handle h, double rate, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_rx_rate(rate, chan);) } -uhd_error uhd_usrp_get_rx_rate( - uhd_usrp_handle h, - size_t chan, - double *rate_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *rate_out = USRP(h)->get_rx_rate(chan); - ) +uhd_error uhd_usrp_get_rx_rate(uhd_usrp_handle h, size_t chan, double* rate_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *rate_out = USRP(h)->get_rx_rate(chan);) } uhd_error uhd_usrp_get_rx_rates( - uhd_usrp_handle h, - size_t chan, - uhd_meta_range_handle rates_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - rates_out->meta_range_cpp = USRP(h)->get_rx_rates(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_meta_range_handle rates_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, rates_out->meta_range_cpp = USRP(h)->get_rx_rates(chan);) } -uhd_error uhd_usrp_set_rx_freq( - uhd_usrp_handle h, - uhd_tune_request_t *tune_request, +uhd_error uhd_usrp_set_rx_freq(uhd_usrp_handle h, + uhd_tune_request_t* tune_request, size_t chan, - uhd_tune_result_t *tune_result -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::tune_request_t tune_request_cpp = uhd_tune_request_c_to_cpp(tune_request); + uhd_tune_result_t* tune_result) +{ + UHD_SAFE_C_SAVE_ERROR( + h, uhd::tune_request_t tune_request_cpp = uhd_tune_request_c_to_cpp(tune_request); uhd::tune_result_t tune_result_cpp = USRP(h)->set_rx_freq(tune_request_cpp, chan); - uhd_tune_result_cpp_to_c(tune_result_cpp, tune_result); - ) + uhd_tune_result_cpp_to_c(tune_result_cpp, tune_result);) } -uhd_error uhd_usrp_get_rx_freq( - uhd_usrp_handle h, - size_t chan, - double *freq_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *freq_out = USRP(h)->get_rx_freq(chan); - ) +uhd_error uhd_usrp_get_rx_freq(uhd_usrp_handle h, size_t chan, double* freq_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *freq_out = USRP(h)->get_rx_freq(chan);) } uhd_error uhd_usrp_get_rx_freq_range( - uhd_usrp_handle h, - size_t chan, - uhd_meta_range_handle freq_range_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - freq_range_out->meta_range_cpp = USRP(h)->get_rx_freq_range(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_meta_range_handle freq_range_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, freq_range_out->meta_range_cpp = USRP(h)->get_rx_freq_range(chan);) } uhd_error uhd_usrp_get_fe_rx_freq_range( - uhd_usrp_handle h, - size_t chan, - uhd_meta_range_handle freq_range_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - freq_range_out->meta_range_cpp = USRP(h)->get_fe_rx_freq_range(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_meta_range_handle freq_range_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, freq_range_out->meta_range_cpp = USRP(h)->get_fe_rx_freq_range(chan);) } UHD_API uhd_error uhd_usrp_get_rx_lo_names( - uhd_usrp_handle h, - size_t chan, - uhd_string_vector_handle *rx_lo_names_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - (*rx_lo_names_out)->string_vector_cpp = USRP(h)->get_rx_lo_names(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_string_vector_handle* rx_lo_names_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, (*rx_lo_names_out)->string_vector_cpp = USRP(h)->get_rx_lo_names(chan);) } UHD_API uhd_error uhd_usrp_set_rx_lo_source( - uhd_usrp_handle h, - const char* src, - const char* name, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_rx_lo_source(src, name, chan); - ) + uhd_usrp_handle h, const char* src, const char* name, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_rx_lo_source(src, name, chan);) } -UHD_API uhd_error uhd_usrp_get_rx_lo_source( - uhd_usrp_handle h, +UHD_API uhd_error uhd_usrp_get_rx_lo_source(uhd_usrp_handle h, const char* name, size_t chan, char* rx_lo_source_out, - size_t strbuffer_len -){ + size_t strbuffer_len) +{ UHD_SAFE_C_SAVE_ERROR(h, - strncpy(rx_lo_source_out, USRP(h)->get_rx_lo_source(name, chan).c_str(), strbuffer_len); - ) + strncpy(rx_lo_source_out, + USRP(h)->get_rx_lo_source(name, chan).c_str(), + strbuffer_len);) } -UHD_API uhd_error uhd_usrp_get_rx_lo_sources( - uhd_usrp_handle h, +UHD_API uhd_error uhd_usrp_get_rx_lo_sources(uhd_usrp_handle h, const char* name, size_t chan, - uhd_string_vector_handle *rx_lo_sources_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - (*rx_lo_sources_out)->string_vector_cpp = USRP(h)->get_rx_lo_sources(name, chan); - ) + uhd_string_vector_handle* rx_lo_sources_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, + (*rx_lo_sources_out)->string_vector_cpp = USRP(h)->get_rx_lo_sources(name, chan);) } UHD_API uhd_error uhd_usrp_set_rx_lo_export_enabled( - uhd_usrp_handle h, - bool enabled, - const char* name, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_rx_lo_export_enabled(enabled, name, chan); - ) + uhd_usrp_handle h, bool enabled, const char* name, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_rx_lo_export_enabled(enabled, name, chan);) } UHD_API uhd_error uhd_usrp_get_rx_lo_export_enabled( - uhd_usrp_handle h, - const char* name, - size_t chan, - bool* result_out -) { - UHD_SAFE_C_SAVE_ERROR(h, - *result_out = USRP(h)->get_rx_lo_export_enabled(name, chan); - ) + uhd_usrp_handle h, const char* name, size_t chan, bool* result_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *result_out = USRP(h)->get_rx_lo_export_enabled(name, chan);) } -UHD_API uhd_error uhd_usrp_set_rx_lo_freq( - uhd_usrp_handle h, +UHD_API uhd_error uhd_usrp_set_rx_lo_freq(uhd_usrp_handle h, double freq, const char* name, size_t chan, - double* coerced_freq_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *coerced_freq_out = USRP(h)->set_rx_lo_freq(freq, name, chan); - ) + double* coerced_freq_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, *coerced_freq_out = USRP(h)->set_rx_lo_freq(freq, name, chan);) } UHD_API uhd_error uhd_usrp_get_rx_lo_freq( - uhd_usrp_handle h, - const char* name, - size_t chan, - double* rx_lo_freq_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *rx_lo_freq_out = USRP(h)->get_rx_lo_freq(name, chan); - ) + uhd_usrp_handle h, const char* name, size_t chan, double* rx_lo_freq_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *rx_lo_freq_out = USRP(h)->get_rx_lo_freq(name, chan);) } uhd_error uhd_usrp_set_rx_gain( - uhd_usrp_handle h, - double gain, - size_t chan, - const char *gain_name -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string name(gain_name); - if(name.empty()){ - USRP(h)->set_rx_gain(gain, chan); - } - else{ - USRP(h)->set_rx_gain(gain, name, chan); - } - ) + uhd_usrp_handle h, double gain, size_t chan, const char* gain_name) +{ + UHD_SAFE_C_SAVE_ERROR(h, std::string name(gain_name); + if (name.empty()) { USRP(h)->set_rx_gain(gain, chan); } else { + USRP(h)->set_rx_gain(gain, name, chan); + }) } -uhd_error uhd_usrp_set_normalized_rx_gain( - uhd_usrp_handle h, - double gain, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_normalized_rx_gain(gain, chan); - ) +uhd_error uhd_usrp_set_normalized_rx_gain(uhd_usrp_handle h, double gain, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_normalized_rx_gain(gain, chan);) } -uhd_error uhd_usrp_set_rx_agc( - uhd_usrp_handle h, - bool enable, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_rx_agc(enable, chan); - ) +uhd_error uhd_usrp_set_rx_agc(uhd_usrp_handle h, bool enable, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_rx_agc(enable, chan);) } uhd_error uhd_usrp_get_rx_gain( - uhd_usrp_handle h, - size_t chan, - const char *gain_name, - double *gain_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string name(gain_name); - if(name.empty()){ + uhd_usrp_handle h, size_t chan, const char* gain_name, double* gain_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, std::string name(gain_name); if (name.empty()) { *gain_out = USRP(h)->get_rx_gain(chan); - } - else{ - *gain_out = USRP(h)->get_rx_gain(name, chan); - } - ) + } else { *gain_out = USRP(h)->get_rx_gain(name, chan); }) } uhd_error uhd_usrp_get_normalized_rx_gain( - uhd_usrp_handle h, - size_t chan, - double *gain_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *gain_out = USRP(h)->get_normalized_rx_gain(chan); - ) + uhd_usrp_handle h, size_t chan, double* gain_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *gain_out = USRP(h)->get_normalized_rx_gain(chan);) } -uhd_error uhd_usrp_get_rx_gain_range( - uhd_usrp_handle h, +uhd_error uhd_usrp_get_rx_gain_range(uhd_usrp_handle h, const char* name, size_t chan, - uhd_meta_range_handle gain_range_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - gain_range_out->meta_range_cpp = USRP(h)->get_rx_gain_range(name, chan); - ) + uhd_meta_range_handle gain_range_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, gain_range_out->meta_range_cpp = USRP(h)->get_rx_gain_range(name, chan);) } uhd_error uhd_usrp_get_rx_gain_names( - uhd_usrp_handle h, - size_t chan, - uhd_string_vector_handle *gain_names_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - (*gain_names_out)->string_vector_cpp = USRP(h)->get_rx_gain_names(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_string_vector_handle* gain_names_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, (*gain_names_out)->string_vector_cpp = USRP(h)->get_rx_gain_names(chan);) } -uhd_error uhd_usrp_set_rx_antenna( - uhd_usrp_handle h, - const char* ant, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_rx_antenna(std::string(ant), chan); - ) +uhd_error uhd_usrp_set_rx_antenna(uhd_usrp_handle h, const char* ant, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_rx_antenna(std::string(ant), chan);) } uhd_error uhd_usrp_get_rx_antenna( - uhd_usrp_handle h, - size_t chan, - char* ant_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string rx_antenna = USRP(h)->get_rx_antenna(chan); - strncpy(ant_out, rx_antenna.c_str(), strbuffer_len); - ) + uhd_usrp_handle h, size_t chan, char* ant_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR(h, std::string rx_antenna = USRP(h)->get_rx_antenna(chan); + strncpy(ant_out, rx_antenna.c_str(), strbuffer_len);) } uhd_error uhd_usrp_get_rx_antennas( - uhd_usrp_handle h, - size_t chan, - uhd_string_vector_handle *antennas_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - (*antennas_out)->string_vector_cpp = USRP(h)->get_rx_antennas(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_string_vector_handle* antennas_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, (*antennas_out)->string_vector_cpp = USRP(h)->get_rx_antennas(chan);) } -uhd_error uhd_usrp_set_rx_bandwidth( - uhd_usrp_handle h, - double bandwidth, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_rx_bandwidth(bandwidth, chan); - ) +uhd_error uhd_usrp_set_rx_bandwidth(uhd_usrp_handle h, double bandwidth, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_rx_bandwidth(bandwidth, chan);) } -uhd_error uhd_usrp_get_rx_bandwidth( - uhd_usrp_handle h, - size_t chan, - double *bandwidth_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *bandwidth_out = USRP(h)->get_rx_bandwidth(chan); - ) +uhd_error uhd_usrp_get_rx_bandwidth(uhd_usrp_handle h, size_t chan, double* bandwidth_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *bandwidth_out = USRP(h)->get_rx_bandwidth(chan);) } uhd_error uhd_usrp_get_rx_bandwidth_range( - uhd_usrp_handle h, - size_t chan, - uhd_meta_range_handle bandwidth_range_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - bandwidth_range_out->meta_range_cpp = USRP(h)->get_rx_bandwidth_range(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_meta_range_handle bandwidth_range_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, bandwidth_range_out->meta_range_cpp = USRP(h)->get_rx_bandwidth_range(chan);) } -uhd_error uhd_usrp_get_rx_sensor( - uhd_usrp_handle h, +uhd_error uhd_usrp_get_rx_sensor(uhd_usrp_handle h, const char* name, size_t chan, - uhd_sensor_value_handle *sensor_value_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - delete (*sensor_value_out)->sensor_value_cpp; - (*sensor_value_out)->sensor_value_cpp = new uhd::sensor_value_t(USRP(h)->get_rx_sensor(name, chan)); - ) + uhd_sensor_value_handle* sensor_value_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, delete (*sensor_value_out)->sensor_value_cpp; + (*sensor_value_out)->sensor_value_cpp = new uhd::sensor_value_t( + USRP(h)->get_rx_sensor(name, chan));) } uhd_error uhd_usrp_get_rx_sensor_names( - uhd_usrp_handle h, - size_t chan, - uhd_string_vector_handle *sensor_names_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - (*sensor_names_out)->string_vector_cpp = USRP(h)->get_rx_sensor_names(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_string_vector_handle* sensor_names_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, (*sensor_names_out)->string_vector_cpp = USRP(h)->get_rx_sensor_names(chan);) } -uhd_error uhd_usrp_set_rx_dc_offset_enabled( - uhd_usrp_handle h, - bool enb, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_rx_dc_offset(enb, chan); - ) +uhd_error uhd_usrp_set_rx_dc_offset_enabled(uhd_usrp_handle h, bool enb, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_rx_dc_offset(enb, chan);) } -uhd_error uhd_usrp_set_rx_iq_balance_enabled( - uhd_usrp_handle h, - bool enb, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_rx_iq_balance(enb, chan); - ) +uhd_error uhd_usrp_set_rx_iq_balance_enabled(uhd_usrp_handle h, bool enb, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_rx_iq_balance(enb, chan);) } /**************************************************************************** @@ -1113,366 +813,238 @@ uhd_error uhd_usrp_set_rx_iq_balance_enabled( ***************************************************************************/ uhd_error uhd_usrp_set_tx_subdev_spec( - uhd_usrp_handle h, - uhd_subdev_spec_handle subdev_spec, - size_t mboard -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_tx_subdev_spec(subdev_spec->subdev_spec_cpp, mboard); - ) + uhd_usrp_handle h, uhd_subdev_spec_handle subdev_spec, size_t mboard) +{ + UHD_SAFE_C_SAVE_ERROR( + h, USRP(h)->set_tx_subdev_spec(subdev_spec->subdev_spec_cpp, mboard);) } uhd_error uhd_usrp_get_tx_subdev_spec( - uhd_usrp_handle h, - size_t mboard, - uhd_subdev_spec_handle subdev_spec_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - subdev_spec_out->subdev_spec_cpp = USRP(h)->get_tx_subdev_spec(mboard); - ) + uhd_usrp_handle h, size_t mboard, uhd_subdev_spec_handle subdev_spec_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, subdev_spec_out->subdev_spec_cpp = USRP(h)->get_tx_subdev_spec(mboard);) } -uhd_error uhd_usrp_get_tx_num_channels( - uhd_usrp_handle h, - size_t *num_channels_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *num_channels_out = USRP(h)->get_tx_num_channels(); - ) +uhd_error uhd_usrp_get_tx_num_channels(uhd_usrp_handle h, size_t* num_channels_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *num_channels_out = USRP(h)->get_tx_num_channels();) } uhd_error uhd_usrp_get_tx_subdev_name( - uhd_usrp_handle h, - size_t chan, - char* tx_subdev_name_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string tx_subdev_name = USRP(h)->get_tx_subdev_name(chan); - strncpy(tx_subdev_name_out, tx_subdev_name.c_str(), strbuffer_len); - ) + uhd_usrp_handle h, size_t chan, char* tx_subdev_name_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR( + h, std::string tx_subdev_name = USRP(h)->get_tx_subdev_name(chan); + strncpy(tx_subdev_name_out, tx_subdev_name.c_str(), strbuffer_len);) } -uhd_error uhd_usrp_set_tx_rate( - uhd_usrp_handle h, - double rate, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_tx_rate(rate, chan); - ) +uhd_error uhd_usrp_set_tx_rate(uhd_usrp_handle h, double rate, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_tx_rate(rate, chan);) } -uhd_error uhd_usrp_get_tx_rate( - uhd_usrp_handle h, - size_t chan, - double *rate_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *rate_out = USRP(h)->get_tx_rate(chan); - ) +uhd_error uhd_usrp_get_tx_rate(uhd_usrp_handle h, size_t chan, double* rate_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *rate_out = USRP(h)->get_tx_rate(chan);) } uhd_error uhd_usrp_get_tx_rates( - uhd_usrp_handle h, - size_t chan, - uhd_meta_range_handle rates_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - rates_out->meta_range_cpp = USRP(h)->get_tx_rates(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_meta_range_handle rates_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, rates_out->meta_range_cpp = USRP(h)->get_tx_rates(chan);) } -uhd_error uhd_usrp_set_tx_freq( - uhd_usrp_handle h, - uhd_tune_request_t *tune_request, +uhd_error uhd_usrp_set_tx_freq(uhd_usrp_handle h, + uhd_tune_request_t* tune_request, size_t chan, - uhd_tune_result_t *tune_result -){ - UHD_SAFE_C_SAVE_ERROR(h, - uhd::tune_request_t tune_request_cpp = uhd_tune_request_c_to_cpp(tune_request); + uhd_tune_result_t* tune_result) +{ + UHD_SAFE_C_SAVE_ERROR( + h, uhd::tune_request_t tune_request_cpp = uhd_tune_request_c_to_cpp(tune_request); uhd::tune_result_t tune_result_cpp = USRP(h)->set_tx_freq(tune_request_cpp, chan); - uhd_tune_result_cpp_to_c(tune_result_cpp, tune_result); - ) + uhd_tune_result_cpp_to_c(tune_result_cpp, tune_result);) } -uhd_error uhd_usrp_get_tx_freq( - uhd_usrp_handle h, - size_t chan, - double *freq_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *freq_out = USRP(h)->get_tx_freq(chan); - ) +uhd_error uhd_usrp_get_tx_freq(uhd_usrp_handle h, size_t chan, double* freq_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *freq_out = USRP(h)->get_tx_freq(chan);) } uhd_error uhd_usrp_get_tx_freq_range( - uhd_usrp_handle h, - size_t chan, - uhd_meta_range_handle freq_range_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - freq_range_out->meta_range_cpp = USRP(h)->get_tx_freq_range(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_meta_range_handle freq_range_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, freq_range_out->meta_range_cpp = USRP(h)->get_tx_freq_range(chan);) } uhd_error uhd_usrp_get_fe_tx_freq_range( - uhd_usrp_handle h, - size_t chan, - uhd_meta_range_handle freq_range_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - freq_range_out->meta_range_cpp = USRP(h)->get_fe_tx_freq_range(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_meta_range_handle freq_range_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, freq_range_out->meta_range_cpp = USRP(h)->get_fe_tx_freq_range(chan);) } UHD_API uhd_error uhd_usrp_get_tx_lo_names( - uhd_usrp_handle h, - size_t chan, - uhd_string_vector_handle *tx_lo_names_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - (*tx_lo_names_out)->string_vector_cpp = USRP(h)->get_tx_lo_names(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_string_vector_handle* tx_lo_names_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, (*tx_lo_names_out)->string_vector_cpp = USRP(h)->get_tx_lo_names(chan);) } UHD_API uhd_error uhd_usrp_set_tx_lo_source( - uhd_usrp_handle h, - const char* src, - const char* name, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_tx_lo_source(src, name, chan); - ) + uhd_usrp_handle h, const char* src, const char* name, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_tx_lo_source(src, name, chan);) } -UHD_API uhd_error uhd_usrp_get_tx_lo_source( - uhd_usrp_handle h, +UHD_API uhd_error uhd_usrp_get_tx_lo_source(uhd_usrp_handle h, const char* name, size_t chan, char* tx_lo_source_out, - size_t strbuffer_len -){ + size_t strbuffer_len) +{ UHD_SAFE_C_SAVE_ERROR(h, - strncpy(tx_lo_source_out, USRP(h)->get_tx_lo_source(name, chan).c_str(), strbuffer_len); - ) + strncpy(tx_lo_source_out, + USRP(h)->get_tx_lo_source(name, chan).c_str(), + strbuffer_len);) } -UHD_API uhd_error uhd_usrp_get_tx_lo_sources( - uhd_usrp_handle h, +UHD_API uhd_error uhd_usrp_get_tx_lo_sources(uhd_usrp_handle h, const char* name, size_t chan, - uhd_string_vector_handle *tx_lo_sources_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - (*tx_lo_sources_out)->string_vector_cpp = USRP(h)->get_tx_lo_sources(name, chan); - ) + uhd_string_vector_handle* tx_lo_sources_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, + (*tx_lo_sources_out)->string_vector_cpp = USRP(h)->get_tx_lo_sources(name, chan);) } UHD_API uhd_error uhd_usrp_set_tx_lo_export_enabled( - uhd_usrp_handle h, - bool enabled, - const char* name, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_tx_lo_export_enabled(enabled, name, chan); - ) + uhd_usrp_handle h, bool enabled, const char* name, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_tx_lo_export_enabled(enabled, name, chan);) } UHD_API uhd_error uhd_usrp_get_tx_lo_export_enabled( - uhd_usrp_handle h, - const char* name, - size_t chan, - bool* result_out -) { - UHD_SAFE_C_SAVE_ERROR(h, - *result_out = USRP(h)->get_tx_lo_export_enabled(name, chan); - ) + uhd_usrp_handle h, const char* name, size_t chan, bool* result_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *result_out = USRP(h)->get_tx_lo_export_enabled(name, chan);) } -UHD_API uhd_error uhd_usrp_set_tx_lo_freq( - uhd_usrp_handle h, +UHD_API uhd_error uhd_usrp_set_tx_lo_freq(uhd_usrp_handle h, double freq, const char* name, size_t chan, - double* coerced_freq_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *coerced_freq_out = USRP(h)->set_tx_lo_freq(freq, name, chan); - ) + double* coerced_freq_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, *coerced_freq_out = USRP(h)->set_tx_lo_freq(freq, name, chan);) } UHD_API uhd_error uhd_usrp_get_tx_lo_freq( - uhd_usrp_handle h, - const char* name, - size_t chan, - double* tx_lo_freq_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *tx_lo_freq_out = USRP(h)->get_tx_lo_freq(name, chan); - ) + uhd_usrp_handle h, const char* name, size_t chan, double* tx_lo_freq_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *tx_lo_freq_out = USRP(h)->get_tx_lo_freq(name, chan);) } uhd_error uhd_usrp_set_tx_gain( - uhd_usrp_handle h, - double gain, - size_t chan, - const char *gain_name -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string name(gain_name); - if(name.empty()){ - USRP(h)->set_tx_gain(gain, chan); - } - else{ - USRP(h)->set_tx_gain(gain, name, chan); - } - ) + uhd_usrp_handle h, double gain, size_t chan, const char* gain_name) +{ + UHD_SAFE_C_SAVE_ERROR(h, std::string name(gain_name); + if (name.empty()) { USRP(h)->set_tx_gain(gain, chan); } else { + USRP(h)->set_tx_gain(gain, name, chan); + }) } -uhd_error uhd_usrp_set_normalized_tx_gain( - uhd_usrp_handle h, - double gain, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_normalized_tx_gain(gain, chan); - ) +uhd_error uhd_usrp_set_normalized_tx_gain(uhd_usrp_handle h, double gain, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_normalized_tx_gain(gain, chan);) } uhd_error uhd_usrp_get_tx_gain( - uhd_usrp_handle h, - size_t chan, - const char *gain_name, - double *gain_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string name(gain_name); - if(name.empty()){ + uhd_usrp_handle h, size_t chan, const char* gain_name, double* gain_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, std::string name(gain_name); if (name.empty()) { *gain_out = USRP(h)->get_tx_gain(chan); - } - else{ - *gain_out = USRP(h)->get_tx_gain(name, chan); - } - ) + } else { *gain_out = USRP(h)->get_tx_gain(name, chan); }) } uhd_error uhd_usrp_get_normalized_tx_gain( - uhd_usrp_handle h, - size_t chan, - double *gain_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *gain_out = USRP(h)->get_normalized_tx_gain(chan); - ) + uhd_usrp_handle h, size_t chan, double* gain_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *gain_out = USRP(h)->get_normalized_tx_gain(chan);) } -uhd_error uhd_usrp_get_tx_gain_range( - uhd_usrp_handle h, +uhd_error uhd_usrp_get_tx_gain_range(uhd_usrp_handle h, const char* name, size_t chan, - uhd_meta_range_handle gain_range_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - gain_range_out->meta_range_cpp = USRP(h)->get_tx_gain_range(name, chan); - ) + uhd_meta_range_handle gain_range_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, gain_range_out->meta_range_cpp = USRP(h)->get_tx_gain_range(name, chan);) } uhd_error uhd_usrp_get_tx_gain_names( - uhd_usrp_handle h, - size_t chan, - uhd_string_vector_handle *gain_names_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - (*gain_names_out)->string_vector_cpp = USRP(h)->get_tx_gain_names(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_string_vector_handle* gain_names_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, (*gain_names_out)->string_vector_cpp = USRP(h)->get_tx_gain_names(chan);) } -uhd_error uhd_usrp_set_tx_antenna( - uhd_usrp_handle h, - const char* ant, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_tx_antenna(std::string(ant), chan); - ) +uhd_error uhd_usrp_set_tx_antenna(uhd_usrp_handle h, const char* ant, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_tx_antenna(std::string(ant), chan);) } uhd_error uhd_usrp_get_tx_antenna( - uhd_usrp_handle h, - size_t chan, - char* ant_out, - size_t strbuffer_len -){ - UHD_SAFE_C_SAVE_ERROR(h, - std::string tx_antenna = USRP(h)->get_tx_antenna(chan); - strncpy(ant_out, tx_antenna.c_str(), strbuffer_len); - ) + uhd_usrp_handle h, size_t chan, char* ant_out, size_t strbuffer_len) +{ + UHD_SAFE_C_SAVE_ERROR(h, std::string tx_antenna = USRP(h)->get_tx_antenna(chan); + strncpy(ant_out, tx_antenna.c_str(), strbuffer_len);) } uhd_error uhd_usrp_get_tx_antennas( - uhd_usrp_handle h, - size_t chan, - uhd_string_vector_handle *antennas_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - (*antennas_out)->string_vector_cpp = USRP(h)->get_tx_antennas(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_string_vector_handle* antennas_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, (*antennas_out)->string_vector_cpp = USRP(h)->get_tx_antennas(chan);) } -uhd_error uhd_usrp_set_tx_bandwidth( - uhd_usrp_handle h, - double bandwidth, - size_t chan -){ - UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_tx_bandwidth(bandwidth, chan); - ) +uhd_error uhd_usrp_set_tx_bandwidth(uhd_usrp_handle h, double bandwidth, size_t chan) +{ + UHD_SAFE_C_SAVE_ERROR(h, USRP(h)->set_tx_bandwidth(bandwidth, chan);) } -uhd_error uhd_usrp_get_tx_bandwidth( - uhd_usrp_handle h, - size_t chan, - double *bandwidth_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *bandwidth_out = USRP(h)->get_tx_bandwidth(chan); - ) +uhd_error uhd_usrp_get_tx_bandwidth(uhd_usrp_handle h, size_t chan, double* bandwidth_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, *bandwidth_out = USRP(h)->get_tx_bandwidth(chan);) } uhd_error uhd_usrp_get_tx_bandwidth_range( - uhd_usrp_handle h, - size_t chan, - uhd_meta_range_handle bandwidth_range_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - bandwidth_range_out->meta_range_cpp = USRP(h)->get_tx_bandwidth_range(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_meta_range_handle bandwidth_range_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, bandwidth_range_out->meta_range_cpp = USRP(h)->get_tx_bandwidth_range(chan);) } -uhd_error uhd_usrp_get_tx_sensor( - uhd_usrp_handle h, +uhd_error uhd_usrp_get_tx_sensor(uhd_usrp_handle h, const char* name, size_t chan, - uhd_sensor_value_handle *sensor_value_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - delete (*sensor_value_out)->sensor_value_cpp; - (*sensor_value_out)->sensor_value_cpp = new uhd::sensor_value_t(USRP(h)->get_tx_sensor(name, chan)); - ) + uhd_sensor_value_handle* sensor_value_out) +{ + UHD_SAFE_C_SAVE_ERROR(h, delete (*sensor_value_out)->sensor_value_cpp; + (*sensor_value_out)->sensor_value_cpp = new uhd::sensor_value_t( + USRP(h)->get_tx_sensor(name, chan));) } uhd_error uhd_usrp_get_tx_sensor_names( - uhd_usrp_handle h, - size_t chan, - uhd_string_vector_handle *sensor_names_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - (*sensor_names_out)->string_vector_cpp = USRP(h)->get_tx_sensor_names(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_string_vector_handle* sensor_names_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, (*sensor_names_out)->string_vector_cpp = USRP(h)->get_tx_sensor_names(chan);) } /**************************************************************************** @@ -1480,38 +1052,31 @@ uhd_error uhd_usrp_get_tx_sensor_names( ***************************************************************************/ uhd_error uhd_usrp_get_gpio_banks( - uhd_usrp_handle h, - size_t chan, - uhd_string_vector_handle *gpio_banks_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - (*gpio_banks_out)->string_vector_cpp = USRP(h)->get_gpio_banks(chan); - ) + uhd_usrp_handle h, size_t chan, uhd_string_vector_handle* gpio_banks_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, (*gpio_banks_out)->string_vector_cpp = USRP(h)->get_gpio_banks(chan);) } -uhd_error uhd_usrp_set_gpio_attr( - uhd_usrp_handle h, +uhd_error uhd_usrp_set_gpio_attr(uhd_usrp_handle h, const char* bank, const char* attr, uint32_t value, uint32_t mask, - size_t mboard -){ + size_t mboard) +{ UHD_SAFE_C_SAVE_ERROR(h, - USRP(h)->set_gpio_attr(std::string(bank), std::string(attr), - value, mask, mboard); - ) + USRP(h)->set_gpio_attr( + std::string(bank), std::string(attr), value, mask, mboard);) } -uhd_error uhd_usrp_get_gpio_attr( - uhd_usrp_handle h, +uhd_error uhd_usrp_get_gpio_attr(uhd_usrp_handle h, const char* bank, const char* attr, size_t mboard, - uint32_t *attr_out -){ - UHD_SAFE_C_SAVE_ERROR(h, - *attr_out = USRP(h)->get_gpio_attr(std::string(bank), std::string(attr), mboard); - ) + uint32_t* attr_out) +{ + UHD_SAFE_C_SAVE_ERROR( + h, + *attr_out = USRP(h)->get_gpio_attr(std::string(bank), std::string(attr), mboard);) } - diff --git a/host/lib/usrp/x300/x300_defaults.hpp b/host/lib/usrp/x300/x300_defaults.hpp index ae10bf243..8b1be15c7 100644 --- a/host/lib/usrp/x300/x300_defaults.hpp +++ b/host/lib/usrp/x300/x300_defaults.hpp @@ -15,21 +15,21 @@ namespace uhd { namespace usrp { namespace x300 { static constexpr size_t NIUSRPRIO_DEFAULT_RPC_PORT = 5444; -static constexpr size_t XB_DST_E0 = 0; -static constexpr size_t XB_DST_E1 = 1; -static constexpr size_t XB_DST_PCI = 2; -static constexpr size_t XB_DST_R0 = 3; // Radio 0 -> Slot A -static constexpr size_t XB_DST_R1 = 4; // Radio 1 -> Slot B -static constexpr size_t XB_DST_CE0 = 5; +static constexpr size_t XB_DST_E0 = 0; +static constexpr size_t XB_DST_E1 = 1; +static constexpr size_t XB_DST_PCI = 2; +static constexpr size_t XB_DST_R0 = 3; // Radio 0 -> Slot A +static constexpr size_t XB_DST_R1 = 4; // Radio 1 -> Slot B +static constexpr size_t XB_DST_CE0 = 5; static constexpr size_t SRC_ADDR0 = 0; static constexpr size_t SRC_ADDR1 = 1; static constexpr size_t DST_ADDR = 2; -static constexpr double DEFAULT_TICK_RATE = 200e6; // Hz -static constexpr double MAX_TICK_RATE = 200e6; // Hz -static constexpr double MIN_TICK_RATE = 184.32e6; // Hz -static constexpr double BUS_CLOCK_RATE = 187.5e6; // Hz +static constexpr double DEFAULT_TICK_RATE = 200e6; // Hz +static constexpr double MAX_TICK_RATE = 200e6; // Hz +static constexpr double MIN_TICK_RATE = 184.32e6; // Hz +static constexpr double BUS_CLOCK_RATE = 187.5e6; // Hz static constexpr double DEFAULT_SYSREF_RATE = 10e6; static const std::string FW_FILE_NAME = "usrp_x300_fw.bin"; @@ -43,8 +43,7 @@ static const std::vector<std::string> CLOCK_SOURCE_OPTIONS{ "internal", "external", "gpsdo"}; static const std::vector<std::string> TIME_SOURCE_OPTIONS{ "internal", "external", "gpsdo"}; -static const std::vector<double> EXTERNAL_FREQ_OPTIONS{ - 10e6, 11.52e6, 23.04e6, 30.72e6}; +static const std::vector<double> EXTERNAL_FREQ_OPTIONS{10e6, 11.52e6, 23.04e6, 30.72e6}; // Limit the number of initialization threads static const size_t MAX_INIT_THREADS = 10; diff --git a/host/lib/usrp/x300/x300_device_args.hpp b/host/lib/usrp/x300/x300_device_args.hpp index 9e9e328a9..6c6680c4f 100644 --- a/host/lib/usrp/x300/x300_device_args.hpp +++ b/host/lib/usrp/x300/x300_device_args.hpp @@ -257,8 +257,8 @@ private: #ifdef HAVE_DPDK _use_dpdk.set(true); #else - UHD_LOG_WARNING("DPDK", - "Detected use_dpdk argument, but DPDK support not built in."); + UHD_LOG_WARNING( + "DPDK", "Detected use_dpdk argument, but DPDK support not built in."); #endif } PARSE_DEFAULT(_recv_frame_size) diff --git a/host/lib/usrp/x300/x300_image_loader.cpp b/host/lib/usrp/x300/x300_image_loader.cpp index ccd3761df..c8690465b 100644 --- a/host/lib/usrp/x300/x300_image_loader.cpp +++ b/host/lib/usrp/x300/x300_image_loader.cpp @@ -233,9 +233,8 @@ static void x300_setup_session(x300_session_t& session, if (fpga_file_type == "ni-2974") { fpga_file_type = "x310"; } - session.filepath = find_image_path( - str(boost::format("usrp_%s_fpga_%s.bit") - % fpga_file_type % session.fpga_type)); + session.filepath = find_image_path(str(boost::format("usrp_%s_fpga_%s.bit") + % fpga_file_type % session.fpga_type)); } } else session.filepath = filepath; diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 273485577..a414fd0f1 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -9,8 +9,8 @@ #include "x300_impl.hpp" #include "x300_claim.hpp" #include "x300_eth_mgr.hpp" -#include "x300_mb_eeprom.hpp" #include "x300_mb_controller.hpp" +#include "x300_mb_eeprom.hpp" #include "x300_mb_eeprom_iface.hpp" #include "x300_mboard_type.hpp" #include "x300_pcie_mgr.hpp" @@ -179,8 +179,7 @@ static void x300_load_fw(wb_iface::sptr fw_reg_ctrl, const std::string& file_nam UHD_LOGGER_INFO("X300") << "Firmware loaded!"; } -x300_impl::x300_impl(const uhd::device_addr_t& dev_addr) - : rfnoc_device() +x300_impl::x300_impl(const uhd::device_addr_t& dev_addr) : rfnoc_device() { UHD_LOGGER_INFO("X300") << "X300 initialization sequence..."; @@ -215,8 +214,8 @@ x300_impl::x300_impl(const uhd::device_addr_t& dev_addr) void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t& dev_addr) { - const fs_path mb_path = fs_path("/mboards") / mb_i; - mboard_members_t& mb = _mb[mb_i]; + const fs_path mb_path = fs_path("/mboards") / mb_i; + mboard_members_t& mb = _mb[mb_i]; mb.args.parse(dev_addr); mb.xport_path = dev_addr.has_key("resource") ? xport_path_t::NIRIO : xport_path_t::ETH; @@ -483,4 +482,3 @@ void x300_impl::check_fpga_compat(const fs_path& mb_path, const mboard_members_t "Using FPGA version: " << compat_major << "." << compat_minor << " git hash: " << git_hash_str); } - diff --git a/host/lib/usrp/x300/x300_mb_controller.hpp b/host/lib/usrp/x300/x300_mb_controller.hpp index 92844f1b9..f33d629c7 100644 --- a/host/lib/usrp/x300/x300_mb_controller.hpp +++ b/host/lib/usrp/x300/x300_mb_controller.hpp @@ -54,17 +54,26 @@ public: } //! Reference to the ZPU peek/poke interface - uhd::wb_iface::sptr get_zpu_ctrl() { return _zpu_ctrl; } + uhd::wb_iface::sptr get_zpu_ctrl() + { + return _zpu_ctrl; + } //! Return reference to LMK clock controller - x300_clock_ctrl::sptr get_clock_ctrl() { return _clock_ctrl; } + x300_clock_ctrl::sptr get_clock_ctrl() + { + return _clock_ctrl; + } void register_reset_codec_cb(std::function<void(void)>&& reset_cb) { _reset_cbs.push_back(std::move(reset_cb)); } - void set_initialization_done() { _initialization_done = true; } + void set_initialization_done() + { + _initialization_done = true; + } void register_radio(uhd::usrp::x300::x300_radio_mbc_iface* radio) { @@ -80,7 +89,8 @@ public: class x300_timekeeper : public mb_controller::timekeeper { public: - x300_timekeeper(const size_t tk_idx, uhd::wb_iface::sptr zpu_ctrl, const double tick_rate) + x300_timekeeper( + const size_t tk_idx, uhd::wb_iface::sptr zpu_ctrl, const double tick_rate) : _tk_idx(tk_idx), _zpu_ctrl(zpu_ctrl) { set_tick_rate(tick_rate); diff --git a/host/lib/usrp/x300/x300_mb_eeprom_iface.hpp b/host/lib/usrp/x300/x300_mb_eeprom_iface.hpp index 2d08d5711..935f6302d 100644 --- a/host/lib/usrp/x300/x300_mb_eeprom_iface.hpp +++ b/host/lib/usrp/x300/x300_mb_eeprom_iface.hpp @@ -11,8 +11,8 @@ #include <uhd/config.hpp> #include <uhd/types/serial.hpp> #include <uhd/types/wb_iface.hpp> -#include <memory> #include <boost/utility.hpp> +#include <memory> class x300_mb_eeprom_iface : public uhd::i2c_iface { diff --git a/host/lib/usrp/x300/x300_pcie_mgr.cpp b/host/lib/usrp/x300/x300_pcie_mgr.cpp index d2aad7e3c..d3f4eba27 100644 --- a/host/lib/usrp/x300/x300_pcie_mgr.cpp +++ b/host/lib/usrp/x300/x300_pcie_mgr.cpp @@ -29,9 +29,9 @@ using namespace uhd::niusrprio; namespace { -//uint32_t extract_sid_from_pkt(void* pkt, size_t) +// uint32_t extract_sid_from_pkt(void* pkt, size_t) //{ - //return uhd::sid_t(uhd::wtohx(static_cast<const uint32_t*>(pkt)[1])).get_dst(); +// return uhd::sid_t(uhd::wtohx(static_cast<const uint32_t*>(pkt)[1])).get_dst(); //} constexpr uint32_t RADIO_DEST_PREFIX_TX = 0; @@ -42,13 +42,13 @@ constexpr uint32_t RADIO_DEST_PREFIX_TX = 0; // 64 frames * 256 bytes each aligns with the typical page size of 4096 bytes. Since most // page sizes are 4096 bytes or some multiple of that, keep the number of frames * frame // size aligned to it. -constexpr size_t PCIE_RX_DATA_FRAME_SIZE = 4096; // bytes -constexpr size_t PCIE_RX_DATA_NUM_FRAMES = 4096; -constexpr size_t PCIE_TX_DATA_FRAME_SIZE = 4096; // bytes -constexpr size_t PCIE_TX_DATA_NUM_FRAMES = 4096; -constexpr size_t PCIE_MSG_FRAME_SIZE = 256; // bytes -constexpr size_t PCIE_MSG_NUM_FRAMES = 64; -constexpr size_t PCIE_MAX_CHANNELS = 6; +constexpr size_t PCIE_RX_DATA_FRAME_SIZE = 4096; // bytes +constexpr size_t PCIE_RX_DATA_NUM_FRAMES = 4096; +constexpr size_t PCIE_TX_DATA_FRAME_SIZE = 4096; // bytes +constexpr size_t PCIE_TX_DATA_NUM_FRAMES = 4096; +constexpr size_t PCIE_MSG_FRAME_SIZE = 256; // bytes +constexpr size_t PCIE_MSG_NUM_FRAMES = 64; +constexpr size_t PCIE_MAX_CHANNELS = 6; // constexpr size_t MAX_RATE_PCIE = 800000000; // bytes/s diff --git a/host/lib/usrp/x300/x300_prop_tree.cpp b/host/lib/usrp/x300/x300_prop_tree.cpp index 21597beea..4f40f3514 100644 --- a/host/lib/usrp/x300/x300_prop_tree.cpp +++ b/host/lib/usrp/x300/x300_prop_tree.cpp @@ -14,8 +14,7 @@ using namespace uhd::rfnoc; namespace uhd { namespace usrp { namespace x300 { -void init_prop_tree( - const size_t mb_idx, x300_mb_controller* mbc, property_tree::sptr pt) +void init_prop_tree(const size_t mb_idx, x300_mb_controller* mbc, property_tree::sptr pt) { const fs_path mb_path = fs_path("/mboards") / mb_idx; try { @@ -42,17 +41,15 @@ void init_prop_tree( //////////////////////////////////////////////////////////////////// pt->create<std::string>(mb_path / "time_source" / "value") .set(mbc->get_time_source()) - .add_coerced_subscriber([mbc](const std::string& time_source) { - mbc->set_time_source(time_source); - }); + .add_coerced_subscriber( + [mbc](const std::string& time_source) { mbc->set_time_source(time_source); }); pt->create<std::vector<std::string>>(mb_path / "time_source" / "options") .set(mbc->get_time_sources()); // setup the time output, default to ON pt->create<bool>(mb_path / "time_source" / "output") - .add_coerced_subscriber([mbc](const bool time_output) { - mbc->set_time_source_out(time_output); - }) + .add_coerced_subscriber( + [mbc](const bool time_output) { mbc->set_time_source_out(time_output); }) .set(true); //////////////////////////////////////////////////////////////////// @@ -69,9 +66,8 @@ void init_prop_tree( // setup external reference options. default to 10 MHz input reference pt->create<std::string>(mb_path / "clock_source" / "external"); - pt - ->create<std::vector<double>>( - mb_path / "clock_source" / "external" / "freq" / "options") + pt->create<std::vector<double>>( + mb_path / "clock_source" / "external" / "freq" / "options") .set(EXTERNAL_FREQ_OPTIONS); pt->create<double>(mb_path / "clock_source" / "external" / "value") .set(mbc->get_clock_ctrl()->get_sysref_clock_rate()) diff --git a/host/lib/usrp/x300/x300_radio_control.cpp b/host/lib/usrp/x300/x300_radio_control.cpp index 48b484467..1bd88164a 100644 --- a/host/lib/usrp/x300/x300_radio_control.cpp +++ b/host/lib/usrp/x300/x300_radio_control.cpp @@ -28,11 +28,11 @@ #include <uhdlib/usrp/cores/spi_core_3000.hpp> #include <uhdlib/usrp/cores/tx_frontend_core_200.hpp> #include <boost/algorithm/string.hpp> -#include <memory> #include <algorithm> #include <chrono> #include <functional> #include <iostream> +#include <memory> #include <thread> using namespace uhd; @@ -869,26 +869,19 @@ public: constexpr uint16_t mask = 0xFFFF; if (attr == "CTRL") { _db_iface->set_pin_ctrl(unit, value, mask); - } - else if (attr == "DDR") { + } else if (attr == "DDR") { _db_iface->set_gpio_ddr(unit, value, mask); - } - else if (attr == "OUT") { + } else if (attr == "OUT") { _db_iface->set_gpio_out(unit, value, mask); - } - else if (attr == "ATR_0X") { + } else if (attr == "ATR_0X") { _db_iface->set_atr_reg(unit, gpio_atr::ATR_REG_IDLE, value, mask); - } - else if (attr == "ATR_RX") { + } else if (attr == "ATR_RX") { _db_iface->set_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY, value, mask); - } - else if (attr == "ATR_TX") { + } else if (attr == "ATR_TX") { _db_iface->set_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY, value, mask); - } - else if (attr == "ATR_XX") { + } else if (attr == "ATR_XX") { _db_iface->set_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX, value, mask); - } - else { + } else { RFNOC_LOG_ERROR("Invalid GPIO attribute name: " << attr); throw uhd::key_error(std::string("Invalid GPIO attribute name: ") + attr); } diff --git a/host/lib/usrp/x300/x300_regs.hpp b/host/lib/usrp/x300/x300_regs.hpp index 86ffd46c4..5e9876507 100644 --- a/host/lib/usrp/x300/x300_regs.hpp +++ b/host/lib/usrp/x300/x300_regs.hpp @@ -27,14 +27,14 @@ static const int BL_DATA = 1; // I2C1 device addresses #define MBOARD_EEPROM_ADDR 0x50 -static const int ZPU_SR_LEDS = 00; -static const int ZPU_SR_SW_RST = 01; -static const int ZPU_SR_CLOCK_CTRL = 02; -static const int ZPU_SR_XB_LOCAL = 03; -static const int ZPU_SR_REF_FREQ = 04; -static const int ZPU_SR_SPI = 32; -static const int ZPU_SR_ETHINT0 = 40; -static const int ZPU_SR_ETHINT1 = 56; +static const int ZPU_SR_LEDS = 00; +static const int ZPU_SR_SW_RST = 01; +static const int ZPU_SR_CLOCK_CTRL = 02; +static const int ZPU_SR_XB_LOCAL = 03; +static const int ZPU_SR_REF_FREQ = 04; +static const int ZPU_SR_SPI = 32; +static const int ZPU_SR_ETHINT0 = 40; +static const int ZPU_SR_ETHINT1 = 56; static const int ZPU_SR_FP_GPIO_SRC = 72; // reset bits @@ -43,13 +43,13 @@ static const int ZPU_SR_FP_GPIO_SRC = 72; #define ZPU_SR_SW_RST_RADIO_CLK_PLL (1 << 2) #define ZPU_SR_SW_RST_ADC_IDELAYCTRL (1 << 3) -static const int ZPU_RB_SPI = 2; -static const int ZPU_RB_CLK_STATUS = 3; -static const int ZPU_RB_COMPAT_NUM = 6; -static const int ZPU_RB_NUM_CE = 7; -static const int ZPU_RB_GIT_HASH = 10; -static const int ZPU_RB_SFP0_TYPE = 4; -static const int ZPU_RB_SFP1_TYPE = 5; +static const int ZPU_RB_SPI = 2; +static const int ZPU_RB_CLK_STATUS = 3; +static const int ZPU_RB_COMPAT_NUM = 6; +static const int ZPU_RB_NUM_CE = 7; +static const int ZPU_RB_GIT_HASH = 10; +static const int ZPU_RB_SFP0_TYPE = 4; +static const int ZPU_RB_SFP1_TYPE = 5; static const int ZPU_RB_FP_GPIO_SRC = 13; static const uint32_t RB_SFP_1G_ETH = 0; diff --git a/host/lib/usrp_clock/octoclock/octoclock_uart.cpp b/host/lib/usrp_clock/octoclock/octoclock_uart.cpp index 4f4ad1e55..0666107c3 100644 --- a/host/lib/usrp_clock/octoclock/octoclock_uart.cpp +++ b/host/lib/usrp_clock/octoclock/octoclock_uart.cpp @@ -107,7 +107,7 @@ std::string octoclock_uart_iface::read_uart(double timeout) void octoclock_uart_iface::_update_cache() { auto pkt_out = make_octoclock_packet(); - size_t len = 0; + size_t len = 0; uint8_t octoclock_data[udp_simple::mtu]; const octoclock_packet_t* pkt_in = diff --git a/host/lib/utils/compat_check.cpp b/host/lib/utils/compat_check.cpp index e340e5c67..834e23ee4 100644 --- a/host/lib/utils/compat_check.cpp +++ b/host/lib/utils/compat_check.cpp @@ -9,57 +9,50 @@ #include <uhdlib/utils/compat_check.hpp> #include <boost/format.hpp> -void uhd::assert_fpga_compat( - const size_t uhd_major, +void uhd::assert_fpga_compat(const size_t uhd_major, const size_t uhd_minor, const uint64_t fpga_compat, const std::string& fpga_component, const std::string& log_component, - const bool fail_on_minor_behind -) { + const bool fail_on_minor_behind) +{ const size_t fpga_major = fpga_compat >> 32; const size_t fpga_minor = fpga_compat & 0xFFFFFFFF; if (!log_component.empty()) { UHD_LOGGER_DEBUG(log_component) << "Checking compat number for FPGA component `" << fpga_component - << "': Expecting " << uhd_major << "." << uhd_minor << ", actual: " - << fpga_major << "." << fpga_minor << "." - ; + << "': Expecting " << uhd_major << "." << uhd_minor + << ", actual: " << fpga_major << "." << fpga_minor << "."; } if (uhd_major > fpga_major) { if (!log_component.empty()) { UHD_LOGGER_ERROR(log_component) - << "Major compat number mismatch for " << fpga_component << ":" - " Expecting " << uhd_major << ", got " << fpga_major << "." - ; + << "Major compat number mismatch for " << fpga_component + << ":" + " Expecting " + << uhd_major << ", got " << fpga_major << "."; } - throw uhd::runtime_error(str( - boost::format("FPGA component `%s' is revision %d and UHD supports" - " revision %d. Please either upgrade the FPGA" - " image (recommended) or downgrade UHD.") - % fpga_component - % fpga_major - % uhd_major - )); + throw uhd::runtime_error( + str(boost::format("FPGA component `%s' is revision %d and UHD supports" + " revision %d. Please either upgrade the FPGA" + " image (recommended) or downgrade UHD.") + % fpga_component % fpga_major % uhd_major)); } if (uhd_major < fpga_major) { if (!log_component.empty()) { UHD_LOGGER_ERROR(log_component) - << "Major compat number mismatch for " << fpga_component << ":" - " Expecting " << uhd_major << ", got " << fpga_major << "." - ; + << "Major compat number mismatch for " << fpga_component + << ":" + " Expecting " + << uhd_major << ", got " << fpga_major << "."; } - throw uhd::runtime_error(str( - boost::format("FPGA component `%s' is revision %d and UHD supports" - " revision %d. Please either upgrade UHD " - " (recommended) or downgrade the FPGA image.") - % fpga_component - % fpga_major - % uhd_major - )); - + throw uhd::runtime_error( + str(boost::format("FPGA component `%s' is revision %d and UHD supports" + " revision %d. Please either upgrade UHD " + " (recommended) or downgrade the FPGA image.") + % fpga_component % fpga_major % uhd_major)); } if (uhd_minor > fpga_minor) { if (fail_on_minor_behind) { @@ -67,34 +60,19 @@ void uhd::assert_fpga_compat( UHD_LOGGER_ERROR(log_component) << str( boost::format("Minor compat number mismatch for `%s':" " Expecting %d.%d, got %d.%d.") - % fpga_component - % uhd_major - % uhd_minor - % fpga_major - % fpga_minor - ); + % fpga_component % uhd_major % uhd_minor % fpga_major % fpga_minor); } - throw uhd::runtime_error(str( - boost::format("FPGA component `%s' is revision %d.%d and UHD supports" - " revision %d.%d. Please either upgrade UHD " - " (recommended) or downgrade the FPGA image.") - % fpga_component - % fpga_major - % fpga_minor - % uhd_major - % uhd_minor - )); + throw uhd::runtime_error( + str(boost::format("FPGA component `%s' is revision %d.%d and UHD supports" + " revision %d.%d. Please either upgrade UHD " + " (recommended) or downgrade the FPGA image.") + % fpga_component % fpga_major % fpga_minor % uhd_major % uhd_minor)); } else { if (!log_component.empty()) { UHD_LOGGER_WARNING(log_component) << str( boost::format("Non-critical minor compat number mismatch " "for `%s': Expecting %d.%d, got %d.%d.") - % fpga_component - % uhd_major - % uhd_minor - % fpga_major - % fpga_minor - ); + % fpga_component % uhd_major % uhd_minor % fpga_major % fpga_minor); } } } else if (uhd_minor < fpga_minor) { @@ -102,12 +80,7 @@ void uhd::assert_fpga_compat( UHD_LOGGER_WARNING(log_component) << str( boost::format("Non-critical minor compat number mismatch " "for `%s': Expecting %d.%d, got %d.%d.") - % fpga_component - % uhd_major - % uhd_minor - % fpga_major - % fpga_minor - ); + % fpga_component % uhd_major % uhd_minor % fpga_major % fpga_minor); } } // We got here? Then all is good. diff --git a/host/lib/utils/config_parser.cpp b/host/lib/utils/config_parser.cpp index c46671623..bf0cdf5ff 100644 --- a/host/lib/utils/config_parser.cpp +++ b/host/lib/utils/config_parser.cpp @@ -5,36 +5,30 @@ // #include <uhdlib/utils/config_parser.hpp> -#include <boost/format.hpp> #include <boost/filesystem.hpp> +#include <boost/format.hpp> #include <boost/property_tree/ini_parser.hpp> using namespace uhd; -config_parser::config_parser(const std::string &path) +config_parser::config_parser(const std::string& path) { if (not path.empty()) { try { boost::property_tree::ini_parser::read_ini(path, _pt); - } catch (const boost::property_tree::ini_parser_error &) { - throw uhd::runtime_error(str( - boost::format("Unable to parse file %s") - % path - )); + } catch (const boost::property_tree::ini_parser_error&) { + throw uhd::runtime_error( + str(boost::format("Unable to parse file %s") % path)); } } } -void config_parser::read_file(const std::string &path) +void config_parser::read_file(const std::string& path) { config_parser new_config(path); for (const auto& section : new_config.sections()) { for (const auto& key : new_config.options(section)) { - set<std::string>( - section, - key, - new_config.get<std::string>(section, key) - ); + set<std::string>(section, key, new_config.get<std::string>(section, key)); } } } @@ -43,17 +37,16 @@ std::vector<std::string> config_parser::sections() { try { return _options(_pt); - } catch (const boost::property_tree::ptree_bad_path &) { + } catch (const boost::property_tree::ptree_bad_path&) { return std::vector<std::string>{}; } } -std::vector<std::string> config_parser::options(const std::string §ion) +std::vector<std::string> config_parser::options(const std::string& section) { try { return _options(_pt.get_child(section)); - } catch (const boost::property_tree::ptree_bad_path &) { + } catch (const boost::property_tree::ptree_bad_path&) { return std::vector<std::string>{}; } } - diff --git a/host/lib/utils/csv.cpp b/host/lib/utils/csv.cpp index 29b219fef..752b2e881 100644 --- a/host/lib/utils/csv.cpp +++ b/host/lib/utils/csv.cpp @@ -9,30 +9,32 @@ using namespace uhd; -csv::rows_type csv::to_rows(std::istream &input){ +csv::rows_type csv::to_rows(std::istream& input) +{ csv::rows_type rows; std::string line; - //for each line in the input stream - while (std::getline(input, line)){ + // for each line in the input stream + while (std::getline(input, line)) { csv::row_type row(1, ""); bool in_quote = false; char last_ch, next_ch = ' '; - //for each character in the line - for(char ch: line){ + // for each character in the line + for (char ch : line) { last_ch = next_ch; next_ch = ch; - //catch a quote character and change the state - //we handle double quotes by checking last_ch - if (ch == '"'){ + // catch a quote character and change the state + // we handle double quotes by checking last_ch + if (ch == '"') { in_quote = not in_quote; - if (last_ch != '"') continue; + if (last_ch != '"') + continue; } - //a comma not inside quotes is a column delimiter - if (not in_quote and ch == ','){ + // a comma not inside quotes is a column delimiter + if (not in_quote and ch == ',') { row.push_back(""); continue; } - //if we got here we record the character + // if we got here we record the character row.back() += ch; } rows.push_back(row); diff --git a/host/lib/utils/eeprom_utils.cpp b/host/lib/utils/eeprom_utils.cpp index 6999827c0..2cb1c7571 100644 --- a/host/lib/utils/eeprom_utils.cpp +++ b/host/lib/utils/eeprom_utils.cpp @@ -7,16 +7,15 @@ #include <uhdlib/utils/eeprom_utils.hpp> #include <boost/lexical_cast.hpp> -uhd::byte_vector_t string_to_uint16_bytes(const std::string &num_str){ - const uint16_t num = boost::lexical_cast<uint16_t>(num_str); - const std::vector<uint8_t> lsb_msb = { - uint8_t(num >> 0), - uint8_t(num >> 8) - }; +uhd::byte_vector_t string_to_uint16_bytes(const std::string& num_str) +{ + const uint16_t num = boost::lexical_cast<uint16_t>(num_str); + const std::vector<uint8_t> lsb_msb = {uint8_t(num >> 0), uint8_t(num >> 8)}; return lsb_msb; } -std::string uint16_bytes_to_string(const uhd::byte_vector_t &bytes){ +std::string uint16_bytes_to_string(const uhd::byte_vector_t& bytes) +{ const uint16_t num = (uint16_t(bytes.at(0)) << 0) | (uint16_t(bytes.at(1)) << 8); - return (num == 0 or num == 0xffff)? "" : std::to_string(num); + return (num == 0 or num == 0xffff) ? "" : std::to_string(num); } diff --git a/host/lib/utils/gain_group.cpp b/host/lib/utils/gain_group.cpp index 32f14d062..c414bc5ff 100644 --- a/host/lib/utils/gain_group.cpp +++ b/host/lib/utils/gain_group.cpp @@ -130,7 +130,10 @@ public: } std::sort(indexes_step_size_dec.begin(), indexes_step_size_dec.end(), - std::bind(&compare_by_step_size, std::placeholders::_1, std::placeholders::_2, all_fcns)); + std::bind(&compare_by_step_size, + std::placeholders::_1, + std::placeholders::_2, + all_fcns)); UHD_ASSERT_THROW(all_fcns.at(indexes_step_size_dec.front()).get_range().step() >= all_fcns.at(indexes_step_size_dec.back()).get_range().step()); diff --git a/host/lib/utils/ihex.cpp b/host/lib/utils/ihex.cpp index 24d8cbdb6..bea03c2ac 100644 --- a/host/lib/utils/ihex.cpp +++ b/host/lib/utils/ihex.cpp @@ -22,7 +22,7 @@ using namespace uhd; */ static bool checksum(const std::string& record) { - size_t len = record.length(); + size_t len = record.length(); unsigned char sum = 0; unsigned int val; @@ -32,9 +32,9 @@ static bool checksum(const std::string& record) } if (sum == 0) - return true; + return true; else - return false; + return false; } @@ -48,13 +48,12 @@ static bool checksum(const std::string& record) * \param data output data * \return true if record is sucessfully read, false on error */ -static bool parse_record( - const std::string& record, - uint16_t &len, - uint16_t &addr, - uint16_t &type, - unsigned char* data -) { +static bool parse_record(const std::string& record, + uint16_t& len, + uint16_t& addr, + uint16_t& type, + unsigned char* data) +{ unsigned int i; unsigned int val; @@ -65,20 +64,19 @@ static bool parse_record( std::istringstream(record.substr(3, 4)) >> std::hex >> addr; std::istringstream(record.substr(7, 2)) >> std::hex >> type; - if (len > (2 * (record.length() - 9))) // sanity check to prevent buffer overrun + if (len > (2 * (record.length() - 9))) // sanity check to prevent buffer overrun return false; for (i = 0; i < len; i++) { std::istringstream(record.substr(9 + 2 * i, 2)) >> std::hex >> val; - data[i] = (unsigned char) val; + data[i] = (unsigned char)val; } return true; } -ihex_reader::ihex_reader(const std::string &ihex_filename) - : _ihex_filename(ihex_filename) +ihex_reader::ihex_reader(const std::string& ihex_filename) : _ihex_filename(ihex_filename) { // nop } @@ -86,12 +84,12 @@ ihex_reader::ihex_reader(const std::string &ihex_filename) void ihex_reader::read(ihex_reader::record_handle_type record_handler) { - const char *filename = _ihex_filename.c_str(); + const char* filename = _ihex_filename.c_str(); /* Fields used in every record. */ - uint16_t len = 0; - uint16_t type = 0; - uint16_t lower_address_bits = 0x0000; + uint16_t len = 0; + uint16_t type = 0; + uint16_t lower_address_bits = 0x0000; static const int MAX_RECORD_LENGTH = 255; unsigned char data[MAX_RECORD_LENGTH]; @@ -103,7 +101,7 @@ void ihex_reader::read(ihex_reader::record_handle_type record_handler) std::ifstream file; file.open(filename, std::ifstream::in); - if(!file.good()) { + if (!file.good()) { throw uhd::io_error("ihex_reader::read(): cannot open firmware input file"); } @@ -126,14 +124,16 @@ void ihex_reader::read(ihex_reader::record_handle_type record_handler) ret = record_handler(lower_address_bits, upper_address_bits, data, len); if (ret < 0) { - throw uhd::io_error("ihex_reader::read(): record hander returned failure code"); + throw uhd::io_error( + "ihex_reader::read(): record hander returned failure code"); } } /* Type 0x01: EOF. */ else if (type == 0x01) { - if (lower_address_bits != 0x0000 || len != 0 ) { - throw uhd::io_error("ihex_reader::read(): For EOF record, address must be 0, length must be 0."); + if (lower_address_bits != 0x0000 || len != 0) { + throw uhd::io_error("ihex_reader::read(): For EOF record, address must " + "be 0, length must be 0."); } /* Successful termination! */ @@ -143,35 +143,39 @@ void ihex_reader::read(ihex_reader::record_handle_type record_handler) /* Type 0x04: Extended Linear Address Record. */ else if (type == 0x04) { - if (lower_address_bits != 0x0000 || len != 2 ) { - throw uhd::io_error("ihex_reader::read(): For ELA record, address must be 0, length must be 2."); + if (lower_address_bits != 0x0000 || len != 2) { + throw uhd::io_error("ihex_reader::read(): For ELA record, address must " + "be 0, length must be 2."); } - upper_address_bits = ((uint16_t)((data[0] & 0x00FF) << 8))\ - + ((uint16_t)(data[1] & 0x00FF)); + upper_address_bits = + ((uint16_t)((data[0] & 0x00FF) << 8)) + ((uint16_t)(data[1] & 0x00FF)); } /* Type 0x05: Start Linear Address Record. */ else if (type == 0x05) { - if (lower_address_bits != 0x0000 || len != 4 ) { - throw uhd::io_error("ihex_reader::read(): For SLA record, address must be 0, length must be 4."); + if (lower_address_bits != 0x0000 || len != 4) { + throw uhd::io_error("ihex_reader::read(): For SLA record, address must " + "be 0, length must be 4."); } /* The firmware load is complete. We now need to tell the CPU * to jump to an execution address start point, now contained within * the data field. Parse these address bits out, and then push the * instruction. */ - upper_address_bits = ((uint16_t)((data[0] & 0x00FF) << 8))\ - + ((uint16_t)(data[1] & 0x00FF)); - lower_address_bits = ((uint16_t)((data[2] & 0x00FF) << 8))\ - + ((uint16_t)(data[3] & 0x00FF)); + upper_address_bits = + ((uint16_t)((data[0] & 0x00FF) << 8)) + ((uint16_t)(data[1] & 0x00FF)); + lower_address_bits = + ((uint16_t)((data[2] & 0x00FF) << 8)) + ((uint16_t)(data[3] & 0x00FF)); record_handler(lower_address_bits, upper_address_bits, 0, 0); } /* If we receive an unknown record type, error out. */ else { - throw uhd::io_error(str(boost::format("ihex_reader::read(): unsupported record type: %X.") % type)); + throw uhd::io_error( + str(boost::format("ihex_reader::read(): unsupported record type: %X.") + % type)); } } @@ -181,33 +185,33 @@ void ihex_reader::read(ihex_reader::record_handle_type record_handler) // We need a functor for the cast, a lambda would be perfect... int _file_writer_callback( - std::shared_ptr<std::ofstream> output_file, - unsigned char *buff, - uint16_t len -) { - output_file->write((const char *) buff, len); + std::shared_ptr<std::ofstream> output_file, unsigned char* buff, uint16_t len) +{ + output_file->write((const char*)buff, len); return 0; } -void ihex_reader::to_bin_file(const std::string &bin_filename) +void ihex_reader::to_bin_file(const std::string& bin_filename) { std::shared_ptr<std::ofstream> output_file(std::make_shared<std::ofstream>()); output_file->open(bin_filename.c_str(), std::ios::out | std::ios::binary); if (not output_file->is_open()) { - throw uhd::io_error(str(boost::format("Could not open file for writing: %s") % bin_filename)); + throw uhd::io_error( + str(boost::format("Could not open file for writing: %s") % bin_filename)); } - this->read(std::bind(&_file_writer_callback, output_file, std::placeholders::_3, std::placeholders::_4)); + this->read(std::bind(&_file_writer_callback, + output_file, + std::placeholders::_3, + std::placeholders::_4)); output_file->close(); } // We need a functor for the cast, a lambda would be perfect... int _vector_writer_callback( - std::vector<uint8_t>& vector, - unsigned char *buff, - uint16_t len -) { + std::vector<uint8_t>& vector, unsigned char* buff, uint16_t len) +{ for (size_t i = 0; i < len; i++) { vector.push_back(buff[i]); } @@ -220,8 +224,10 @@ std::vector<uint8_t> ihex_reader::to_vector(const size_t size_estimate) std::vector<uint8_t> buf; buf.reserve(size_estimate == 0 ? DEFAULT_SIZE_ESTIMATE : size_estimate); - this->read(std::bind(&_vector_writer_callback, std::ref(buf), std::placeholders::_3, std::placeholders::_4)); + this->read(std::bind(&_vector_writer_callback, + std::ref(buf), + std::placeholders::_3, + std::placeholders::_4)); return buf; } - diff --git a/host/lib/utils/load_modules.cpp b/host/lib/utils/load_modules.cpp index c862a0abd..cac678975 100644 --- a/host/lib/utils/load_modules.cpp +++ b/host/lib/utils/load_modules.cpp @@ -5,11 +5,11 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include <uhd/exception.hpp> #include <uhd/utils/paths.hpp> #include <uhd/utils/static.hpp> -#include <uhd/exception.hpp> -#include <boost/format.hpp> #include <boost/filesystem.hpp> +#include <boost/format.hpp> #include <iostream> #include <string> #include <vector> @@ -20,34 +20,34 @@ namespace fs = boost::filesystem; * Module Load Function **********************************************************************/ #ifdef HAVE_DLOPEN -#include <dlfcn.h> -static void load_module(const std::string &file_name){ - if (dlopen(file_name.c_str(), RTLD_LAZY) == NULL){ - throw uhd::os_error(str( - boost::format("dlopen failed to load \"%s\"") % file_name - )); +# include <dlfcn.h> +static void load_module(const std::string& file_name) +{ + if (dlopen(file_name.c_str(), RTLD_LAZY) == NULL) { + throw uhd::os_error( + str(boost::format("dlopen failed to load \"%s\"") % file_name)); } } #endif /* HAVE_DLOPEN */ #ifdef HAVE_LOAD_LIBRARY -#include <windows.h> -static void load_module(const std::string &file_name){ - if (LoadLibrary(file_name.c_str()) == NULL){ - throw uhd::os_error(str( - boost::format("LoadLibrary failed to load \"%s\"") % file_name - )); +# include <windows.h> +static void load_module(const std::string& file_name) +{ + if (LoadLibrary(file_name.c_str()) == NULL) { + throw uhd::os_error( + str(boost::format("LoadLibrary failed to load \"%s\"") % file_name)); } } #endif /* HAVE_LOAD_LIBRARY */ #ifdef HAVE_LOAD_MODULES_DUMMY -static void load_module(const std::string &file_name){ +static void load_module(const std::string& file_name) +{ throw uhd::not_implemented_error(str( - boost::format("Module loading not supported: Cannot load \"%s\"") % file_name - )); + boost::format("Module loading not supported: Cannot load \"%s\"") % file_name)); } #endif /* HAVE_LOAD_MODULES_DUMMY */ @@ -60,29 +60,27 @@ static void load_module(const std::string &file_name){ * Does not throw, prints to std error. * \param path the filesystem path */ -static void load_module_path(const fs::path &path){ - if (not fs::exists(path)){ - //std::cerr << boost::format("Module path \"%s\" not found.") % path.string() << std::endl; +static void load_module_path(const fs::path& path) +{ + if (not fs::exists(path)) { + // std::cerr << boost::format("Module path \"%s\" not found.") % path.string() << + // std::endl; return; } - //try to load the files in this path - if (fs::is_directory(path)){ - for( - fs::directory_iterator dir_itr(path); - dir_itr != fs::directory_iterator(); - ++dir_itr - ){ + // try to load the files in this path + if (fs::is_directory(path)) { + for (fs::directory_iterator dir_itr(path); dir_itr != fs::directory_iterator(); + ++dir_itr) { load_module_path(dir_itr->path()); } return; } - //its not a directory, try to load it - try{ + // its not a directory, try to load it + try { load_module(path.string()); - } - catch(const std::exception &err){ + } catch (const std::exception& err) { std::cerr << boost::format("Error: %s") % err.what() << std::endl; } } @@ -90,8 +88,9 @@ static void load_module_path(const fs::path &path){ /*! * Load all the modules given in the module paths. */ -UHD_STATIC_BLOCK(load_modules){ - for(const fs::path &path: uhd::get_module_paths()){ +UHD_STATIC_BLOCK(load_modules) +{ + for (const fs::path& path : uhd::get_module_paths()) { load_module_path(path); } } diff --git a/host/lib/utils/log_c.cpp b/host/lib/utils/log_c.cpp index 8ccc031a5..be08dbe01 100644 --- a/host/lib/utils/log_c.cpp +++ b/host/lib/utils/log_c.cpp @@ -9,16 +9,15 @@ #include <stdarg.h> -void UHD_API _uhd_log( - const uhd_log_severity_level_t log_level, - const char *filename, - const int lineno, - const char *component, - const char *format, - ... -) { - int size = 0; - char *c_str = NULL; +void UHD_API _uhd_log(const uhd_log_severity_level_t log_level, + const char* filename, + const int lineno, + const char* component, + const char* format, + ...) +{ + int size = 0; + char* c_str = NULL; va_list ap; /* figure out size */ @@ -32,7 +31,7 @@ void UHD_API _uhd_log( /* trailing '\0' */ size++; - c_str = (char *)malloc(size); + c_str = (char*)malloc(size); if (!c_str) { return; } @@ -45,14 +44,14 @@ void UHD_API _uhd_log( va_end(ap); try { - uhd::_log::log( - static_cast<uhd::log::severity_level>(log_level), + uhd::_log::log(static_cast<uhd::log::severity_level>(log_level), filename, unsigned(lineno), component, - boost::this_thread::get_id() - ) << c_str; - } catch (...) {} + boost::this_thread::get_id()) + << c_str; + } catch (...) { + } out_free: free(c_str); diff --git a/host/lib/utils/paths.cpp b/host/lib/utils/paths.cpp index 258722d79..326551c8c 100644 --- a/host/lib/utils/paths.cpp +++ b/host/lib/utils/paths.cpp @@ -9,29 +9,27 @@ #include <uhd/exception.hpp> #include <uhd/utils/paths.hpp> #include <uhdlib/utils/paths.hpp> - #include <boost/algorithm/string.hpp> -#include <functional> #include <boost/version.hpp> +#include <functional> #if BOOST_VERSION >= 106100 -#include <boost/dll/runtime_symbol_info.hpp> +# include <boost/dll/runtime_symbol_info.hpp> #endif #include <boost/filesystem.hpp> #include <boost/format.hpp> -#include <regex> #include <boost/tokenizer.hpp> - #include <cstdio> #include <cstdlib> #include <fstream> #include <iostream> +#include <regex> #include <streambuf> #include <string> #include <vector> #ifdef BOOST_MSVC -#define USE_GET_TEMP_PATH -#include <windows.h> //GetTempPath +# define USE_GET_TEMP_PATH +# include <windows.h> //GetTempPath #endif namespace fs = boost::filesystem; @@ -45,22 +43,22 @@ namespace fs = boost::filesystem; * \param default_val A default string value to use if the path isn't found. * \returns The string value of the environment variable. */ -static std::string get_env_var(const std::string &var_name, - const std::string &default_val = "") { - +static std::string get_env_var( + const std::string& var_name, const std::string& default_val = "") +{ std::string env_result = default_val; - char *env_var_str = NULL; + char* env_var_str = NULL; /* Some versions of MinGW don't expose `_dupenv_s` */ #if defined(UHD_PLATFORM_WIN32) && !defined(__MINGW32__) size_t len; errno_t err = _dupenv_s(&env_var_str, &len, var_name.c_str()); - if((not err) and (env_var_str != NULL)) + if ((not err) and (env_var_str != NULL)) env_result = std::string(env_var_str); free(env_var_str); #else env_var_str = std::getenv(var_name.c_str()); - if(env_var_str != NULL) + if (env_var_str != NULL) env_result = std::string(env_var_str); #endif @@ -75,25 +73,28 @@ static std::string get_env_var(const std::string &var_name, * \param var_name The environment variable name to read. * \returns The vector of paths from the environment variable. */ -static std::vector<std::string> get_env_paths(const std::string &var_name){ +static std::vector<std::string> get_env_paths(const std::string& var_name) +{ #ifdef UHD_PLATFORM_WIN32 static const std::string env_path_sep = ";"; #else static const std::string env_path_sep = ":"; #endif /*UHD_PLATFORM_WIN32*/ -#define path_tokenizer(inp) \ - boost::tokenizer<boost::char_separator<char> > \ - (inp, boost::char_separator<char>(env_path_sep.c_str())) +#define path_tokenizer(inp) \ + boost::tokenizer<boost::char_separator<char>>( \ + inp, boost::char_separator<char>(env_path_sep.c_str())) std::string var_value = get_env_var(var_name); std::vector<std::string> paths; - //convert to full filesystem path, filter blank paths - if (var_value.empty()) return paths; - for(const std::string &path_string: path_tokenizer(var_value)){ - if (path_string.empty()) continue; + // convert to full filesystem path, filter blank paths + if (var_value.empty()) + return paths; + for (const std::string& path_string : path_tokenizer(var_value)) { + if (path_string.empty()) + continue; paths.push_back(fs::system_complete(path_string).string()); } @@ -111,10 +112,11 @@ static std::vector<std::string> get_env_paths(const std::string &var_name){ * \param path The path starting with the tilde character * \returns The same path with the tilde expanded to contents of $HOME. */ -static std::string expand_home_directory(std::string path) { +static std::string expand_home_directory(std::string path) +{ boost::trim(path); - if(path.empty() || (path[0] != '~')) { + if (path.empty() || (path[0] != '~')) { return path; } @@ -130,80 +132,95 @@ static std::string expand_home_directory(std::string path) { **********************************************************************/ -std::string uhd::get_tmp_path(void){ - const char *tmp_path = NULL; +std::string uhd::get_tmp_path(void) +{ + const char* tmp_path = NULL; - //try the official uhd temp path environment variable + // try the official uhd temp path environment variable tmp_path = std::getenv("UHD_TEMP_PATH"); - if (tmp_path != NULL) return tmp_path; + if (tmp_path != NULL) + return tmp_path; - //try the windows function if available - #ifdef USE_GET_TEMP_PATH +// try the windows function if available +#ifdef USE_GET_TEMP_PATH char lpBuffer[2048]; - if (GetTempPath(sizeof(lpBuffer), lpBuffer)) return lpBuffer; - #endif + if (GetTempPath(sizeof(lpBuffer), lpBuffer)) + return lpBuffer; +#endif - //try windows environment variables + // try windows environment variables tmp_path = std::getenv("TMP"); - if (tmp_path != NULL) return tmp_path; + if (tmp_path != NULL) + return tmp_path; tmp_path = std::getenv("TEMP"); - if (tmp_path != NULL) return tmp_path; + if (tmp_path != NULL) + return tmp_path; - //try the stdio define if available - #ifdef P_tmpdir +// try the stdio define if available +#ifdef P_tmpdir return P_tmpdir; - #else +#else - //try unix environment variables + // try unix environment variables tmp_path = std::getenv("TMPDIR"); - if (tmp_path != NULL) return tmp_path; + if (tmp_path != NULL) + return tmp_path; - //give up and use the unix default + // give up and use the unix default return "/tmp"; - #endif +#endif } -std::string uhd::get_app_path(void){ +std::string uhd::get_app_path(void) +{ const std::string uhdcalib_path = get_env_var("UHD_CONFIG_DIR"); - if (not uhdcalib_path.empty()) return uhdcalib_path; + if (not uhdcalib_path.empty()) + return uhdcalib_path; const std::string appdata_path = get_env_var("APPDATA"); - if (not appdata_path.empty()) return appdata_path; + if (not appdata_path.empty()) + return appdata_path; const std::string home_path = get_env_var("HOME"); - if (not home_path.empty()) return home_path; + if (not home_path.empty()) + return home_path; return uhd::get_tmp_path(); } #if BOOST_VERSION >= 106100 -std::string uhd::get_pkg_path(void) { +std::string uhd::get_pkg_path(void) +{ fs::path pkg_path = fs::path(uhd::get_lib_path()).parent_path().lexically_normal(); return get_env_var("UHD_PKG_PATH", pkg_path.string()); } -std::string uhd::get_lib_path(void) { +std::string uhd::get_lib_path(void) +{ fs::path runtime_libfile_path = boost::dll::this_line_location(); return runtime_libfile_path.remove_filename().string(); } #else -std::string uhd::get_pkg_path(void) { +std::string uhd::get_pkg_path(void) +{ return get_env_var("UHD_PKG_PATH", UHD_PKG_PATH); } -std::string uhd::get_lib_path(void) { +std::string uhd::get_lib_path(void) +{ fs::path lib_path = fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR; return lib_path.string(); } #endif -std::vector<fs::path> uhd::get_module_paths(void){ +std::vector<fs::path> uhd::get_module_paths(void) +{ std::vector<fs::path> paths; std::vector<std::string> env_paths = get_env_paths("UHD_MODULE_PATH"); - for(std::string &str_path: env_paths) { + for (std::string& str_path : env_paths) { paths.push_back(str_path); } @@ -214,52 +231,76 @@ std::vector<fs::path> uhd::get_module_paths(void){ } #ifdef UHD_PLATFORM_WIN32 -#include <windows.h> +# include <windows.h> /*! * On Windows, query the system registry for the UHD images install path. * If the key isn't found in the registry, an empty string is returned. * \param registry_key_path The registry key to look for. * \return The images path, formatted for windows. */ -std::string _get_images_path_from_registry(const std::string& registry_key_path) { +std::string _get_images_path_from_registry(const std::string& registry_key_path) +{ std::smatch reg_key_match; - //If a substring in the search path is enclosed in [] (square brackets) then it is interpreted as a registry path - if (not std::regex_search(registry_key_path, reg_key_match, std::regex("\\[(.+)\\](.*)", std::regex::icase))) + // If a substring in the search path is enclosed in [] (square brackets) then it is + // interpreted as a registry path + if (not std::regex_search(registry_key_path, + reg_key_match, + std::regex("\\[(.+)\\](.*)", std::regex::icase))) return std::string(); - std::string reg_key_path = std::string(reg_key_match[1].first, reg_key_match[1].second); - std::string path_suffix = std::string(reg_key_match[2].first, reg_key_match[2].second); + std::string reg_key_path = + std::string(reg_key_match[1].first, reg_key_match[1].second); + std::string path_suffix = + std::string(reg_key_match[2].first, reg_key_match[2].second); - //Split the registry path into parent, key-path and value. + // Split the registry path into parent, key-path and value. std::smatch reg_parent_match; - if (not std::regex_search(reg_key_path, reg_parent_match, std::regex("^(.+?)\\\\(.+)\\\\(.+)$", std::regex::icase))) + if (not std::regex_search(reg_key_path, + reg_parent_match, + std::regex("^(.+?)\\\\(.+)\\\\(.+)$", std::regex::icase))) return std::string(); - std::string reg_parent = std::string(reg_parent_match[1].first, reg_parent_match[1].second); - std::string reg_path = std::string(reg_parent_match[2].first, reg_parent_match[2].second); - std::string reg_val_name = std::string(reg_parent_match[3].first, reg_parent_match[3].second); + std::string reg_parent = + std::string(reg_parent_match[1].first, reg_parent_match[1].second); + std::string reg_path = + std::string(reg_parent_match[2].first, reg_parent_match[2].second); + std::string reg_val_name = + std::string(reg_parent_match[3].first, reg_parent_match[3].second); HKEY hkey_parent = HKEY_LOCAL_MACHINE; - if (reg_parent == "HKEY_LOCAL_MACHINE") hkey_parent = HKEY_LOCAL_MACHINE; - else if (reg_parent == "HKEY_CURRENT_USER") hkey_parent = HKEY_CURRENT_USER; - else if (reg_parent == "HKEY_CLASSES_ROOT") hkey_parent = HKEY_CLASSES_ROOT; - else if (reg_parent == "HKEY_CURRENT_CONFIG") hkey_parent = HKEY_CURRENT_CONFIG; - else if (reg_parent == "HKEY_USERS") hkey_parent = HKEY_CURRENT_USER; + if (reg_parent == "HKEY_LOCAL_MACHINE") + hkey_parent = HKEY_LOCAL_MACHINE; + else if (reg_parent == "HKEY_CURRENT_USER") + hkey_parent = HKEY_CURRENT_USER; + else if (reg_parent == "HKEY_CLASSES_ROOT") + hkey_parent = HKEY_CLASSES_ROOT; + else if (reg_parent == "HKEY_CURRENT_CONFIG") + hkey_parent = HKEY_CURRENT_CONFIG; + else if (reg_parent == "HKEY_USERS") + hkey_parent = HKEY_CURRENT_USER; TCHAR value_buff[1024]; - DWORD value_buff_size = 1024*sizeof(TCHAR); + DWORD value_buff_size = 1024 * sizeof(TCHAR); - //Get a handle to the key location + // Get a handle to the key location HKEY hkey_location; - if (RegOpenKeyExA(hkey_parent, reg_path.c_str(), 0, KEY_QUERY_VALUE, &hkey_location) != ERROR_SUCCESS) + if (RegOpenKeyExA(hkey_parent, reg_path.c_str(), 0, KEY_QUERY_VALUE, &hkey_location) + != ERROR_SUCCESS) return std::string(); - //Query key value + // Query key value DWORD dw_type = REG_SZ; - if(RegQueryValueExA(hkey_location, reg_val_name.c_str(), NULL, &dw_type, (LPBYTE)value_buff, &value_buff_size) == ERROR_SUCCESS) { + if (RegQueryValueExA(hkey_location, + reg_val_name.c_str(), + NULL, + &dw_type, + (LPBYTE)value_buff, + &value_buff_size) + == ERROR_SUCCESS) { RegCloseKey(hkey_location); - if (value_buff_size >= 1024*sizeof(TCHAR)) { + if (value_buff_size >= 1024 * sizeof(TCHAR)) { return std::string(); } else { - std::string return_value(value_buff, value_buff_size-1); //value_buff_size includes the null terminator + std::string return_value(value_buff, + value_buff_size - 1); // value_buff_size includes the null terminator return_value += path_suffix; return return_value; } @@ -267,10 +308,10 @@ std::string _get_images_path_from_registry(const std::string& registry_key_path) return std::string(); } } -#endif /*UHD_PLATFORM_WIN32*/ - -std::string uhd::get_images_dir(const std::string &search_paths) { +#endif /*UHD_PLATFORM_WIN32*/ +std::string uhd::get_images_dir(const std::string& search_paths) +{ /* This function will check for the existence of directories in this * order: * @@ -285,9 +326,9 @@ std::string uhd::get_images_dir(const std::string &search_paths) { /* We will start by looking for a path indicated by the `UHD_IMAGES_DIR` * environment variable. */ std::vector<std::string> env_paths = get_env_paths("UHD_IMAGES_DIR"); - for(auto possible_dir: env_paths) { + for (auto possible_dir : env_paths) { if (fs::is_directory(fs::path(possible_dir))) { - return possible_dir; + return possible_dir; } } @@ -306,18 +347,18 @@ std::string uhd::get_images_dir(const std::string &search_paths) { std::vector<std::string> search_paths_vector; boost::split(search_paths_vector, _search_paths, boost::is_any_of(",;")); - for(std::string& search_path: search_paths_vector) { - + for (std::string& search_path : search_paths_vector) { boost::algorithm::trim(search_path); - if (search_path.empty()) continue; + if (search_path.empty()) + continue; #ifdef UHD_PLATFORM_WIN32 possible_dir = _get_images_path_from_registry(search_path); if (possible_dir.empty()) { - //Could not read from the registry due to missing key, invalid - //values, etc Just use the search path. The is_directory check - //will fail if this is a registry path and we will move on to - //the next item in the list. + // Could not read from the registry due to missing key, invalid + // values, etc Just use the search path. The is_directory check + // will fail if this is a registry path and we will move on to + // the next item in the list. possible_dir = search_path; } #else @@ -340,10 +381,12 @@ std::string uhd::get_images_dir(const std::string &search_paths) { } } -std::string uhd::find_image_path(const std::string &image_name, const std::string &search_paths){ +std::string uhd::find_image_path( + const std::string& image_name, const std::string& search_paths) +{ /* If a path was provided on the command-line or as a hint from the caller, * we default to that. */ - if (fs::exists(image_name)){ + if (fs::exists(image_name)) { return fs::system_complete(image_name).string(); } @@ -354,33 +397,33 @@ std::string uhd::find_image_path(const std::string &image_name, const std::strin if (fs::exists(image_path)) { return image_path.string(); } else { - throw uhd::io_error( - "Could not find the image '" + image_name + "' in the image directory " + images_dir - + "\nFor more information regarding image paths, please refer to the UHD manual."); + throw uhd::io_error("Could not find the image '" + image_name + + "' in the image directory " + images_dir + + "\nFor more information regarding image paths, please " + "refer to the UHD manual."); } } /* If we made it this far, then we didn't find anything. */ images_dir = "<no images directory located>"; - throw uhd::io_error("Could not find path for image: " + image_name - + "\n\n" - + "Using images directory: " + images_dir - + "\n\n" - + "Set the environment variable 'UHD_IMAGES_DIR' appropriately or" - + " follow the below instructions to download the images package." - + "\n\n" - + uhd::print_utility_error("uhd_images_downloader.py")); + throw uhd::io_error("Could not find path for image: " + image_name + "\n\n" + + "Using images directory: " + images_dir + "\n\n" + + "Set the environment variable 'UHD_IMAGES_DIR' appropriately or" + + " follow the below instructions to download the images package." + + "\n\n" + uhd::print_utility_error("uhd_images_downloader.py")); } -std::string uhd::find_utility(const std::string &name) { - return fs::path(fs::path(uhd::get_lib_path()) / "uhd" / "utils" / name) - .string(); +std::string uhd::find_utility(const std::string& name) +{ + return fs::path(fs::path(uhd::get_lib_path()) / "uhd" / "utils" / name).string(); } -std::string uhd::print_utility_error(const std::string &name, const std::string &args){ - #ifdef UHD_PLATFORM_WIN32 - return "As an Administrator, please run:\n\n\"" + find_utility(name) + args + "\""; - #else - return "Please run:\n\n \"" + find_utility(name) + (args.empty() ? "" : (" " + args)) + "\""; - #endif +std::string uhd::print_utility_error(const std::string& name, const std::string& args) +{ +#ifdef UHD_PLATFORM_WIN32 + return "As an Administrator, please run:\n\n\"" + find_utility(name) + args + "\""; +#else + return "Please run:\n\n \"" + find_utility(name) + (args.empty() ? "" : (" " + args)) + + "\""; +#endif } diff --git a/host/lib/utils/pathslib.cpp b/host/lib/utils/pathslib.cpp index cbb0d0917..547c860b1 100644 --- a/host/lib/utils/pathslib.cpp +++ b/host/lib/utils/pathslib.cpp @@ -8,9 +8,9 @@ #include <uhdlib/utils/paths.hpp> #ifdef BOOST_MSVC -# include <windows.h> +# include <windows.h> #else -# include <wordexp.h> +# include <wordexp.h> #endif std::string uhd::path_expandvars(const std::string& path) @@ -21,15 +21,12 @@ std::string uhd::path_expandvars(const std::string& path) #ifdef BOOST_MSVC constexpr size_t max_pathlen = 4096; char result[max_pathlen]; - const size_t result_len = ExpandEnvironmentStrings( - path.c_str(), - &result[0], - max_pathlen - ); + const size_t result_len = + ExpandEnvironmentStrings(path.c_str(), &result[0], max_pathlen); if (result == 0) { return path; } - return std::string(result, result+result_len); + return std::string(result, result + result_len); #else wordexp_t p; std::string return_value; @@ -42,4 +39,3 @@ std::string uhd::path_expandvars(const std::string& path) return return_value; #endif } - diff --git a/host/lib/utils/platform.cpp b/host/lib/utils/platform.cpp index 859f3aa20..e12f7ad17 100644 --- a/host/lib/utils/platform.cpp +++ b/host/lib/utils/platform.cpp @@ -5,44 +5,52 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/platform.hpp> #include <uhd/config.hpp> +#include <uhd/utils/platform.hpp> #include <boost/functional/hash.hpp> #ifdef UHD_PLATFORM_WIN32 -#include <windows.h> +# include <windows.h> #else -#include <unistd.h> +# include <unistd.h> #endif namespace uhd { - int32_t get_process_id() { +int32_t get_process_id() +{ #ifdef UHD_PLATFORM_WIN32 return int32_t(GetCurrentProcessId()); #else return int32_t(getpid()); #endif - } +} - uint32_t get_host_id() { +uint32_t get_host_id() +{ #ifdef UHD_PLATFORM_WIN32 - //extract volume serial number - char szVolName[MAX_PATH+1], szFileSysName[MAX_PATH+1]; - DWORD dwSerialNumber, dwMaxComponentLen, dwFileSysFlags; - GetVolumeInformation("C:\\", szVolName, MAX_PATH, - &dwSerialNumber, &dwMaxComponentLen, - &dwFileSysFlags, szFileSysName, sizeof(szFileSysName)); + // extract volume serial number + char szVolName[MAX_PATH + 1], szFileSysName[MAX_PATH + 1]; + DWORD dwSerialNumber, dwMaxComponentLen, dwFileSysFlags; + GetVolumeInformation("C:\\", + szVolName, + MAX_PATH, + &dwSerialNumber, + &dwMaxComponentLen, + &dwFileSysFlags, + szFileSysName, + sizeof(szFileSysName)); - return uint32_t(dwSerialNumber); + return uint32_t(dwSerialNumber); #else - return uint32_t(gethostid()); + return uint32_t(gethostid()); #endif - } +} - uint32_t get_process_hash() { - size_t hash = 0; - boost::hash_combine(hash, uhd::get_process_id()); - boost::hash_combine(hash, uhd::get_host_id()); - return uint32_t(hash); - } +uint32_t get_process_hash() +{ + size_t hash = 0; + boost::hash_combine(hash, uhd::get_process_id()); + boost::hash_combine(hash, uhd::get_host_id()); + return uint32_t(hash); } +} // namespace uhd diff --git a/host/lib/utils/prefs.cpp b/host/lib/utils/prefs.cpp index 63479c911..72a9c9eea 100644 --- a/host/lib/utils/prefs.cpp +++ b/host/lib/utils/prefs.cpp @@ -4,74 +4,69 @@ // SPDX-License-Identifier: GPL-3.0+ // -#include <config.h> #include <uhd/utils/log.hpp> #include <uhd/utils/paths.hpp> -#include <uhdlib/utils/prefs.hpp> #include <uhdlib/utils/paths.hpp> +#include <uhdlib/utils/prefs.hpp> +#include <config.h> #include <boost/filesystem.hpp> #include <cstdlib> using namespace uhd; namespace { - constexpr char UHD_CONF_FILE_VAR[] = "UHD_CONFIG_FILE"; +constexpr char UHD_CONF_FILE_VAR[] = "UHD_CONFIG_FILE"; - inline void _update_conf_file( - const std::string& path, - const std::string& config_type, - config_parser& conf_file - ) { - if (not path.empty()) { - UHD_LOG_TRACE("PREFS", "Trying to load " << path); - if (boost::filesystem::exists(path)) { - try { - conf_file.read_file(path); - UHD_LOG_DEBUG("PREFS", - "Loaded " << config_type << " config file " << path); - } catch (...) { - UHD_LOG_DEBUG("PREFS", - "Failed to load " << config_type << " config file " << path); - } - } else { - UHD_LOG_TRACE("PREFS", - "No " << config_type << " config file found at " << path); +inline void _update_conf_file( + const std::string& path, const std::string& config_type, config_parser& conf_file) +{ + if (not path.empty()) { + UHD_LOG_TRACE("PREFS", "Trying to load " << path); + if (boost::filesystem::exists(path)) { + try { + conf_file.read_file(path); + UHD_LOG_DEBUG( + "PREFS", "Loaded " << config_type << " config file " << path); + } catch (...) { + UHD_LOG_DEBUG( + "PREFS", "Failed to load " << config_type << " config file " << path); } + } else { + UHD_LOG_TRACE( + "PREFS", "No " << config_type << " config file found at " << path); } } +} - void update_from_key( - const std::string& key, const std::string &value, - uhd::device_addr_t& user_args - ) { - if (value.empty()) { - return; - } - - const std::string key_str = key + "=" + value; - for (const auto& key : uhd::prefs::get_uhd_config().options(key_str)) { - user_args[key] = - uhd::prefs::get_uhd_config().get<std::string>(key_str, key); - } +void update_from_key( + const std::string& key, const std::string& value, uhd::device_addr_t& user_args) +{ + if (value.empty()) { + return; } - device_addr_t get_args( - const uhd::device_addr_t& user_args, - const std::vector<std::string>& keys_to_update_from - ) { - device_addr_t args; - for (const auto& key : keys_to_update_from) { - update_from_key(key, user_args.get(key, ""), args); - } + const std::string key_str = key + "=" + value; + for (const auto& key : uhd::prefs::get_uhd_config().options(key_str)) { + user_args[key] = uhd::prefs::get_uhd_config().get<std::string>(key_str, key); + } +} - // Finally, copy over the original user args: - for (const auto& user_key : user_args.keys()) { - args[user_key] = user_args[user_key]; - } +device_addr_t get_args(const uhd::device_addr_t& user_args, + const std::vector<std::string>& keys_to_update_from) +{ + device_addr_t args; + for (const auto& key : keys_to_update_from) { + update_from_key(key, user_args.get(key, ""), args); + } - return args; + // Finally, copy over the original user args: + for (const auto& user_key : user_args.keys()) { + args[user_key] = user_args[user_key]; } + + return args; } +} // namespace config_parser& uhd::prefs::get_uhd_config() { @@ -82,8 +77,8 @@ config_parser& uhd::prefs::get_uhd_config() const std::string sys_conf_file = path_expandvars(UHD_SYS_CONF_FILE); _update_conf_file(sys_conf_file, "system", _conf_files); const std::string user_conf_file = - (boost::filesystem::path(get_app_path()) - / std::string(UHD_USER_CONF_FILE)).string(); + (boost::filesystem::path(get_app_path()) / std::string(UHD_USER_CONF_FILE)) + .string(); _update_conf_file(user_conf_file, "user", _conf_files); std::string env_conf_file; try { // getenv into std::string can fail @@ -91,7 +86,7 @@ config_parser& uhd::prefs::get_uhd_config() env_conf_file = std::string(std::getenv(UHD_CONF_FILE_VAR)); } _update_conf_file(env_conf_file, "ENV", _conf_files); - } catch (const std::exception &) { + } catch (const std::exception&) { // nop } init_done = true; @@ -102,31 +97,20 @@ config_parser& uhd::prefs::get_uhd_config() } -device_addr_t uhd::prefs::get_usrp_args( - const uhd::device_addr_t &user_args -) { - const std::vector<std::string> keys_to_update_from = { - "type", - "product", - "serial" - }; +device_addr_t uhd::prefs::get_usrp_args(const uhd::device_addr_t& user_args) +{ + const std::vector<std::string> keys_to_update_from = {"type", "product", "serial"}; return get_args(user_args, keys_to_update_from); } -device_addr_t uhd::prefs::get_dpdk_args( - const uhd::device_addr_t &user_args -) { - const std::vector<std::string> keys_to_update_from = { - "use_dpdk" - }; +device_addr_t uhd::prefs::get_dpdk_args(const uhd::device_addr_t& user_args) +{ + const std::vector<std::string> keys_to_update_from = {"use_dpdk"}; return get_args(user_args, keys_to_update_from); } -device_addr_t uhd::prefs::get_dpdk_nic_args( - const uhd::device_addr_t &user_args -) { - const std::vector<std::string> keys_to_update_from = { - "dpdk_mac" - }; +device_addr_t uhd::prefs::get_dpdk_nic_args(const uhd::device_addr_t& user_args) +{ + const std::vector<std::string> keys_to_update_from = {"dpdk_mac"}; return get_args(user_args, keys_to_update_from); } diff --git a/host/lib/utils/static.cpp b/host/lib/utils/static.cpp index 84ca992c8..22cd3a1b6 100644 --- a/host/lib/utils/static.cpp +++ b/host/lib/utils/static.cpp @@ -6,17 +6,16 @@ // #include <uhd/utils/static.hpp> -#include <stdexcept> #include <iostream> -_uhd_static_fixture::_uhd_static_fixture(void (*fcn)(void), const char *name){ - try{ +#include <stdexcept> +_uhd_static_fixture::_uhd_static_fixture(void (*fcn)(void), const char* name) +{ + try { fcn(); - } - catch(const std::exception &e){ + } catch (const std::exception& e) { std::cerr << "Exception in static block " << name << std::endl; std::cerr << " " << e.what() << std::endl; - } - catch(...){ + } catch (...) { std::cerr << "Exception in static block " << name << std::endl; } } diff --git a/host/lib/utils/system_time.cpp b/host/lib/utils/system_time.cpp index 71fcd3fff..6693a38d4 100644 --- a/host/lib/utils/system_time.cpp +++ b/host/lib/utils/system_time.cpp @@ -9,8 +9,9 @@ uhd::time_spec_t uhd::get_system_time(void) { - const auto now = std::chrono::steady_clock::now().time_since_epoch(); + const auto now = std::chrono::steady_clock::now().time_since_epoch(); const auto seconds = std::chrono::duration_cast<std::chrono::seconds>(now); - const auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(now-seconds); + const auto nanoseconds = + std::chrono::duration_cast<std::chrono::nanoseconds>(now - seconds); return uhd::time_spec_t(seconds.count(), nanoseconds.count(), 1e9); } diff --git a/host/lib/utils/tasks.cpp b/host/lib/utils/tasks.cpp index a2d7f82d3..ce6e1716c 100644 --- a/host/lib/utils/tasks.cpp +++ b/host/lib/utils/tasks.cpp @@ -21,19 +21,19 @@ using namespace uhd; -class task_impl : public task{ +class task_impl : public task +{ public: - - task_impl(const task_fcn_type &task_fcn, const std::string &name): - _exit(false) + task_impl(const task_fcn_type& task_fcn, const std::string& name) : _exit(false) { - _task = std::thread([this, task_fcn](){ this->task_loop(task_fcn); }); + _task = std::thread([this, task_fcn]() { this->task_loop(task_fcn); }); if (not name.empty()) { set_thread_name(&_task, name); } } - ~task_impl(void){ + ~task_impl(void) + { _exit = true; if (_task.joinable()) { _task.join(); @@ -41,37 +41,37 @@ public: } private: - void task_loop(const task_fcn_type &task_fcn){ - try{ - while (!_exit){ + void task_loop(const task_fcn_type& task_fcn) + { + try { + while (!_exit) { task_fcn(); } - } - catch(const std::exception &e){ + } catch (const std::exception& e) { do_error_msg(e.what()); - } - catch(...){ + } catch (...) { UHD_THROW_INVALID_CODE_PATH(); } } - void do_error_msg(const std::string &msg){ + void do_error_msg(const std::string& msg) + { UHD_LOGGER_ERROR("UHD") << "An unexpected exception was caught in a task loop." - << "The task loop will now exit, things may not work." - << msg - ; + << "The task loop will now exit, things may not work." << msg; } std::atomic<bool> _exit; std::thread _task; }; -task::sptr task::make(const task_fcn_type &task_fcn, const std::string &name){ +task::sptr task::make(const task_fcn_type& task_fcn, const std::string& name) +{ return task::sptr(new task_impl(task_fcn, name)); } -msg_task::~msg_task(void){ +msg_task::~msg_task(void) +{ /* NOP */ } @@ -81,17 +81,18 @@ msg_task::~msg_task(void){ * ctrl_cores can check this queue for stranded messages. */ -class msg_task_impl : public msg_task{ +class msg_task_impl : public msg_task +{ public: - - msg_task_impl(const task_fcn_type &task_fcn): - _spawn_barrier(2) + msg_task_impl(const task_fcn_type& task_fcn) : _spawn_barrier(2) { - (void)_thread_group.create_thread(std::bind(&msg_task_impl::task_loop, this, task_fcn)); + (void)_thread_group.create_thread( + std::bind(&msg_task_impl::task_loop, this, task_fcn)); _spawn_barrier.wait(); } - ~msg_task_impl(void){ + ~msg_task_impl(void) + { _running = false; _thread_group.interrupt_all(); _thread_group.join_all(); @@ -99,8 +100,8 @@ public: /* * Returns the first message for the given SID. - * This way a radio_ctrl_core doesn't have to die in timeout but can check for stranded messages here. - * This might happen during shutdown when dtors are called. + * This way a radio_ctrl_core doesn't have to die in timeout but can check for + * stranded messages here. This might happen during shutdown when dtors are called. * See also: comments in b200_io_impl->handle_async_task */ msg_payload_t get_msg_from_dump_queue(uint32_t sid) @@ -118,43 +119,40 @@ public: } private: - - void task_loop(const task_fcn_type &task_fcn){ + void task_loop(const task_fcn_type& task_fcn) + { _running = true; _spawn_barrier.wait(); - try{ - while (_running){ - boost::optional<msg_type_t> buff = task_fcn(); - if(buff != boost::none){ - /* - * If a message gets stranded it is returned by task_fcn and then pushed to the dump_queue. - * This way ctrl_cores can check dump_queue for missing messages. - */ - boost::mutex::scoped_lock lock(_mutex); - _dump_queue.push_back(buff.get() ); - } + try { + while (_running) { + boost::optional<msg_type_t> buff = task_fcn(); + if (buff != boost::none) { + /* + * If a message gets stranded it is returned by task_fcn and then + * pushed to the dump_queue. This way ctrl_cores can check dump_queue + * for missing messages. + */ + boost::mutex::scoped_lock lock(_mutex); + _dump_queue.push_back(buff.get()); + } } - } - catch(const boost::thread_interrupted &){ - //this is an ok way to exit the task loop - } - catch(const std::exception &e){ + } catch (const boost::thread_interrupted&) { + // this is an ok way to exit the task loop + } catch (const std::exception& e) { do_error_msg(e.what()); - } - catch(...){ - //FIXME - //Unfortunately, this is also an ok way to end a task, - //because on some systems boost throws uncatchables. + } catch (...) { + // FIXME + // Unfortunately, this is also an ok way to end a task, + // because on some systems boost throws uncatchables. } } - void do_error_msg(const std::string &msg){ + void do_error_msg(const std::string& msg) + { UHD_LOGGER_ERROR("UHD") - << "An unexpected exception was caught in a task loop." - << "The task loop will now exit, things may not work." - << msg - ; + << "An unexpected exception was caught in a task loop." + << "The task loop will now exit, things may not work." << msg; } boost::mutex _mutex; @@ -163,11 +161,13 @@ private: bool _running; /* - * This queue holds stranded messages until a radio_ctrl_core grabs them via 'get_msg_from_dump_queue'. + * This queue holds stranded messages until a radio_ctrl_core grabs them via + * 'get_msg_from_dump_queue'. */ - std::vector <msg_type_t> _dump_queue; + std::vector<msg_type_t> _dump_queue; }; -msg_task::sptr msg_task::make(const task_fcn_type &task_fcn){ +msg_task::sptr msg_task::make(const task_fcn_type& task_fcn) +{ return msg_task::sptr(new msg_task_impl(task_fcn)); } diff --git a/host/lib/utils/thread_priority_c.cpp b/host/lib/utils/thread_priority_c.cpp index 6f0c76fe9..3e9f1dbf4 100644 --- a/host/lib/utils/thread_priority_c.cpp +++ b/host/lib/utils/thread_priority_c.cpp @@ -6,18 +6,14 @@ // #include <uhd/error.h> -#include <uhd/utils/thread_priority.h> -#include <uhd/utils/thread.hpp> -#include <uhd/utils/log.hpp> #include <uhd/exception.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/thread.hpp> +#include <uhd/utils/thread_priority.h> #include <boost/format.hpp> #include <iostream> -uhd_error uhd_set_thread_priority( - float priority, - bool realtime -){ - UHD_SAFE_C( - uhd::set_thread_priority(priority, realtime); - ) +uhd_error uhd_set_thread_priority(float priority, bool realtime) +{ + UHD_SAFE_C(uhd::set_thread_priority(priority, realtime);) } diff --git a/host/lib/version.cpp b/host/lib/version.cpp index 016c46a9f..80121b271 100644 --- a/host/lib/version.cpp +++ b/host/lib/version.cpp @@ -5,20 +5,23 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/version.hpp> -#include <uhd/utils/static.hpp> #include <uhd/utils/log.hpp> +#include <uhd/utils/static.hpp> +#include <uhd/version.hpp> #include <boost/version.hpp> #include <iostream> -std::string uhd::get_version_string(void){ +std::string uhd::get_version_string(void) +{ return "@UHD_VERSION@"; } -std::string uhd::get_abi_string(void){ +std::string uhd::get_abi_string(void) +{ return UHD_VERSION_ABI_STRING; } -std::string uhd::get_component(void){ +std::string uhd::get_component(void) +{ return "@UHD_COMPONENT@"; }
\ No newline at end of file diff --git a/host/lib/version_c.cpp b/host/lib/version_c.cpp index 2897a6407..95dd93141 100644 --- a/host/lib/version_c.cpp +++ b/host/lib/version_c.cpp @@ -6,29 +6,20 @@ #include <uhd/version.h> #include <uhd/version.hpp> - #include <string.h> -uhd_error uhd_get_abi_string( - char* abi_string_out, - size_t buffer_len -){ - UHD_SAFE_C( - const std::string cpp_abi_string = uhd::get_abi_string(); +uhd_error uhd_get_abi_string(char* abi_string_out, size_t buffer_len) +{ + UHD_SAFE_C(const std::string cpp_abi_string = uhd::get_abi_string(); - memset(abi_string_out, 0, buffer_len); - strncpy(abi_string_out, cpp_abi_string.c_str(), buffer_len); - ) + memset(abi_string_out, 0, buffer_len); + strncpy(abi_string_out, cpp_abi_string.c_str(), buffer_len);) } -uhd_error uhd_get_version_string( - char* version_out, - size_t buffer_len -){ - UHD_SAFE_C( - const std::string cpp_version = uhd::get_version_string(); +uhd_error uhd_get_version_string(char* version_out, size_t buffer_len) +{ + UHD_SAFE_C(const std::string cpp_version = uhd::get_version_string(); - memset(version_out, 0, buffer_len); - strncpy(version_out, cpp_version.c_str(), buffer_len); - ) + memset(version_out, 0, buffer_len); + strncpy(version_out, cpp_version.c_str(), buffer_len);) } |