diff options
Diffstat (limited to 'host/lib')
| -rw-r--r-- | host/lib/include/uhdlib/utils/compat_check.hpp | 30 | ||||
| -rw-r--r-- | host/lib/rfnoc/ddc_block_ctrl_impl.cpp | 88 | ||||
| -rw-r--r-- | host/lib/rfnoc/duc_block_ctrl_impl.cpp | 90 | ||||
| -rw-r--r-- | host/lib/utils/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/lib/utils/compat_check.cpp | 114 | 
5 files changed, 234 insertions, 89 deletions
diff --git a/host/lib/include/uhdlib/utils/compat_check.hpp b/host/lib/include/uhdlib/utils/compat_check.hpp new file mode 100644 index 000000000..acdf97340 --- /dev/null +++ b/host/lib/include/uhdlib/utils/compat_check.hpp @@ -0,0 +1,30 @@ +// +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0 +// + +#ifndef INCLUDED_UHDLIB_UTILS_COMPATCHECK_HPP +#define INCLUDED_UHDLIB_UTILS_COMPATCHECK_HPP + +#include <cstddef> +#include <string> + +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 +    ); + +} /* namespace uhd */ + +#endif /* INCLUDED_UHDLIB_UTILS_COMPATCHECK_HPP */ diff --git a/host/lib/rfnoc/ddc_block_ctrl_impl.cpp b/host/lib/rfnoc/ddc_block_ctrl_impl.cpp index 62a5ce896..9c7764045 100644 --- a/host/lib/rfnoc/ddc_block_ctrl_impl.cpp +++ b/host/lib/rfnoc/ddc_block_ctrl_impl.cpp @@ -9,6 +9,8 @@  #include <uhd/utils/log.hpp>  #include <uhd/convert.hpp>  #include <uhd/types/ranges.hpp> +#include <uhdlib/utils/narrow.hpp> +#include <uhdlib/utils/compat_check.hpp>  #include <boost/math/special_functions/round.hpp>  #include <cmath> @@ -24,10 +26,23 @@ class ddc_block_ctrl_impl : public ddc_block_ctrl  public:      UHD_RFNOC_BLOCK_CONSTRUCTOR(ddc_block_ctrl) +        , _fpga_compat(user_reg_read64(RB_REG_COMPAT_NUM)) +        , _num_halfbands(uhd::narrow_cast<size_t>( +                    user_reg_read64(RB_REG_NUM_HALFBANDS))) +        , _cic_max_decim(uhd::narrow_cast<size_t>( +                    user_reg_read64(RB_REG_CIC_MAX_DECIM)))      { -        check_compat_num(); -        _num_halfbands = (size_t) user_reg_read64(RB_REG_NUM_HALFBANDS); -        _cic_max_decim = (size_t) user_reg_read64(RB_REG_CIC_MAX_DECIM); +        UHD_LOG_DEBUG(unique_id(), +            "Loading DDC with " << get_num_halfbands() << " halfbands and " +            "max CIC decimation " << get_cic_max_decim() +        ); +        uhd::assert_fpga_compat( +            MAJOR_COMP, MINOR_COMP, +            _fpga_compat, +            "DDC", "DDC", +            false /* Let it slide if minors mismatch */ +        ); +          // Argument/prop tree hooks          for (size_t chan = 0; chan < get_input_ports().size(); chan++) {              double default_freq = get_arg<double>("freq", chan); @@ -186,14 +201,15 @@ public:      }  private: +    static constexpr size_t MAJOR_COMP = 1; +    static constexpr size_t MINOR_COMP = 0; +    static constexpr size_t RB_REG_COMPAT_NUM = 0; +    static constexpr size_t RB_REG_NUM_HALFBANDS = 1; +    static constexpr size_t RB_REG_CIC_MAX_DECIM = 2; -    size_t _num_halfbands; -    size_t _cic_max_decim; -    static const size_t MAJOR_COMP = 1; -    static const size_t MINOR_COMP = 0; -    static const size_t RB_REG_COMPAT_NUM = 0; -    static const size_t RB_REG_NUM_HALFBANDS = 1; -    static const size_t RB_REG_CIC_MAX_DECIM = 2; +    const uint64_t _fpga_compat; +    const size_t _num_halfbands; +    const size_t _cic_max_decim;      //! Set the CORDIC frequency shift the signal to \p requested_freq      double set_freq(const double requested_freq, const size_t chan) @@ -224,7 +240,7 @@ private:          for (int hb = _num_halfbands; hb >= 0; hb--) {              const size_t decim_offset = _cic_max_decim<<(hb-1);              for(size_t decim = _cic_max_decim; decim > 0; decim--) { -                const size_t hb_cic_decim =  decim*(1<<hb);  +                const size_t hb_cic_decim =  decim*(1<<hb);                  if(hb == 0 || hb_cic_decim > decim_offset) {                      range.push_back(uhd::range_t(input_rate/hb_cic_decim));                  } @@ -315,39 +331,23 @@ private:          sr_write("SCALE_IQ", actual_scalar, chan);      } -   //Get cached value of _num_halfbands -   size_t get_num_halfbands() const -   { -       return _num_halfbands; -   } - -   //Get cached value of _cic_max_decim readback -   size_t get_cic_max_decim() const -   { -       return _cic_max_decim; -   } - -   //Check compatibility num, if not current, throw error. -   //MAJOR COMPATIBILITY, top 32 bits = 0x1 -   //MINOR COMPATIBILITY, lower 32 bits = 0x0 -   void check_compat_num() -   { -       uint64_t compat_num = user_reg_read64(RB_REG_COMPAT_NUM); -       uint32_t compat_num_major = compat_num>>32; -       uint32_t compat_num_minor = compat_num&0xFFFFFFFF; -       if (compat_num_major > MAJOR_COMP) { -           throw uhd::runtime_error(str(boost::format( -                   "DDC RFNoC block is too new for this software. Please upgrade to a driver that supports hardware revision %d.") -                       % compat_num_major)); -       } else if (compat_num_major < MAJOR_COMP) { -           throw uhd::runtime_error(str(boost::format( -                   "DDC software is too new for this hardware. Please downgrade to a driver that supports hardware revision %d.") -                       % compat_num_major)); -       } -       if (compat_num_minor != MINOR_COMP) { -           UHD_LOGGER_WARNING("DDC") << "DDC hardware compatability does not match software, this may have adverse affects on the block's behavior."; -       } -   } +    //! Get cached value of FPGA compat number +    uint64_t get_fpga_compat() const +    { +        return _fpga_compat; +    } + +    //! Get cached value of _num_halfbands +    size_t get_num_halfbands() const +    { +        return _num_halfbands; +    } + +    //! Get cached value of _cic_max_decim readback +    size_t get_cic_max_decim() const +    { +        return _cic_max_decim; +    }  };  UHD_RFNOC_BLOCK_REGISTER(ddc_block_ctrl, "DDC"); diff --git a/host/lib/rfnoc/duc_block_ctrl_impl.cpp b/host/lib/rfnoc/duc_block_ctrl_impl.cpp index 3a779566b..0e1521d9f 100644 --- a/host/lib/rfnoc/duc_block_ctrl_impl.cpp +++ b/host/lib/rfnoc/duc_block_ctrl_impl.cpp @@ -9,6 +9,8 @@  #include <uhd/utils/log.hpp>  #include <uhd/convert.hpp>  #include <uhd/types/ranges.hpp> +#include <uhdlib/utils/narrow.hpp> +#include <uhdlib/utils/compat_check.hpp>  #include <boost/math/special_functions/round.hpp>  #include <cmath> @@ -35,10 +37,23 @@ class duc_block_ctrl_impl : public duc_block_ctrl  public:      UHD_RFNOC_BLOCK_CONSTRUCTOR(duc_block_ctrl) +        , _fpga_compat(user_reg_read64(RB_REG_COMPAT_NUM)) +        , _num_halfbands(uhd::narrow_cast<size_t>( +                    user_reg_read64(RB_REG_NUM_HALFBANDS))) +        , _cic_max_interp(uhd::narrow_cast<size_t>( +                    user_reg_read64(RB_REG_CIC_MAX_INTERP)))      { -        check_compat_num(); -        _num_halfbands = (size_t) user_reg_read64(RB_REG_NUM_HALFBANDS); -        _cic_max_interp = (size_t) user_reg_read64(RB_REG_CIC_MAX_INTERP); +        UHD_LOG_DEBUG(unique_id(), +            "Loading DUC with " << get_num_halfbands() << " halfbands and " +            "max CIC interpolation " << get_cic_max_interp() +        ); +        uhd::assert_fpga_compat( +            MAJOR_COMP, MINOR_COMP, +            _fpga_compat, +            "DUC", "DUC", +            false /* Let it slide if minors mismatch */ +        ); +          // Argument/prop tree hooks          for (size_t chan = 0; chan < get_input_ports().size(); chan++) {              double default_freq = get_arg<double>("freq", chan); @@ -149,13 +164,15 @@ public:  private: -    size_t _num_halfbands; -    size_t _cic_max_interp; -    static const size_t MAJOR_COMP = 1; -    static const size_t MINOR_COMP = 0; -    static const size_t RB_REG_COMPAT_NUM = 0; -    static const size_t RB_REG_NUM_HALFBANDS = 1; -    static const size_t RB_REG_CIC_MAX_INTERP = 2; +    static constexpr size_t MAJOR_COMP = 1; +    static constexpr size_t MINOR_COMP = 0; +    static constexpr size_t RB_REG_COMPAT_NUM = 0; +    static constexpr size_t RB_REG_NUM_HALFBANDS = 1; +    static constexpr size_t RB_REG_CIC_MAX_INTERP = 2; + +    const uint64_t _fpga_compat; +    const size_t _num_halfbands; +    const size_t _cic_max_interp;      //! Set the CORDIC frequency shift the signal to \p requested_freq      double set_freq(const double requested_freq, const size_t chan) @@ -187,7 +204,7 @@ private:          for (int hb = _num_halfbands; hb >= 0; hb--) {              const size_t interp_offset = _cic_max_interp<<(hb-1);              for(size_t interp = _cic_max_interp; interp > 0; interp--) { -                const size_t hb_cic_interp =  interp*(1<<hb);  +                const size_t hb_cic_interp =  interp*(1<<hb);                  if(hb == 0 || hb_cic_interp > interp_offset) {                      range.push_back(uhd::range_t(output_rate/hb_cic_interp));                  } @@ -263,40 +280,23 @@ private:          sr_write("SCALE_IQ", actual_scalar, chan);      } -   //Get cached value of _num_halfbands -   size_t get_num_halfbands() const -   { -       return (size_t) _num_halfbands; -   } - -   //Get cached value of _cic_max_decim readback -   size_t get_cic_max_decim() const -   { -       return (size_t) _cic_max_interp; -   } - -   //Check compatibility num, if not current, throw error. -   //MAJOR COMPATIBILITY, top 32 bits = 0x1 -   //MINOR COMPATIBILITY, lower 32 bits = 0x0 -   void check_compat_num() -   { -       uint64_t compat_num = user_reg_read64(RB_REG_COMPAT_NUM); -       uint32_t compat_num_major = compat_num>>32; -       uint32_t compat_num_minor = compat_num&0xFFFFFFFF; -       if ( compat_num_major > MAJOR_COMP) { -          throw uhd::runtime_error(str(boost::format( -              "DUC RFNoC block is too new for this software. Please upgrade to a driver that supports hardware revision %d.") -              % compat_num_major)); -       } else if ( compat_num_major < MAJOR_COMP) { -          throw uhd::runtime_error(str(boost::format( -              "DUC software is too new for this hardware. Please downgrade to a driver that supports hardware revision %d.") -              % compat_num_major)); -       } -       if (compat_num_minor != MINOR_COMP) { -         UHD_LOGGER_WARNING("DDC") << "DDC hardware compatability does not match software, this may have adverse affects on the block's behavior."; -       } -   } +    //! Get cached value of FPGA compat number +    uint64_t get_fpga_compat() const +    { +        return _fpga_compat; +    } + +    //Get cached value of _num_halfbands +    size_t get_num_halfbands() const +    { +        return _num_halfbands; +    } + +    //Get cached value of _cic_max_decim readback +    size_t get_cic_max_interp() const +    { +        return _cic_max_interp; +    }  };  UHD_RFNOC_BLOCK_REGISTER(duc_block_ctrl, "DUC"); - diff --git a/host/lib/utils/CMakeLists.txt b/host/lib/utils/CMakeLists.txt index afaf99274..c7de9fbf8 100644 --- a/host/lib/utils/CMakeLists.txt +++ b/host/lib/utils/CMakeLists.txt @@ -160,6 +160,7 @@ SET_SOURCE_FILES_PROPERTIES(  LIBUHD_APPEND_SOURCES(      ${CMAKE_CURRENT_SOURCE_DIR}/csv.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/config_parser.cpp +    ${CMAKE_CURRENT_SOURCE_DIR}/compat_check.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/eeprom_utils.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/gain_group.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/ihex.cpp diff --git a/host/lib/utils/compat_check.cpp b/host/lib/utils/compat_check.cpp new file mode 100644 index 000000000..aebf6e6bf --- /dev/null +++ b/host/lib/utils/compat_check.cpp @@ -0,0 +1,114 @@ +// +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0 +// + +#include <uhd/exception.hpp> +#include <uhd/utils/log.hpp> +#include <uhdlib/utils/compat_check.hpp> +#include <boost/format.hpp> + +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 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 << "." +        ; +    } + +    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 << "." +            ; +        } +        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 << "." +            ; +        } +        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) { +            if (!log_component.empty()) { +                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 +                ); +            } +            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 +                ); +            } +        } +    } else if (uhd_minor < fpga_minor) { +        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 +            ); +        } +    } +    // We got here? Then all is good. +}  | 
