aboutsummaryrefslogtreecommitdiffstats
path: root/host/include
diff options
context:
space:
mode:
authorLars Amsel <lars.amsel@ni.com>2021-06-04 08:27:50 +0200
committerAaron Rossetto <aaron.rossetto@ni.com>2021-06-10 12:01:53 -0500
commit2a575bf9b5a4942f60e979161764b9e942699e1e (patch)
tree2f0535625c30025559ebd7494a4b9e7122550a73 /host/include
parente17916220cc955fa219ae37f607626ba88c4afe3 (diff)
downloaduhd-2a575bf9b5a4942f60e979161764b9e942699e1e.tar.gz
uhd-2a575bf9b5a4942f60e979161764b9e942699e1e.tar.bz2
uhd-2a575bf9b5a4942f60e979161764b9e942699e1e.zip
uhd: Add support for the USRP X410
Co-authored-by: Lars Amsel <lars.amsel@ni.com> Co-authored-by: Michael Auchter <michael.auchter@ni.com> Co-authored-by: Martin Braun <martin.braun@ettus.com> Co-authored-by: Paul Butler <paul.butler@ni.com> Co-authored-by: Cristina Fuentes <cristina.fuentes-curiel@ni.com> Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com> Co-authored-by: Virendra Kakade <virendra.kakade@ni.com> Co-authored-by: Lane Kolbly <lane.kolbly@ni.com> Co-authored-by: Max Köhler <max.koehler@ni.com> Co-authored-by: Andrew Lynch <andrew.lynch@ni.com> Co-authored-by: Grant Meyerhoff <grant.meyerhoff@ni.com> Co-authored-by: Ciro Nishiguchi <ciro.nishiguchi@ni.com> Co-authored-by: Thomas Vogel <thomas.vogel@ni.com>
Diffstat (limited to 'host/include')
-rw-r--r--host/include/uhd/cal/CMakeLists.txt25
-rw-r--r--host/include/uhd/cal/dsa_cal.fbs36
-rw-r--r--host/include/uhd/cal/dsa_cal.hpp130
-rw-r--r--host/include/uhd/cal/dsa_cal_generated.h274
-rw-r--r--host/include/uhd/features/CMakeLists.txt1
-rw-r--r--host/include/uhd/features/adc_self_calibration_iface.hpp45
-rw-r--r--host/include/uhd/features/discoverable_feature.hpp3
-rw-r--r--host/include/uhd/features/ref_clk_calibration_iface.hpp44
-rw-r--r--host/include/uhd/rfnoc/blocks/radio.yml8
-rw-r--r--host/include/uhd/rfnoc/core/io_signatures.yml48
-rw-r--r--host/include/uhd/rfnoc/core/rfnoc_imagebuilder_args.json17
-rw-r--r--host/include/uhd/rfnoc/core/x410_bsp.yml57
-rw-r--r--host/include/uhd/rfnoc/defaults.hpp2
-rw-r--r--host/include/uhd/rfnoc/mb_controller.hpp4
-rw-r--r--host/include/uhd/rfnoc/rf_control/core_iface.hpp1
15 files changed, 681 insertions, 14 deletions
diff --git a/host/include/uhd/cal/CMakeLists.txt b/host/include/uhd/cal/CMakeLists.txt
index 38b4885ef..482502c89 100644
--- a/host/include/uhd/cal/CMakeLists.txt
+++ b/host/include/uhd/cal/CMakeLists.txt
@@ -4,21 +4,38 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
+set(FLATBUFFER_SCHEMA_FILES
+ "cal_metadata.fbs"
+ "iq_cal.fbs"
+ "pwr_cal.fbs"
+ "dsa_cal.fbs"
+)
+
+set(FLATBUFFER_GEN_HEADER_FILES
+ "cal_metadata_generated.h"
+ "iq_cal_generated.h"
+ "pwr_cal_generated.h"
+ "dsa_cal_generated.h"
+)
+
UHD_INSTALL(FILES
container.hpp
database.hpp
iq_cal.hpp
pwr_cal.hpp
- iq_cal_generated.h
- pwr_cal_generated.h
+ dsa_cal.hpp
DESTINATION ${INCLUDE_DIR}/uhd/cal
COMPONENT headers
)
UHD_INSTALL(FILES
- iq_cal.fbs
- pwr_cal.fbs
+ ${FLATBUFFER_SCHEMA_FILES}
DESTINATION ${PKG_DATA_DIR}/cal
COMPONENT headers
)
+UHD_INSTALL(FILES
+ ${FLATBUFFER_GEN_HEADER_FILES}
+ DESTINATION ${INCLUDE_DIR}/uhd/cal
+ COMPONENT headers
+ )
diff --git a/host/include/uhd/cal/dsa_cal.fbs b/host/include/uhd/cal/dsa_cal.fbs
new file mode 100644
index 000000000..dc33da497
--- /dev/null
+++ b/host/include/uhd/cal/dsa_cal.fbs
@@ -0,0 +1,36 @@
+//
+// Copyright 2020 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+// DSA step setting table
+
+include "cal_metadata.fbs";
+
+namespace uhd.usrp.cal;
+
+// DSA step settings for a given gain in a band
+table DsaStep
+{
+ steps: [uint];
+}
+
+// DSA settings for all gains of a band
+table BandDsaMap
+{
+ max_freq: ulong (key); // max frequency for the band
+ gains: [DsaStep]; // DSA step setting for all gain values
+ name: string; // human readable frequency band name
+}
+
+// Band settings
+table DsaCal
+{
+ metadata: Metadata; // useful additional information
+ band_dsa_map: [BandDsaMap]; // settings for all bands
+}
+
+root_type DsaCal;
+file_identifier "dsas";
+file_extension "cal";
diff --git a/host/include/uhd/cal/dsa_cal.hpp b/host/include/uhd/cal/dsa_cal.hpp
new file mode 100644
index 000000000..e8ead87ee
--- /dev/null
+++ b/host/include/uhd/cal/dsa_cal.hpp
@@ -0,0 +1,130 @@
+//
+// Copyright 2020 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_LIBUHD_CAL_GAIN_HPP
+#define INCLUDED_LIBUHD_CAL_GAIN_HPP
+
+#include <uhd/cal/container.hpp>
+#include <uhd/config.hpp>
+#include <boost/optional.hpp>
+#include <array>
+#include <map>
+
+namespace uhd { namespace usrp { namespace cal {
+
+/*! Class that stores DSA indices for all ZBX TX bands.
+ */
+class UHD_API zbx_tx_dsa_cal : public container
+{
+public:
+ static constexpr uint32_t NUM_AMP = 1;
+ static constexpr uint32_t NUM_DSA = 2 + NUM_AMP;
+ static constexpr uint32_t NUM_GAIN_STAGES = 61;
+
+ using sptr = std::shared_ptr<zbx_tx_dsa_cal>;
+ using step_settings = std::array<uint32_t, NUM_DSA>;
+
+ /*! Add a new band description
+ *
+ * max_freq is the (inclusive) upper limit
+ * for the band (lower limit derives from the other bands). Name is an
+ * text representation (human readable) for the band. dsa_steps is an
+ * array of DSA settings for all gains in the band.
+ */
+ virtual void add_frequency_band(const double max_freq,
+ const std::string& name,
+ std::array<step_settings, NUM_GAIN_STAGES> dsa_steps) = 0;
+
+ /*! Retrieves DSA settings for frequency and gain_index.
+ *
+ * The settings are
+ * retrieved from the band with the biggest max_freq that is smaller or
+ * equal to freq. DSA settings are the settings at gain_index in that band.
+ * Value errors are thrown if freq is larger that the largest freq_max of
+ * all bands or gain_index is not within range.
+ */
+ virtual const step_settings get_dsa_setting(
+ const double freq, const size_t gain_index) const = 0;
+
+ /* Check whether two frequencies map to the same band.
+ */
+ virtual bool is_same_band(double freq1, double freq2) const = 0;
+
+ /*! Retrieves DSA settings as flat list.
+ * The values are flattened by frequency band, gain and values in that order.
+ * Use NUM_DSA and NUM_GAIN_STAGES to find values in the list.
+ */
+ virtual std::vector<uint32_t> get_band_settings(double freq, uint8_t dsa) const = 0;
+
+ /*!
+ * Clear all stored values
+ */
+ 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();
+};
+
+/*! Class that stores DSA indices for all ZBX TX bands.
+ */
+class UHD_API zbx_rx_dsa_cal : public container
+{
+public:
+ static constexpr uint32_t NUM_DSA = 4;
+ static constexpr uint32_t NUM_GAIN_STAGES = 61;
+
+ using sptr = std::shared_ptr<zbx_rx_dsa_cal>;
+ using step_settings = std::array<uint32_t, NUM_DSA>;
+
+ /*! Add a new band description.
+ *
+ * max_freq is the (inclusive) upper limit
+ * for the band (lower limit derives from the other bands). Name is an
+ * text representation (human readable) for the band. dsa_steps is an
+ * array of DSA settings for all gains in the band.
+ */
+ virtual void add_frequency_band(const double max_freq,
+ const std::string& name,
+ std::array<step_settings, NUM_GAIN_STAGES> dsa_steps) = 0;
+
+ virtual bool is_same_band(double freq1, double freq2) const = 0;
+ /*! Retrieves DSA settings for frequency and gain_index.
+ *
+ * The settings are
+ * retrieved from the band with the biggest max_freq that is smaller or
+ * equal to freq. DSA settings are the settings at gain_index in that band.
+ * Value errors are thrown if freq is larger that the largest freq_max of
+ * all bands or gain_index is not within range.
+ */
+ virtual const step_settings get_dsa_setting(
+ const double freq, const size_t gain_index) const = 0;
+
+ /*! Retrieves DSA settings as flat list.
+ * The values are flattend by frequency band, gain and values in that order.
+ * Use NUM_DSA and NUM_GAIN_STAGES to find values in the list.
+ */
+ virtual std::vector<uint32_t> get_band_settings(double freq, uint8_t dsa) const = 0;
+
+ /*!
+ * Clear all stored values
+ */
+ 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_GAIN_HPP */
diff --git a/host/include/uhd/cal/dsa_cal_generated.h b/host/include/uhd/cal/dsa_cal_generated.h
new file mode 100644
index 000000000..18e8a2713
--- /dev/null
+++ b/host/include/uhd/cal/dsa_cal_generated.h
@@ -0,0 +1,274 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_DSACAL_UHD_USRP_CAL_H_
+#define FLATBUFFERS_GENERATED_DSACAL_UHD_USRP_CAL_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+#include "cal_metadata_generated.h"
+
+namespace uhd {
+namespace usrp {
+namespace cal {
+
+struct DsaStep;
+struct DsaStepBuilder;
+
+struct BandDsaMap;
+struct BandDsaMapBuilder;
+
+struct DsaCal;
+struct DsaCalBuilder;
+
+struct DsaStep FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef DsaStepBuilder Builder;
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_STEPS = 4
+ };
+ const flatbuffers::Vector<uint32_t> *steps() const {
+ return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_STEPS);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyOffset(verifier, VT_STEPS) &&
+ verifier.VerifyVector(steps()) &&
+ verifier.EndTable();
+ }
+};
+
+struct DsaStepBuilder {
+ typedef DsaStep Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_steps(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> steps) {
+ fbb_.AddOffset(DsaStep::VT_STEPS, steps);
+ }
+ explicit DsaStepBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ DsaStepBuilder &operator=(const DsaStepBuilder &);
+ flatbuffers::Offset<DsaStep> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<DsaStep>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<DsaStep> CreateDsaStep(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ flatbuffers::Offset<flatbuffers::Vector<uint32_t>> steps = 0) {
+ DsaStepBuilder builder_(_fbb);
+ builder_.add_steps(steps);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<DsaStep> CreateDsaStepDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ const std::vector<uint32_t> *steps = nullptr) {
+ auto steps__ = steps ? _fbb.CreateVector<uint32_t>(*steps) : 0;
+ return uhd::usrp::cal::CreateDsaStep(
+ _fbb,
+ steps__);
+}
+
+struct BandDsaMap FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef BandDsaMapBuilder Builder;
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_MAX_FREQ = 4,
+ VT_GAINS = 6,
+ VT_NAME = 8
+ };
+ uint64_t max_freq() const {
+ return GetField<uint64_t>(VT_MAX_FREQ, 0);
+ }
+ bool KeyCompareLessThan(const BandDsaMap *o) const {
+ return max_freq() < o->max_freq();
+ }
+ int KeyCompareWithValue(uint64_t val) const {
+ return static_cast<int>(max_freq() > val) - static_cast<int>(max_freq() < val);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<uhd::usrp::cal::DsaStep>> *gains() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<uhd::usrp::cal::DsaStep>> *>(VT_GAINS);
+ }
+ const flatbuffers::String *name() const {
+ return GetPointer<const flatbuffers::String *>(VT_NAME);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<uint64_t>(verifier, VT_MAX_FREQ) &&
+ VerifyOffset(verifier, VT_GAINS) &&
+ verifier.VerifyVector(gains()) &&
+ verifier.VerifyVectorOfTables(gains()) &&
+ VerifyOffset(verifier, VT_NAME) &&
+ verifier.VerifyString(name()) &&
+ verifier.EndTable();
+ }
+};
+
+struct BandDsaMapBuilder {
+ typedef BandDsaMap Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_max_freq(uint64_t max_freq) {
+ fbb_.AddElement<uint64_t>(BandDsaMap::VT_MAX_FREQ, max_freq, 0);
+ }
+ void add_gains(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<uhd::usrp::cal::DsaStep>>> gains) {
+ fbb_.AddOffset(BandDsaMap::VT_GAINS, gains);
+ }
+ void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+ fbb_.AddOffset(BandDsaMap::VT_NAME, name);
+ }
+ explicit BandDsaMapBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ BandDsaMapBuilder &operator=(const BandDsaMapBuilder &);
+ flatbuffers::Offset<BandDsaMap> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<BandDsaMap>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<BandDsaMap> CreateBandDsaMap(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ uint64_t max_freq = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<uhd::usrp::cal::DsaStep>>> gains = 0,
+ flatbuffers::Offset<flatbuffers::String> name = 0) {
+ BandDsaMapBuilder builder_(_fbb);
+ builder_.add_max_freq(max_freq);
+ builder_.add_name(name);
+ builder_.add_gains(gains);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<BandDsaMap> CreateBandDsaMapDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ uint64_t max_freq = 0,
+ const std::vector<flatbuffers::Offset<uhd::usrp::cal::DsaStep>> *gains = nullptr,
+ const char *name = nullptr) {
+ auto gains__ = gains ? _fbb.CreateVector<flatbuffers::Offset<uhd::usrp::cal::DsaStep>>(*gains) : 0;
+ auto name__ = name ? _fbb.CreateString(name) : 0;
+ return uhd::usrp::cal::CreateBandDsaMap(
+ _fbb,
+ max_freq,
+ gains__,
+ name__);
+}
+
+struct DsaCal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef DsaCalBuilder Builder;
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_METADATA = 4,
+ VT_BAND_DSA_MAP = 6
+ };
+ const Metadata *metadata() const {
+ return GetPointer<const Metadata *>(VT_METADATA);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<uhd::usrp::cal::BandDsaMap>> *band_dsa_map() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<uhd::usrp::cal::BandDsaMap>> *>(VT_BAND_DSA_MAP);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyOffset(verifier, VT_METADATA) &&
+ verifier.VerifyTable(metadata()) &&
+ VerifyOffset(verifier, VT_BAND_DSA_MAP) &&
+ verifier.VerifyVector(band_dsa_map()) &&
+ verifier.VerifyVectorOfTables(band_dsa_map()) &&
+ verifier.EndTable();
+ }
+};
+
+struct DsaCalBuilder {
+ typedef DsaCal Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_metadata(flatbuffers::Offset<Metadata> metadata) {
+ fbb_.AddOffset(DsaCal::VT_METADATA, metadata);
+ }
+ void add_band_dsa_map(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<uhd::usrp::cal::BandDsaMap>>> band_dsa_map) {
+ fbb_.AddOffset(DsaCal::VT_BAND_DSA_MAP, band_dsa_map);
+ }
+ explicit DsaCalBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ DsaCalBuilder &operator=(const DsaCalBuilder &);
+ flatbuffers::Offset<DsaCal> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<DsaCal>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<DsaCal> CreateDsaCal(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ flatbuffers::Offset<Metadata> metadata = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<uhd::usrp::cal::BandDsaMap>>> band_dsa_map = 0) {
+ DsaCalBuilder builder_(_fbb);
+ builder_.add_band_dsa_map(band_dsa_map);
+ builder_.add_metadata(metadata);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<DsaCal> CreateDsaCalDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ flatbuffers::Offset<Metadata> metadata = 0,
+ std::vector<flatbuffers::Offset<uhd::usrp::cal::BandDsaMap>> *band_dsa_map = nullptr) {
+ auto band_dsa_map__ = band_dsa_map ? _fbb.CreateVectorOfSortedTables<uhd::usrp::cal::BandDsaMap>(band_dsa_map) : 0;
+ return uhd::usrp::cal::CreateDsaCal(
+ _fbb,
+ metadata,
+ band_dsa_map__);
+}
+
+inline const uhd::usrp::cal::DsaCal *GetDsaCal(const void *buf) {
+ return flatbuffers::GetRoot<uhd::usrp::cal::DsaCal>(buf);
+}
+
+inline const uhd::usrp::cal::DsaCal *GetSizePrefixedDsaCal(const void *buf) {
+ return flatbuffers::GetSizePrefixedRoot<uhd::usrp::cal::DsaCal>(buf);
+}
+
+inline const char *DsaCalIdentifier() {
+ return "dsas";
+}
+
+inline bool DsaCalBufferHasIdentifier(const void *buf) {
+ return flatbuffers::BufferHasIdentifier(
+ buf, DsaCalIdentifier());
+}
+
+inline bool VerifyDsaCalBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifyBuffer<uhd::usrp::cal::DsaCal>(DsaCalIdentifier());
+}
+
+inline bool VerifySizePrefixedDsaCalBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifySizePrefixedBuffer<uhd::usrp::cal::DsaCal>(DsaCalIdentifier());
+}
+
+inline const char *DsaCalExtension() {
+ return "cal";
+}
+
+inline void FinishDsaCalBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<uhd::usrp::cal::DsaCal> root) {
+ fbb.Finish(root, DsaCalIdentifier());
+}
+
+inline void FinishSizePrefixedDsaCalBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<uhd::usrp::cal::DsaCal> root) {
+ fbb.FinishSizePrefixed(root, DsaCalIdentifier());
+}
+
+} // namespace cal
+} // namespace usrp
+} // namespace uhd
+
+#endif // FLATBUFFERS_GENERATED_DSACAL_UHD_USRP_CAL_H_
diff --git a/host/include/uhd/features/CMakeLists.txt b/host/include/uhd/features/CMakeLists.txt
index 798844077..64e50bb12 100644
--- a/host/include/uhd/features/CMakeLists.txt
+++ b/host/include/uhd/features/CMakeLists.txt
@@ -7,6 +7,7 @@
UHD_INSTALL(FILES
discoverable_feature.hpp
discoverable_feature_getter_iface.hpp
+ ref_clk_calibration_iface.hpp
DESTINATION ${INCLUDE_DIR}/uhd/features
COMPONENT headers
)
diff --git a/host/include/uhd/features/adc_self_calibration_iface.hpp b/host/include/uhd/features/adc_self_calibration_iface.hpp
new file mode 100644
index 000000000..fbacccf77
--- /dev/null
+++ b/host/include/uhd/features/adc_self_calibration_iface.hpp
@@ -0,0 +1,45 @@
+//
+// Copyright 2020 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#pragma once
+
+#include <uhd/features/discoverable_feature.hpp>
+#include <memory>
+
+namespace uhd { namespace features {
+
+/*! Interface for running ADC self-calibration on supported devices.
+ * Currently, only the X4xx series of devices supports calibrating the
+ * internal ADCs.
+ */
+class adc_self_calibration_iface : public discoverable_feature
+{
+public:
+ using sptr = std::shared_ptr<adc_self_calibration_iface>;
+
+ static discoverable_feature::feature_id_t get_feature_id()
+ {
+ return discoverable_feature::ADC_SELF_CALIBRATION;
+ }
+
+ std::string get_feature_name() const
+ {
+ return "ADC Self Calibration";
+ }
+
+ virtual ~adc_self_calibration_iface() = default;
+
+ //! Runs calibration on the specified channel. This will momentarily
+ // reconfigure both the specified RX channel as well as the matching
+ // TX channel for the operation.
+ //
+ // If you would like to calibrate the ADCs without interrupting the
+ // signal chain, use the rx_codec/<n>/calibration_frozen property on the
+ // motherboard's property tree.
+ virtual void run(const size_t chan) = 0;
+};
+
+}} // namespace uhd::features
diff --git a/host/include/uhd/features/discoverable_feature.hpp b/host/include/uhd/features/discoverable_feature.hpp
index afe25cb63..8cbe8e13f 100644
--- a/host/include/uhd/features/discoverable_feature.hpp
+++ b/host/include/uhd/features/discoverable_feature.hpp
@@ -31,6 +31,9 @@ public:
enum feature_id_t {
RESERVED0,
RESERVED1,
+ FPGA_LOAD_NOTIFICATION,
+ ADC_SELF_CALIBRATION,
+ REF_CLK_CALIBRATION,
};
virtual ~discoverable_feature() = default;
diff --git a/host/include/uhd/features/ref_clk_calibration_iface.hpp b/host/include/uhd/features/ref_clk_calibration_iface.hpp
new file mode 100644
index 000000000..83082da68
--- /dev/null
+++ b/host/include/uhd/features/ref_clk_calibration_iface.hpp
@@ -0,0 +1,44 @@
+//
+// Copyright 2020 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#pragma once
+
+#include <uhd/features/discoverable_feature.hpp>
+#include <memory>
+
+namespace uhd { namespace features {
+
+/*! Interface to provide access to functions (set, get and store the tuning
+ * word) to perform calibration of the DAC for the internal reference clock
+ * source on supported devices. Currently, only the X4xx series of devices
+ * supports this.
+ */
+class ref_clk_calibration_iface : public discoverable_feature
+{
+public:
+ using sptr = std::shared_ptr<ref_clk_calibration_iface>;
+
+ static discoverable_feature::feature_id_t get_feature_id()
+ {
+ return discoverable_feature::REF_CLK_CALIBRATION;
+ }
+
+ std::string get_feature_name() const
+ {
+ return "Ref Clk Calibration";
+ }
+
+ virtual ~ref_clk_calibration_iface() = default;
+
+ //! Set the tuning word to be configured on the internal reference clock DAC.
+ virtual void set_ref_clk_tuning_word(uint32_t tuning_word) = 0;
+ //! Returns the tuning word configured on the internal reference clock DAC.
+ virtual uint32_t get_ref_clk_tuning_word() = 0;
+ //! Writes the reference clock tuning word to the clocking board EEPROM.
+ virtual void store_ref_clk_tuning_word(uint32_t tuning_word) = 0;
+};
+
+}} // namespace uhd::features
diff --git a/host/include/uhd/rfnoc/blocks/radio.yml b/host/include/uhd/rfnoc/blocks/radio.yml
index 81b96bf07..bae9fe128 100644
--- a/host/include/uhd/rfnoc/blocks/radio.yml
+++ b/host/include/uhd/rfnoc/blocks/radio.yml
@@ -52,17 +52,17 @@ data:
mdata_sig: ~
io_ports:
- ctrl_port:
+ ctrlport:
type: ctrl_port
drive: master
rename:
pattern: (.*)
repl: m_\1
- time_keeper:
+ time:
type: time_keeper
drive: listener
- x300_radio:
- type: radio_1x32
+ radio:
+ type: radio_8x32
drive: slave
registers:
diff --git a/host/include/uhd/rfnoc/core/io_signatures.yml b/host/include/uhd/rfnoc/core/io_signatures.yml
index 9b1d729f6..de8ab0050 100644
--- a/host/include/uhd/rfnoc/core/io_signatures.yml
+++ b/host/include/uhd/rfnoc/core/io_signatures.yml
@@ -34,6 +34,7 @@ time_keeper:
- name: radio_time
width: 64
+# Single channel radio interface
radio_1x32:
type: master-slave
ports:
@@ -56,6 +57,30 @@ radio_1x32:
type: to-master
width: 1
+# Two channel radio interface, or single channel with 2 SPC
+radio_2x32:
+ type: master-slave
+ ports:
+ - name: radio_rx_data
+ type: from-master
+ width: 64
+ - name: radio_rx_stb
+ type: from-master
+ width: 2
+ - name: radio_rx_running
+ type: to-master
+ width: 2
+ - name: radio_tx_data
+ type: to-master
+ width: 64
+ - name: radio_tx_stb
+ type: from-master
+ width: 2
+ - name: radio_tx_running
+ type: to-master
+ width: 2
+
+# Same as radio_2x32, but kept for backwards compatibility with the old name
x300_radio:
type: master-slave
ports:
@@ -78,6 +103,29 @@ x300_radio:
type: to-master
width: 2
+# Eight channel radio interface, or two channels with 4 SPC
+radio_8x32:
+ type: master-slave
+ ports:
+ - name: radio_rx_data
+ type: from-master
+ width: 256
+ - name: radio_rx_stb
+ type: from-master
+ width: 8
+ - name: radio_rx_running
+ type: to-master
+ width: 8
+ - name: radio_tx_data
+ type: to-master
+ width: 256
+ - name: radio_tx_stb
+ type: from-master
+ width: 8
+ - name: radio_tx_running
+ type: to-master
+ width: 8
+
# A 4-port AXI4 memory-mapped interface with 64-bit data, and 4 GiB address
# space (32-bit).
axi4_mm_4x64_4g:
diff --git a/host/include/uhd/rfnoc/core/rfnoc_imagebuilder_args.json b/host/include/uhd/rfnoc/core/rfnoc_imagebuilder_args.json
index 2d76643be..120ecd5dd 100644
--- a/host/include/uhd/rfnoc/core/rfnoc_imagebuilder_args.json
+++ b/host/include/uhd/rfnoc/core/rfnoc_imagebuilder_args.json
@@ -3,12 +3,13 @@
"properties": {
"schema": { "const": "rfnoc_imagebuilder_args" },
"copyright": { "type": "string" },
- "version": { "type": "number" },
+ "version": { "type": "string" },
"license": { "type": "string" },
"device": { "type": "string" },
+ "image_core_name": { "type": "string" },
"default_target": { "type": "string" },
- "rfnoc_version": { "type": "number" },
- "chdr_width": { "enum": [64, 256] },
+ "rfnoc_version": { "type": "string" },
+ "chdr_width": { "enum": [64, 128, 256, 512] },
"stream_endpoints": { "$ref": "#/definitions/stream_endpoints" },
"noc_blocks": { "$ref": "#/definitions/noc_blocks" },
@@ -45,9 +46,15 @@
"data": { "type": "boolean" },
"num_data_i":{ "type": "integer", "minimum": 1 },
"num_data_o":{ "type": "integer", "minimum": 1 },
- "buff_size": { "type": "integer", "minimum": 0 }
+ "buff_size": { "type": "integer", "minimum": 0 },
+ "buff_size_bytes": { "type": "integer", "minimum": 0 }
},
- "additionalProperties": false
+ "additionalProperties": false,
+ "not": {
+ "anyOf": [
+ {"required": ["buff_size", "buff_size_bytes"]}
+ ]
+ }
},
"noc_block": {
diff --git a/host/include/uhd/rfnoc/core/x410_bsp.yml b/host/include/uhd/rfnoc/core/x410_bsp.yml
new file mode 100644
index 000000000..66b6d77b0
--- /dev/null
+++ b/host/include/uhd/rfnoc/core/x410_bsp.yml
@@ -0,0 +1,57 @@
+type: x410
+type_id: A400
+family: ULTRASCALE
+transports:
+# QSFP Ethernet Ports:
+- name: eth0
+ type: 10G
+ width: 64
+- name: eth1
+ type: 10G
+ width: 64
+- name: eth2
+ type: 10G
+ width: 64
+- name: eth3
+ type: 10G
+ width: 64
+- name: eth4
+ type: 10G
+ width: 64
+# ARM CPU:
+- name: dma
+ type: dma
+ width: 64
+
+clocks:
+- name: radio
+- name: radio_2x
+
+io_ports:
+ ctrlport_radio0:
+ type: ctrl_port
+ drive: slave
+ rename:
+ pattern: (ctrlport_)(.*)
+ repl: m_\1radio0_\2
+ ctrlport_radio1:
+ type: ctrl_port
+ drive: slave
+ rename:
+ pattern: (ctrlport_)(.*)
+ repl: m_\1radio1_\2
+ time:
+ type: time_keeper
+ drive: broadcaster
+ radio0:
+ type: radio_8x32
+ drive: master
+ rename:
+ pattern: (.*)
+ repl: \1_radio0
+ radio1:
+ type: radio_8x32
+ drive: master
+ rename:
+ pattern: (.*)
+ repl: \1_radio1
diff --git a/host/include/uhd/rfnoc/defaults.hpp b/host/include/uhd/rfnoc/defaults.hpp
index 1b9cb5016..d0f6c2311 100644
--- a/host/include/uhd/rfnoc/defaults.hpp
+++ b/host/include/uhd/rfnoc/defaults.hpp
@@ -72,6 +72,8 @@ static const device_type_t N300 = 0x1300;
static const device_type_t N320 = 0x1320;
//! X300 device family (X300, X310)
static const device_type_t X300 = 0xA300;
+//! X400 device family
+static const device_type_t X400 = 0xA400;
// block identifiers
static const noc_id_t ADDSUB_BLOCK = 0xADD00000;
diff --git a/host/include/uhd/rfnoc/mb_controller.hpp b/host/include/uhd/rfnoc/mb_controller.hpp
index e1268d923..5ca0ce52a 100644
--- a/host/include/uhd/rfnoc/mb_controller.hpp
+++ b/host/include/uhd/rfnoc/mb_controller.hpp
@@ -7,6 +7,7 @@
#pragma once
#include <uhd/config.hpp>
+#include <uhd/features/discoverable_feature_getter_iface.hpp>
#include <uhd/types/device_addr.hpp>
#include <uhd/types/sensors.hpp>
#include <uhd/types/time_spec.hpp>
@@ -21,7 +22,8 @@ namespace uhd { namespace rfnoc {
/*! A default block controller for blocks that can't be found in the registry
*/
-class UHD_API mb_controller : public uhd::noncopyable
+class UHD_API mb_controller : public uhd::noncopyable,
+ public virtual ::uhd::features::discoverable_feature_getter_iface
{
public:
using sptr = std::shared_ptr<mb_controller>;
diff --git a/host/include/uhd/rfnoc/rf_control/core_iface.hpp b/host/include/uhd/rfnoc/rf_control/core_iface.hpp
index ff7ec3550..a96ed2f60 100644
--- a/host/include/uhd/rfnoc/rf_control/core_iface.hpp
+++ b/host/include/uhd/rfnoc/rf_control/core_iface.hpp
@@ -6,6 +6,7 @@
#pragma once
+#include <uhd/types/device_addr.hpp>
#include <uhd/types/ranges.hpp>
#include <stdint.h>
#include <string>