diff options
author | Martin Braun <martin.braun@ettus.com> | 2020-03-03 16:10:06 -0800 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2020-04-02 11:55:17 -0500 |
commit | 3fe5ccf700a0c6f27dca9511386460194dcc593c (patch) | |
tree | 19d394faac0581601d3d6e5d35a7a82e325bf245 /host/include | |
parent | 1e016e49e82c430197a90a018fbc7613cc654088 (diff) | |
download | uhd-3fe5ccf700a0c6f27dca9511386460194dcc593c.tar.gz uhd-3fe5ccf700a0c6f27dca9511386460194dcc593c.tar.bz2 uhd-3fe5ccf700a0c6f27dca9511386460194dcc593c.zip |
uhd: cal: Add iq_cal calibration data container class
This class can be used to store calibration coefficients for the X300
DC offset and IQ imbalance calibration.
Note: This also modifies Doxyfile.in to not document files generated by
flatc.
Diffstat (limited to 'host/include')
-rw-r--r-- | host/include/uhd/cal/CMakeLists.txt | 8 | ||||
-rw-r--r-- | host/include/uhd/cal/cal_metadata.fbs | 15 | ||||
-rw-r--r-- | host/include/uhd/cal/cal_metadata_generated.h | 111 | ||||
-rw-r--r-- | host/include/uhd/cal/container.hpp | 9 | ||||
-rw-r--r-- | host/include/uhd/cal/iq_cal.fbs | 32 | ||||
-rw-r--r-- | host/include/uhd/cal/iq_cal.hpp | 78 | ||||
-rw-r--r-- | host/include/uhd/cal/iq_cal_generated.h | 162 |
7 files changed, 415 insertions, 0 deletions
diff --git a/host/include/uhd/cal/CMakeLists.txt b/host/include/uhd/cal/CMakeLists.txt index b3f724d2e..2aba1a91c 100644 --- a/host/include/uhd/cal/CMakeLists.txt +++ b/host/include/uhd/cal/CMakeLists.txt @@ -8,7 +8,15 @@ UHD_INSTALL(FILES database.hpp container.hpp interpolation.hpp + iq_cal.hpp + iq_cal_generated.h DESTINATION ${INCLUDE_DIR}/uhd/cal COMPONENT headers ) +UHD_INSTALL(FILES + iq_cal.fbs + DESTINATION ${PKG_DATA_DIR}/cal + COMPONENT headers +) + diff --git a/host/include/uhd/cal/cal_metadata.fbs b/host/include/uhd/cal/cal_metadata.fbs new file mode 100644 index 000000000..ce380c141 --- /dev/null +++ b/host/include/uhd/cal/cal_metadata.fbs @@ -0,0 +1,15 @@ +// +// Copyright 2020 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +// Common metadata for all calibration containers +table Metadata +{ + name: string; // Can be given arbitrary, based on calibration + serial: string; // Device serial + timestamp: uint64; // Unix timestamp + version_major: int; // Cal data version (major) + version_minor: int; // Cal data version (minor) +} diff --git a/host/include/uhd/cal/cal_metadata_generated.h b/host/include/uhd/cal/cal_metadata_generated.h new file mode 100644 index 000000000..3b4a6a8e7 --- /dev/null +++ b/host/include/uhd/cal/cal_metadata_generated.h @@ -0,0 +1,111 @@ +// automatically generated by the FlatBuffers compiler, do not modify + + +#ifndef FLATBUFFERS_GENERATED_CALMETADATA_H_ +#define FLATBUFFERS_GENERATED_CALMETADATA_H_ + +#include "flatbuffers/flatbuffers.h" + +struct Metadata; + +struct Metadata FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NAME = 4, + VT_SERIAL = 6, + VT_TIMESTAMP = 8, + VT_VERSION_MAJOR = 10, + VT_VERSION_MINOR = 12 + }; + const flatbuffers::String *name() const { + return GetPointer<const flatbuffers::String *>(VT_NAME); + } + const flatbuffers::String *serial() const { + return GetPointer<const flatbuffers::String *>(VT_SERIAL); + } + uint64_t timestamp() const { + return GetField<uint64_t>(VT_TIMESTAMP, 0); + } + int32_t version_major() const { + return GetField<int32_t>(VT_VERSION_MAJOR, 0); + } + int32_t version_minor() const { + return GetField<int32_t>(VT_VERSION_MINOR, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyOffset(verifier, VT_SERIAL) && + verifier.VerifyString(serial()) && + VerifyField<uint64_t>(verifier, VT_TIMESTAMP) && + VerifyField<int32_t>(verifier, VT_VERSION_MAJOR) && + VerifyField<int32_t>(verifier, VT_VERSION_MINOR) && + verifier.EndTable(); + } +}; + +struct MetadataBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_name(flatbuffers::Offset<flatbuffers::String> name) { + fbb_.AddOffset(Metadata::VT_NAME, name); + } + void add_serial(flatbuffers::Offset<flatbuffers::String> serial) { + fbb_.AddOffset(Metadata::VT_SERIAL, serial); + } + void add_timestamp(uint64_t timestamp) { + fbb_.AddElement<uint64_t>(Metadata::VT_TIMESTAMP, timestamp, 0); + } + void add_version_major(int32_t version_major) { + fbb_.AddElement<int32_t>(Metadata::VT_VERSION_MAJOR, version_major, 0); + } + void add_version_minor(int32_t version_minor) { + fbb_.AddElement<int32_t>(Metadata::VT_VERSION_MINOR, version_minor, 0); + } + explicit MetadataBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + MetadataBuilder &operator=(const MetadataBuilder &); + flatbuffers::Offset<Metadata> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<Metadata>(end); + return o; + } +}; + +inline flatbuffers::Offset<Metadata> CreateMetadata( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<flatbuffers::String> name = 0, + flatbuffers::Offset<flatbuffers::String> serial = 0, + uint64_t timestamp = 0, + int32_t version_major = 0, + int32_t version_minor = 0) { + MetadataBuilder builder_(_fbb); + builder_.add_timestamp(timestamp); + builder_.add_version_minor(version_minor); + builder_.add_version_major(version_major); + builder_.add_serial(serial); + builder_.add_name(name); + return builder_.Finish(); +} + +inline flatbuffers::Offset<Metadata> CreateMetadataDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, + const char *serial = nullptr, + uint64_t timestamp = 0, + int32_t version_major = 0, + int32_t version_minor = 0) { + auto name__ = name ? _fbb.CreateString(name) : 0; + auto serial__ = serial ? _fbb.CreateString(serial) : 0; + return CreateMetadata( + _fbb, + name__, + serial__, + timestamp, + version_major, + version_minor); +} + +#endif // FLATBUFFERS_GENERATED_CALMETADATA_H_ diff --git a/host/include/uhd/cal/container.hpp b/host/include/uhd/cal/container.hpp index c3035c610..14f28d5ff 100644 --- a/host/include/uhd/cal/container.hpp +++ b/host/include/uhd/cal/container.hpp @@ -25,6 +25,15 @@ class UHD_API container public: virtual ~container() = default; + //! Return the name of this calibration table + virtual std::string get_name() const = 0; + + //! Return the device serial of this calibration table + virtual std::string get_serial() const = 0; + + //! Timestamp of acquisition time + virtual uint64_t get_timestamp() const = 0; + //! Return a serialized version of this container virtual std::vector<uint8_t> serialize() = 0; diff --git a/host/include/uhd/cal/iq_cal.fbs b/host/include/uhd/cal/iq_cal.fbs new file mode 100644 index 000000000..55c9ae3de --- /dev/null +++ b/host/include/uhd/cal/iq_cal.fbs @@ -0,0 +1,32 @@ +// +// Copyright 2020 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +// Calibration Table for I/Q Balance correction coefficients +// This is a very simple calibration coefficient table, and +// works for Gen-3 cals (IQ balance and DC offset) which have +// a single real/imag pair of coefficients per frequency. + +include "cal_metadata.fbs"; + +namespace uhd.usrp.cal; + +struct IQCalCoeff +{ + freq: double; + coeff_real: double; + coeff_imag: double; + suppression_abs: double; + suppression_delta: double; +} + +table IQCalCoeffs +{ + metadata: Metadata; + coeffs: [IQCalCoeff]; +} + +root_type IQCalCoeffs; +file_identifier "IQ/f"; // I/Q data per frequency diff --git a/host/include/uhd/cal/iq_cal.hpp b/host/include/uhd/cal/iq_cal.hpp new file mode 100644 index 000000000..ded082698 --- /dev/null +++ b/host/include/uhd/cal/iq_cal.hpp @@ -0,0 +1,78 @@ +// +// Copyright 2020 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_CAL_IQ_DATA_HPP +#define INCLUDED_LIBUHD_CAL_IQ_DATA_HPP + +#include <uhd/cal/container.hpp> +#include <uhd/cal/interpolation.hpp> +#include <uhd/config.hpp> +#include <complex> +#include <memory> +#include <string> + +namespace uhd { namespace usrp { namespace cal { + +/*! Class that stores IQ cal data per frequency + * + * The following calibrations use this: + * - Gen-2 and Gen-3 TX DC Offset + * - Gen-2 and Gen-3 RX,TX IQ Imbalance + */ +class UHD_API iq_cal : public container +{ +public: + using sptr = std::shared_ptr<iq_cal>; + + //! Choose interpolation mode + // + // This class supports two kinds of interpolation: Nearest-neighbour, and + // linear. + // + // \param interp The new interpolation mode + // \throws uhd::value_error if the given interpolation mode is not + // supported. + virtual void set_interp_mode(const interp_mode interp) = 0; + + //! Return a calibration coefficient for a given frequency + // + // This function will interpolate to return a valid coefficient for any + // given frequency. + virtual std::complex<double> get_cal_coeff(const double freq) const = 0; + + //! Update / set a calbration coefficient + // + // This usually only needs to called by calibration utilities. + // + // \param freq The frequency at which this coefficient is measured + // \param coeff The value that is stored + // \param suppression_abs The amount of impairment suppression this + // coefficient provides, in dB. + // \param suppression_delta The difference of impairment power between + // applying this coefficient and applying none, in + // dB. + virtual void set_cal_coeff(const double freq, + const std::complex<double> coeff, + const double suppression_abs = 0, + const double suppression_delta = 0) = 0; + + //! Clear the list of coefficients + // + // This can be useful in order to drop existing cal data, and load an + // entirely new set with deserialize(). + virtual void clear() = 0; + + //! Factory for new cal data sets + static sptr make( + const std::string& name, const std::string& serial, const uint64_t timestamp); + + //! Default factory + static sptr make(); +}; + +}}} // namespace uhd::usrp::cal + +#endif /* INCLUDED_LIBUHD_CAL_IQ_DATA_HPP */ diff --git a/host/include/uhd/cal/iq_cal_generated.h b/host/include/uhd/cal/iq_cal_generated.h new file mode 100644 index 000000000..f0dfa0b82 --- /dev/null +++ b/host/include/uhd/cal/iq_cal_generated.h @@ -0,0 +1,162 @@ +// automatically generated by the FlatBuffers compiler, do not modify + + +#ifndef FLATBUFFERS_GENERATED_IQCAL_UHD_USRP_CAL_H_ +#define FLATBUFFERS_GENERATED_IQCAL_UHD_USRP_CAL_H_ + +#include "flatbuffers/flatbuffers.h" + +#include "cal_metadata_generated.h" + +namespace uhd { +namespace usrp { +namespace cal { + +struct IQCalCoeff; + +struct IQCalCoeffs; + +FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) IQCalCoeff FLATBUFFERS_FINAL_CLASS { + private: + double freq_; + double coeff_real_; + double coeff_imag_; + double suppression_abs_; + double suppression_delta_; + + public: + IQCalCoeff() { + memset(static_cast<void *>(this), 0, sizeof(IQCalCoeff)); + } + IQCalCoeff(double _freq, double _coeff_real, double _coeff_imag, double _suppression_abs, double _suppression_delta) + : freq_(flatbuffers::EndianScalar(_freq)), + coeff_real_(flatbuffers::EndianScalar(_coeff_real)), + coeff_imag_(flatbuffers::EndianScalar(_coeff_imag)), + suppression_abs_(flatbuffers::EndianScalar(_suppression_abs)), + suppression_delta_(flatbuffers::EndianScalar(_suppression_delta)) { + } + double freq() const { + return flatbuffers::EndianScalar(freq_); + } + double coeff_real() const { + return flatbuffers::EndianScalar(coeff_real_); + } + double coeff_imag() const { + return flatbuffers::EndianScalar(coeff_imag_); + } + double suppression_abs() const { + return flatbuffers::EndianScalar(suppression_abs_); + } + double suppression_delta() const { + return flatbuffers::EndianScalar(suppression_delta_); + } +}; +FLATBUFFERS_STRUCT_END(IQCalCoeff, 40); + +struct IQCalCoeffs FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_METADATA = 4, + VT_COEFFS = 6 + }; + const Metadata *metadata() const { + return GetPointer<const Metadata *>(VT_METADATA); + } + const flatbuffers::Vector<const IQCalCoeff *> *coeffs() const { + return GetPointer<const flatbuffers::Vector<const IQCalCoeff *> *>(VT_COEFFS); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_METADATA) && + verifier.VerifyTable(metadata()) && + VerifyOffset(verifier, VT_COEFFS) && + verifier.VerifyVector(coeffs()) && + verifier.EndTable(); + } +}; + +struct IQCalCoeffsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_metadata(flatbuffers::Offset<Metadata> metadata) { + fbb_.AddOffset(IQCalCoeffs::VT_METADATA, metadata); + } + void add_coeffs(flatbuffers::Offset<flatbuffers::Vector<const IQCalCoeff *>> coeffs) { + fbb_.AddOffset(IQCalCoeffs::VT_COEFFS, coeffs); + } + explicit IQCalCoeffsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + IQCalCoeffsBuilder &operator=(const IQCalCoeffsBuilder &); + flatbuffers::Offset<IQCalCoeffs> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<IQCalCoeffs>(end); + return o; + } +}; + +inline flatbuffers::Offset<IQCalCoeffs> CreateIQCalCoeffs( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<Metadata> metadata = 0, + flatbuffers::Offset<flatbuffers::Vector<const IQCalCoeff *>> coeffs = 0) { + IQCalCoeffsBuilder builder_(_fbb); + builder_.add_coeffs(coeffs); + builder_.add_metadata(metadata); + return builder_.Finish(); +} + +inline flatbuffers::Offset<IQCalCoeffs> CreateIQCalCoeffsDirect( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<Metadata> metadata = 0, + const std::vector<IQCalCoeff> *coeffs = nullptr) { + auto coeffs__ = coeffs ? _fbb.CreateVectorOfStructs<IQCalCoeff>(*coeffs) : 0; + return uhd::usrp::cal::CreateIQCalCoeffs( + _fbb, + metadata, + coeffs__); +} + +inline const uhd::usrp::cal::IQCalCoeffs *GetIQCalCoeffs(const void *buf) { + return flatbuffers::GetRoot<uhd::usrp::cal::IQCalCoeffs>(buf); +} + +inline const uhd::usrp::cal::IQCalCoeffs *GetSizePrefixedIQCalCoeffs(const void *buf) { + return flatbuffers::GetSizePrefixedRoot<uhd::usrp::cal::IQCalCoeffs>(buf); +} + +inline const char *IQCalCoeffsIdentifier() { + return "IQ/f"; +} + +inline bool IQCalCoeffsBufferHasIdentifier(const void *buf) { + return flatbuffers::BufferHasIdentifier( + buf, IQCalCoeffsIdentifier()); +} + +inline bool VerifyIQCalCoeffsBuffer( + flatbuffers::Verifier &verifier) { + return verifier.VerifyBuffer<uhd::usrp::cal::IQCalCoeffs>(IQCalCoeffsIdentifier()); +} + +inline bool VerifySizePrefixedIQCalCoeffsBuffer( + flatbuffers::Verifier &verifier) { + return verifier.VerifySizePrefixedBuffer<uhd::usrp::cal::IQCalCoeffs>(IQCalCoeffsIdentifier()); +} + +inline void FinishIQCalCoeffsBuffer( + flatbuffers::FlatBufferBuilder &fbb, + flatbuffers::Offset<uhd::usrp::cal::IQCalCoeffs> root) { + fbb.Finish(root, IQCalCoeffsIdentifier()); +} + +inline void FinishSizePrefixedIQCalCoeffsBuffer( + flatbuffers::FlatBufferBuilder &fbb, + flatbuffers::Offset<uhd::usrp::cal::IQCalCoeffs> root) { + fbb.FinishSizePrefixed(root, IQCalCoeffsIdentifier()); +} + +} // namespace cal +} // namespace usrp +} // namespace uhd + +#endif // FLATBUFFERS_GENERATED_IQCAL_UHD_USRP_CAL_H_ |