aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/mboard_eeprom.cpp14
-rw-r--r--host/lib/usrp/x300/x300_fw_common.h3
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp240
-rw-r--r--host/lib/usrp/x300/x300_impl.hpp2
-rw-r--r--host/lib/usrp/x300/x300_regs.hpp50
5 files changed, 231 insertions, 78 deletions
diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp
index 9c92fe252..f60182c76 100644
--- a/host/lib/usrp/mboard_eeprom.cpp
+++ b/host/lib/usrp/mboard_eeprom.cpp
@@ -213,7 +213,8 @@ struct x300_eeprom_map
//indentifying numbers
unsigned char revision[2];
unsigned char product[2];
- boost::uint8_t _pad0[4];
+ unsigned char revision_compat[2];
+ boost::uint8_t _pad0[2];
//all the mac addrs
boost::uint8_t mac_addr0[6];
@@ -239,6 +240,11 @@ static void load_x300(mboard_eeprom_t &mb_eeprom, i2c_iface &iface)
iface.read_eeprom(X300_EEPROM_ADDR, offsetof(x300_eeprom_map, revision), 2)
);
+ //extract the revision compat number
+ mb_eeprom["revision_compat"] = uint16_bytes_to_string(
+ iface.read_eeprom(X300_EEPROM_ADDR, offsetof(x300_eeprom_map, revision_compat), 2)
+ );
+
//extract the product code
mb_eeprom["product"] = uint16_bytes_to_string(
iface.read_eeprom(X300_EEPROM_ADDR, offsetof(x300_eeprom_map, product), 2)
@@ -285,6 +291,12 @@ static void store_x300(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface)
string_to_uint16_bytes(mb_eeprom["revision"])
);
+ //parse the revision compat number
+ if (mb_eeprom.has_key("revision_compat")) iface.write_eeprom(
+ X300_EEPROM_ADDR, offsetof(x300_eeprom_map, revision_compat),
+ string_to_uint16_bytes(mb_eeprom["revision_compat"])
+ );
+
//parse the product code
if (mb_eeprom.has_key("product")) iface.write_eeprom(
X300_EEPROM_ADDR, offsetof(x300_eeprom_map, product),
diff --git a/host/lib/usrp/x300/x300_fw_common.h b/host/lib/usrp/x300/x300_fw_common.h
index f7364c774..63dbd1d32 100644
--- a/host/lib/usrp/x300/x300_fw_common.h
+++ b/host/lib/usrp/x300/x300_fw_common.h
@@ -29,7 +29,8 @@
extern "C" {
#endif
-#define X300_MAX_HW_REV 8
+#define X300_REVISION_COMPAT 7
+#define X300_REVISION_MIN 2
#define X300_FW_COMPAT_MAJOR 4
#define X300_FW_COMPAT_MINOR 0
#define X300_FPGA_COMPAT_MAJOR 11
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index 8c565a252..c742d34df 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -37,6 +37,7 @@
#include <uhd/transport/nirio_zero_copy.hpp>
#include <uhd/transport/nirio/niusrprio_session.h>
#include <uhd/utils/platform.hpp>
+#include <boost/date_time/posix_time/posix_time_io.hpp>
#define NIUSRPRIO_DEFAULT_RPC_PORT "5444"
@@ -399,7 +400,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
default:
nirio_status_to_exception(status, "Motherboard detection error. Please ensure that you \
have a valid USRP X3x0, NI USRP-294xR or NI USRP-295xR device and that all the device \
- driver have been loaded.");
+ drivers have loaded successfully.");
}
//Load the lvbitx onto the device
UHD_MSG(status) << boost::format("Using LVBITX bitfile %s...\n") % lvbitx->get_bitfile_path();
@@ -558,6 +559,13 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
.set(mb_eeprom)
.subscribe(boost::bind(&x300_impl::set_mb_eeprom, this, mb.zpu_i2c, _1));
+ bool recover_mb_eeprom = dev_addr.has_key("recover_mb_eeprom");
+ if (recover_mb_eeprom) {
+ UHD_MSG(warning) << "UHD is operating in EEPROM Recovery Mode which disables hardware version "
+ "checks.\nOperating in this mode may cause hardware damage and unstable "
+ "radio performance!"<< std::endl;
+ }
+
////////////////////////////////////////////////////////////////////
// parse the product number
////////////////////////////////////////////////////////////////////
@@ -570,7 +578,10 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
product_name = "X310";
break;
default:
- break;
+ if (not recover_mb_eeprom)
+ throw uhd::runtime_error("Unrecognized product type.\n"
+ "Either the software does not support this device in which case please update your driver software to the latest version and retry OR\n"
+ "The product code in the EEPROM is corrupt and may require reprogramming.");
}
_tree->create<std::string>(mb_path / "name").set(product_name);
_tree->create<std::string>(mb_path / "codename").set("Yetti");
@@ -602,36 +613,57 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
}
////////////////////////////////////////////////////////////////////
- // create clock control objects
+ // read hardware revision and compatibility number
////////////////////////////////////////////////////////////////////
- UHD_MSG(status) << "Setup RF frontend clocking..." << std::endl;
-
mb.hw_rev = 0;
if(mb_eeprom.has_key("revision") and not mb_eeprom["revision"].empty()) {
try {
mb.hw_rev = boost::lexical_cast<size_t>(mb_eeprom["revision"]);
} catch(...) {
- UHD_MSG(warning) << "Revision in EEPROM is invalid! Please reprogram your EEPROM." << std::endl;
+ if (not recover_mb_eeprom)
+ throw uhd::runtime_error("Revision in EEPROM is invalid! Please reprogram your EEPROM.");
+ }
+ } else {
+ if (not recover_mb_eeprom)
+ throw uhd::runtime_error("No revision detected. MB EEPROM must be reprogrammed!");
+ }
+
+ size_t hw_rev_compat = 0;
+ if (mb.hw_rev >= 7) { //Revision compat was added with revision 7
+ if (mb_eeprom.has_key("revision_compat") and not mb_eeprom["revision_compat"].empty()) {
+ try {
+ hw_rev_compat = boost::lexical_cast<size_t>(mb_eeprom["revision_compat"]);
+ } catch(...) {
+ if (not recover_mb_eeprom)
+ throw uhd::runtime_error("Revision compat in EEPROM is invalid! Please reprogram your EEPROM.");
+ }
+ } else {
+ if (not recover_mb_eeprom)
+ throw uhd::runtime_error("No revision compat detected. MB EEPROM must be reprogrammed!");
}
} else {
- UHD_MSG(warning) << "No revision detected MB EEPROM must be reprogrammed!" << std::endl;
+ //For older HW just assume that revision_compat = revision
+ hw_rev_compat = mb.hw_rev;
}
- if(mb.hw_rev == 0) {
- UHD_MSG(warning) << "Defaulting to X300 RevD Clock Settings. This will result in non-optimal lock times." << std::endl;
- mb.hw_rev = X300_REV("D");
+ if (hw_rev_compat > X300_REVISION_COMPAT) {
+ if (not recover_mb_eeprom)
+ throw uhd::runtime_error(str(boost::format(
+ "Hardware is too new for this software. Please upgrade to a driver that supports hardware revision %d.")
+ % mb.hw_rev));
+ } else if (mb.hw_rev < X300_REVISION_MIN) { //Compare min against the revision (and not compat) to give us more leeway for partial support for a compat
+ if (not recover_mb_eeprom)
+ throw uhd::runtime_error(str(boost::format(
+ "Software is too new for this hardware. Please downgrade to a driver that supports hardware revision %d.")
+ % mb.hw_rev));
}
- if (mb.hw_rev > X300_MAX_HW_REV) {
- throw uhd::runtime_error(str(
- boost::format("Unsupported board revision number: %d.\n"
- "The maximum board revision number supported in this version is %d.\n"
- "Please update your UHD version.")
- % mb.hw_rev % X300_MAX_HW_REV
- ));
- }
+ ////////////////////////////////////////////////////////////////////
+ // create clock control objects
+ ////////////////////////////////////////////////////////////////////
+ UHD_MSG(status) << "Setup RF frontend clocking..." << std::endl;
- //Create clock control. NOTE: This does not configure the LMK yet.
+ //Initialize clock control registers. NOTE: This does not configure the LMK yet.
initialize_clock_control(mb);
mb.clock = x300_clock_ctrl::make(mb.zpu_spi,
1 /*slaveno*/,
@@ -705,7 +737,11 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
if (dev_addr.has_key("self_cal_adc_delay")) {
self_cal_adc_xfer_delay(mb, true /* Apply ADC delay */);
}
- self_test_adcs(mb);
+ if (dev_addr.has_key("ext_adc_self_test")) {
+ extended_adc_test(mb, dev_addr.cast<double>("ext_adc_self_test", 30));
+ } else {
+ self_test_adcs(mb);
+ }
////////////////////////////////////////////////////////////////////
// front panel gpio
@@ -1743,23 +1779,39 @@ x300_impl::x300_mboard_t x300_impl::get_mb_type_from_pcie(const std::string& res
if (nirio_status_not_fatal(status)) {
//The PCIe ID -> MB mapping may be different from the EEPROM -> MB mapping
switch (pid) {
- case X300_USRP_PCIE_SSID:
+ case X300_USRP_PCIE_SSID_ADC_33:
+ case X300_USRP_PCIE_SSID_ADC_18:
mb_type = USRP_X300_MB; break;
- case X310_USRP_PCIE_SSID:
- case X310_2940R_40MHz_PCIE_SSID:
- case X310_2940R_120MHz_PCIE_SSID:
- case X310_2942R_40MHz_PCIE_SSID:
- case X310_2942R_120MHz_PCIE_SSID:
- case X310_2943R_40MHz_PCIE_SSID:
- case X310_2943R_120MHz_PCIE_SSID:
- case X310_2944R_40MHz_PCIE_SSID:
- case X310_2950R_40MHz_PCIE_SSID:
- case X310_2950R_120MHz_PCIE_SSID:
- case X310_2952R_40MHz_PCIE_SSID:
- case X310_2952R_120MHz_PCIE_SSID:
- case X310_2953R_40MHz_PCIE_SSID:
- case X310_2953R_120MHz_PCIE_SSID:
- case X310_2954R_40MHz_PCIE_SSID:
+ case X310_USRP_PCIE_SSID_ADC_33:
+ case X310_2940R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2940R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2942R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2942R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2943R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2943R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2944R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2950R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2950R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2952R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2952R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2953R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2953R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2954R_40MHz_PCIE_SSID_ADC_33:
+ case X310_USRP_PCIE_SSID_ADC_18:
+ case X310_2940R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2940R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2942R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2942R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2943R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2943R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2944R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2950R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2950R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2952R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2952R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2953R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2953R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2954R_40MHz_PCIE_SSID_ADC_18:
mb_type = USRP_X310_MB; break;
default:
mb_type = UNKNOWN; break;
@@ -1784,23 +1836,39 @@ x300_impl::x300_mboard_t x300_impl::get_mb_type_from_eeprom(const uhd::usrp::mbo
switch (product_num) {
//The PCIe ID -> MB mapping may be different from the EEPROM -> MB mapping
- case X300_USRP_PCIE_SSID:
+ case X300_USRP_PCIE_SSID_ADC_33:
+ case X300_USRP_PCIE_SSID_ADC_18:
mb_type = USRP_X300_MB; break;
- case X310_USRP_PCIE_SSID:
- case X310_2940R_40MHz_PCIE_SSID:
- case X310_2940R_120MHz_PCIE_SSID:
- case X310_2942R_40MHz_PCIE_SSID:
- case X310_2942R_120MHz_PCIE_SSID:
- case X310_2943R_40MHz_PCIE_SSID:
- case X310_2943R_120MHz_PCIE_SSID:
- case X310_2944R_40MHz_PCIE_SSID:
- case X310_2950R_40MHz_PCIE_SSID:
- case X310_2950R_120MHz_PCIE_SSID:
- case X310_2952R_40MHz_PCIE_SSID:
- case X310_2952R_120MHz_PCIE_SSID:
- case X310_2953R_40MHz_PCIE_SSID:
- case X310_2953R_120MHz_PCIE_SSID:
- case X310_2954R_40MHz_PCIE_SSID:
+ case X310_USRP_PCIE_SSID_ADC_33:
+ case X310_2940R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2940R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2942R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2942R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2943R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2943R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2944R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2950R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2950R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2952R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2952R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2953R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2953R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2954R_40MHz_PCIE_SSID_ADC_33:
+ case X310_USRP_PCIE_SSID_ADC_18:
+ case X310_2940R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2940R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2942R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2942R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2943R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2943R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2944R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2950R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2950R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2952R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2952R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2953R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2953R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2954R_40MHz_PCIE_SSID_ADC_18:
mb_type = USRP_X310_MB; break;
default:
UHD_MSG(warning) << "X300 unknown product code in EEPROM: " << product_num << std::endl;
@@ -2078,20 +2146,72 @@ void x300_impl::self_test_adcs(mboard_members_t& mb, boost::uint32_t ramp_time_m
perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 1);
}
boost::this_thread::sleep(boost::posix_time::milliseconds(ramp_time_ms));
+
+ bool passed = true;
+ std::string status_str;
for (size_t r = 0; r < mboard_members_t::NUM_RADIOS; r++) {
radio_perifs_t &perif = mb.radio_perifs[r];
+ perif.misc_ins->refresh();
+
+ std::string i_status, q_status;
+ if (perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_I_LOCKED))
+ if (perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_I_ERROR))
+ i_status = "Bit Errors!";
+ else
+ i_status = "Good";
+ else
+ i_status = "Not Locked!";
- if (!perif.misc_ins->read(radio_misc_ins_reg::ADC_CHECKER1_I_LOCKED) ||
- perif.misc_ins->read(radio_misc_ins_reg::ADC_CHECKER1_I_ERROR) ||
- !perif.misc_ins->read(radio_misc_ins_reg::ADC_CHECKER1_Q_LOCKED) ||
- perif.misc_ins->read(radio_misc_ins_reg::ADC_CHECKER1_Q_ERROR))
- {
- throw uhd::runtime_error(
- (boost::format("ADC self-test failed for Radio%d. (Ramp checker failure)")%r).str());
- }
+ if (perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_Q_LOCKED))
+ if (perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_Q_ERROR))
+ q_status = "Bit Errors!";
+ else
+ q_status = "Good";
+ else
+ q_status = "Not Locked!";
+
+ passed = passed && (i_status == "Good") && (q_status == "Good");
+ status_str += (boost::format(", ADC%d_I=%s, ADC%d_Q=%s")%r%i_status%r%q_status).str();
//Return to normal mode
perif.adc->set_test_word("normal", "normal");
}
+
+ if (not passed) {
+ throw uhd::runtime_error(
+ (boost::format("ADC self-test failed! Ramp checker status: {%s}")%status_str.substr(2)).str());
+ }
}
+void x300_impl::extended_adc_test(mboard_members_t& mb, double duration_s)
+{
+ static const size_t SECS_PER_ITER = 5;
+ UHD_MSG(status) << boost::format("Running Extended ADC Self-Test (Duration=%.0fs, %ds/iteration)...\n")
+ % duration_s % SECS_PER_ITER;
+
+ size_t num_iters = static_cast<size_t>(ceil(duration_s/SECS_PER_ITER));
+ size_t num_failures = 0;
+ for (size_t iter = 0; iter < num_iters; iter++) {
+ //Print date and time
+ boost::posix_time::time_facet *facet = new boost::posix_time::time_facet("%d-%b-%Y %H:%M:%S");
+ std::ostringstream time_strm;
+ time_strm.imbue(std::locale(std::locale::classic(), facet));
+ time_strm << boost::posix_time::second_clock::local_time();
+ //Run self-test
+ UHD_MSG(status) << boost::format("-- [%s] Iteration %06d... ") % time_strm.str() % (iter+1);
+ try {
+ self_test_adcs(mb, SECS_PER_ITER*1000);
+ UHD_MSG(status) << "passed" << std::endl;
+ } catch(std::exception &e) {
+ num_failures++;
+ UHD_MSG(status) << e.what() << std::endl;
+ }
+
+ }
+ if (num_failures == 0) {
+ UHD_MSG(status) << "Extended ADC Self-Test PASSED\n";
+ } else {
+ throw uhd::runtime_error(
+ (boost::format("Extended ADC Self-Test FAILED!!! (%d/%d failures)\n") % num_failures % num_iters).str());
+ }
+}
diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp
index 64f14cae6..ad1c802ee 100644
--- a/host/lib/usrp/x300/x300_impl.hpp
+++ b/host/lib/usrp/x300/x300_impl.hpp
@@ -410,6 +410,8 @@ private:
double self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay = false);
void self_test_adcs(mboard_members_t& mb, boost::uint32_t ramp_time_ms = 100);
+ void extended_adc_test(mboard_members_t& mb, double duration_s);
+
//**PRECONDITION**
//This function assumes that all the VITA times in "radios" are synchronized
//to a common reference. Currently, this function is called in get_tx_stream
diff --git a/host/lib/usrp/x300/x300_regs.hpp b/host/lib/usrp/x300/x300_regs.hpp
index e984eb908..f41afeb23 100644
--- a/host/lib/usrp/x300/x300_regs.hpp
+++ b/host/lib/usrp/x300/x300_regs.hpp
@@ -106,22 +106,40 @@ localparam ZPU_RB_ETH_TYPE1 = 5;
static const uint32_t X300_PCIE_VID = 0x1093;
static const uint32_t X300_PCIE_PID = 0xC4C4;
-static const uint32_t X300_USRP_PCIE_SSID = 0x7736;
-static const uint32_t X310_USRP_PCIE_SSID = 0x76CA;
-static const uint32_t X310_2940R_40MHz_PCIE_SSID = 0x772B;
-static const uint32_t X310_2940R_120MHz_PCIE_SSID = 0x77FB;
-static const uint32_t X310_2942R_40MHz_PCIE_SSID = 0x772C;
-static const uint32_t X310_2942R_120MHz_PCIE_SSID = 0x77FC;
-static const uint32_t X310_2943R_40MHz_PCIE_SSID = 0x772D;
-static const uint32_t X310_2943R_120MHz_PCIE_SSID = 0x77FD;
-static const uint32_t X310_2944R_40MHz_PCIE_SSID = 0x772E;
-static const uint32_t X310_2950R_40MHz_PCIE_SSID = 0x772F;
-static const uint32_t X310_2950R_120MHz_PCIE_SSID = 0x77FE;
-static const uint32_t X310_2952R_40MHz_PCIE_SSID = 0x7730;
-static const uint32_t X310_2952R_120MHz_PCIE_SSID = 0x77FF;
-static const uint32_t X310_2953R_40MHz_PCIE_SSID = 0x7731;
-static const uint32_t X310_2953R_120MHz_PCIE_SSID = 0x7800;
-static const uint32_t X310_2954R_40MHz_PCIE_SSID = 0x7732;
+//Rev 0-6 motherboard/PCIe IDs (ADC driven at 3.3V)
+static const uint32_t X300_USRP_PCIE_SSID_ADC_33 = 0x7736;
+static const uint32_t X310_USRP_PCIE_SSID_ADC_33 = 0x76CA;
+static const uint32_t X310_2940R_40MHz_PCIE_SSID_ADC_33 = 0x772B;
+static const uint32_t X310_2940R_120MHz_PCIE_SSID_ADC_33 = 0x77FB;
+static const uint32_t X310_2942R_40MHz_PCIE_SSID_ADC_33 = 0x772C;
+static const uint32_t X310_2942R_120MHz_PCIE_SSID_ADC_33 = 0x77FC;
+static const uint32_t X310_2943R_40MHz_PCIE_SSID_ADC_33 = 0x772D;
+static const uint32_t X310_2943R_120MHz_PCIE_SSID_ADC_33 = 0x77FD;
+static const uint32_t X310_2944R_40MHz_PCIE_SSID_ADC_33 = 0x772E;
+static const uint32_t X310_2950R_40MHz_PCIE_SSID_ADC_33 = 0x772F;
+static const uint32_t X310_2950R_120MHz_PCIE_SSID_ADC_33 = 0x77FE;
+static const uint32_t X310_2952R_40MHz_PCIE_SSID_ADC_33 = 0x7730;
+static const uint32_t X310_2952R_120MHz_PCIE_SSID_ADC_33 = 0x77FF;
+static const uint32_t X310_2953R_40MHz_PCIE_SSID_ADC_33 = 0x7731;
+static const uint32_t X310_2953R_120MHz_PCIE_SSID_ADC_33 = 0x7800;
+static const uint32_t X310_2954R_40MHz_PCIE_SSID_ADC_33 = 0x7732;
+//Rev 7+ motherboard/PCIe IDs (ADCs driven at 1.8V)
+static const uint32_t X300_USRP_PCIE_SSID_ADC_18 = 0x7861;
+static const uint32_t X310_USRP_PCIE_SSID_ADC_18 = 0x7862;
+static const uint32_t X310_2940R_40MHz_PCIE_SSID_ADC_18 = 0x7853;
+static const uint32_t X310_2940R_120MHz_PCIE_SSID_ADC_18 = 0x785B;
+static const uint32_t X310_2942R_40MHz_PCIE_SSID_ADC_18 = 0x7854;
+static const uint32_t X310_2942R_120MHz_PCIE_SSID_ADC_18 = 0x785C;
+static const uint32_t X310_2943R_40MHz_PCIE_SSID_ADC_18 = 0x7855;
+static const uint32_t X310_2943R_120MHz_PCIE_SSID_ADC_18 = 0x785D;
+static const uint32_t X310_2944R_40MHz_PCIE_SSID_ADC_18 = 0x7856;
+static const uint32_t X310_2950R_40MHz_PCIE_SSID_ADC_18 = 0x7857;
+static const uint32_t X310_2950R_120MHz_PCIE_SSID_ADC_18 = 0x785E;
+static const uint32_t X310_2952R_40MHz_PCIE_SSID_ADC_18 = 0x7858;
+static const uint32_t X310_2952R_120MHz_PCIE_SSID_ADC_18 = 0x785F;
+static const uint32_t X310_2953R_40MHz_PCIE_SSID_ADC_18 = 0x7859;
+static const uint32_t X310_2953R_120MHz_PCIE_SSID_ADC_18 = 0x7860;
+static const uint32_t X310_2954R_40MHz_PCIE_SSID_ADC_18 = 0x785A;
static const uint32_t FPGA_X3xx_SIG_VALUE = 0x58333030;