aboutsummaryrefslogtreecommitdiffstats
path: root/host/include
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2020-03-03 16:10:06 -0800
committerAaron Rossetto <aaron.rossetto@ni.com>2020-04-02 11:55:17 -0500
commit3fe5ccf700a0c6f27dca9511386460194dcc593c (patch)
tree19d394faac0581601d3d6e5d35a7a82e325bf245 /host/include
parent1e016e49e82c430197a90a018fbc7613cc654088 (diff)
downloaduhd-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.txt8
-rw-r--r--host/include/uhd/cal/cal_metadata.fbs15
-rw-r--r--host/include/uhd/cal/cal_metadata_generated.h111
-rw-r--r--host/include/uhd/cal/container.hpp9
-rw-r--r--host/include/uhd/cal/iq_cal.fbs32
-rw-r--r--host/include/uhd/cal/iq_cal.hpp78
-rw-r--r--host/include/uhd/cal/iq_cal_generated.h162
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_