aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAshish Chaudhari <ashish@ettus.com>2015-08-04 16:15:58 -0500
committerAshish Chaudhari <ashish@ettus.com>2015-08-04 16:15:58 -0500
commit55a280a09905567b61e4cf7c7aecfa971947131c (patch)
tree48608366809f8233045ceaa2c2b0f34cb5c46ebc
parentd49ca2cf0fca954fc033cf4ddf3cd3502cc39548 (diff)
downloaduhd-55a280a09905567b61e4cf7c7aecfa971947131c.tar.gz
uhd-55a280a09905567b61e4cf7c7aecfa971947131c.tar.bz2
uhd-55a280a09905567b61e4cf7c7aecfa971947131c.zip
x300: Used new soft register API for X300 registers
-rw-r--r--host/lib/usrp/x300/x300_adc_dac_utils.cpp68
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp143
-rw-r--r--host/lib/usrp/x300/x300_impl.hpp52
-rw-r--r--host/lib/usrp/x300/x300_regs.hpp109
4 files changed, 196 insertions, 176 deletions
diff --git a/host/lib/usrp/x300/x300_adc_dac_utils.cpp b/host/lib/usrp/x300/x300_adc_dac_utils.cpp
index 2dadea26e..b1483b3a5 100644
--- a/host/lib/usrp/x300/x300_adc_dac_utils.cpp
+++ b/host/lib/usrp/x300/x300_adc_dac_utils.cpp
@@ -18,6 +18,8 @@
#include "x300_impl.hpp"
#include <boost/date_time/posix_time/posix_time_io.hpp>
+using namespace uhd::usrp::x300;
+
/***********************************************************************
* DAC: Reset and synchronization operations
**********************************************************************/
@@ -101,8 +103,8 @@ void x300_impl::self_test_adcs(mboard_members_t& mb, boost::uint32_t ramp_time_m
//Turn on ramp pattern test
perif.adc->set_test_word("ramp", "ramp");
- perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
- perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 1);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
}
boost::this_thread::sleep(boost::posix_time::milliseconds(ramp_time_ms));
@@ -110,19 +112,19 @@ void x300_impl::self_test_adcs(mboard_members_t& mb, boost::uint32_t ramp_time_m
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();
+ perif.regmap->misc_ins_reg.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))
+ if (perif.regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_LOCKED))
+ if (perif.regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_ERROR))
i_status = "Bit Errors!";
else
i_status = "Good";
else
i_status = "Not Locked!";
- 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))
+ if (perif.regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_LOCKED))
+ if (perif.regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_ERROR))
q_status = "Bit Errors!";
else
q_status = "Good";
@@ -193,9 +195,9 @@ void x300_impl::self_cal_adc_capture_delay(mboard_members_t& mb, const size_t ra
while (iter++ < NUM_RETRIES) {
for (boost::uint32_t dly_tap = 0; dly_tap < NUM_DELAY_STEPS; dly_tap++) {
//Apply delay
- perif.misc_outs->write(radio_misc_outs_reg::ADC_DATA_DLY_VAL, dly_tap);
- perif.misc_outs->write(radio_misc_outs_reg::ADC_DATA_DLY_STB, 1);
- perif.misc_outs->write(radio_misc_outs_reg::ADC_DATA_DLY_STB, 0);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, dly_tap);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 1);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 0);
boost::uint32_t err_code = 0;
@@ -204,12 +206,12 @@ void x300_impl::self_cal_adc_capture_delay(mboard_members_t& mb, const size_t ra
perif.adc->set_test_word("ramp", "ones");
//Turn on the pattern checker in the FPGA. It will lock when it sees a zero
//and count deviations from the expected value
- perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
- perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 1);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
//10ms @ 200MHz = 2 million samples
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
- if (perif.misc_ins->read(radio_misc_ins_reg::ADC_CHECKER0_I_LOCKED)) {
- err_code += perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER0_I_ERROR);
+ if (perif.regmap->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_LOCKED)) {
+ err_code += perif.regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_ERROR);
} else {
err_code += 100; //Increment error code by 100 to indicate no lock
}
@@ -219,12 +221,12 @@ void x300_impl::self_cal_adc_capture_delay(mboard_members_t& mb, const size_t ra
perif.adc->set_test_word("ones", "ramp");
//Turn on the pattern checker in the FPGA. It will lock when it sees a zero
//and count deviations from the expected value
- perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
- perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 1);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
//10ms @ 200MHz = 2 million samples
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
- if (perif.misc_ins->read(radio_misc_ins_reg::ADC_CHECKER0_Q_LOCKED)) {
- err_code += perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER0_Q_ERROR);
+ if (perif.regmap->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_LOCKED)) {
+ err_code += perif.regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_ERROR);
} else {
err_code += 100; //Increment error code by 100 to indicate no lock
}
@@ -258,7 +260,7 @@ void x300_impl::self_cal_adc_capture_delay(mboard_members_t& mb, const size_t ra
}
}
perif.adc->set_test_word("normal", "normal");
- perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
if (win_start == -1) {
throw uhd::runtime_error("self_cal_adc_capture_delay: Self calibration failed. Convergence error.");
@@ -269,9 +271,9 @@ void x300_impl::self_cal_adc_capture_delay(mboard_members_t& mb, const size_t ra
}
boost::uint32_t ideal_tap = (win_stop + win_start) / 2;
- perif.misc_outs->write(radio_misc_outs_reg::ADC_DATA_DLY_VAL, ideal_tap);
- perif.misc_outs->write(radio_misc_outs_reg::ADC_DATA_DLY_STB, 1);
- perif.misc_outs->write(radio_misc_outs_reg::ADC_DATA_DLY_STB, 0);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, ideal_tap);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 1);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 0);
if (print_status) {
double tap_delay = (1.0e12 / mb.clock->get_master_clock_rate()) / (2*32); //in ps
@@ -300,7 +302,7 @@ double x300_impl::self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay
for (size_t i = 0; i < NUM_DELAY_STEPS; i++) {
//Delay the ADC clock (will set both Ch0 and Ch1 delays)
double delay = mb.clock->set_clock_delay(X300_CLOCK_WHICH_ADC0, delay_incr*i + delay_start);
- wait_for_clk_locked(mb.zpu_ctrl, ZPU_RB_CLK_STATUS_LMK_LOCK, 0.1);
+ wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, 0.1);
boost::uint32_t err_code = 0;
for (size_t r = 0; r < mboard_members_t::NUM_RADIOS; r++) {
@@ -312,12 +314,12 @@ double x300_impl::self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay
mb.radio_perifs[r].adc->set_test_word("ramp", "ones");
//Turn on the pattern checker in the FPGA. It will lock when it sees a zero
//and count deviations from the expected value
- mb.radio_perifs[r].misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
- mb.radio_perifs[r].misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 1);
+ mb.radio_perifs[r].regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+ mb.radio_perifs[r].regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
//50ms @ 200MHz = 10 million samples
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
- if (mb.radio_perifs[r].misc_ins->read(radio_misc_ins_reg::ADC_CHECKER1_I_LOCKED)) {
- err_code += mb.radio_perifs[r].misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_I_ERROR);
+ if (mb.radio_perifs[r].regmap->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_LOCKED)) {
+ err_code += mb.radio_perifs[r].regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_ERROR);
} else {
err_code += 100; //Increment error code by 100 to indicate no lock
}
@@ -327,12 +329,12 @@ double x300_impl::self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay
mb.radio_perifs[r].adc->set_test_word("ones", "ramp");
//Turn on the pattern checker in the FPGA. It will lock when it sees a zero
//and count deviations from the expected value
- mb.radio_perifs[r].misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
- mb.radio_perifs[r].misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 1);
+ mb.radio_perifs[r].regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+ mb.radio_perifs[r].regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
//50ms @ 200MHz = 10 million samples
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
- if (mb.radio_perifs[r].misc_ins->read(radio_misc_ins_reg::ADC_CHECKER1_Q_LOCKED)) {
- err_code += mb.radio_perifs[r].misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_Q_ERROR);
+ if (mb.radio_perifs[r].regmap->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_LOCKED)) {
+ err_code += mb.radio_perifs[r].regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_ERROR);
} else {
err_code += 100; //Increment error code by 100 to indicate no lock
}
@@ -392,7 +394,7 @@ double x300_impl::self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay
UHD_MSG(status) << "Validating..." << std::flush;
//Apply delay
win_center = mb.clock->set_clock_delay(X300_CLOCK_WHICH_ADC0, win_center); //Sets ADC0 and ADC1
- wait_for_clk_locked(mb.zpu_ctrl, ZPU_RB_CLK_STATUS_LMK_LOCK, 0.1);
+ wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, 0.1);
//Validate
self_test_adcs(mb, 2000);
} else {
@@ -403,7 +405,7 @@ double x300_impl::self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay
//Teardown
for (size_t r = 0; r < mboard_members_t::NUM_RADIOS; r++) {
mb.radio_perifs[r].adc->set_test_word("normal", "normal");
- mb.radio_perifs[r].misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
+ mb.radio_perifs[r].regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
}
UHD_MSG(status) << (boost::format(" done (FPGA->ADC=%.3fns%s, Window=%.3fns)\n") %
(win_center-fpga_clk_delay) % (cycle_slip?" +cyc":"") % win_length);
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index f0332691d..437fec82d 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -46,6 +46,7 @@ using namespace uhd;
using namespace uhd::usrp;
using namespace uhd::transport;
using namespace uhd::niusrprio;
+using namespace uhd::usrp::x300;
namespace asio = boost::asio;
/***********************************************************************
@@ -512,6 +513,9 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
this->check_fpga_compat(mb_path, mb);
this->check_fw_compat(mb_path, mb.zpu_ctrl);
+ mb.fw_regmap = boost::make_shared<fw_regmap_t>();
+ mb.fw_regmap->initialize(*mb.zpu_ctrl.get(), true);
+
//store which FPGA image is loaded
mb.loaded_fpga_image = get_fpga_option(mb.zpu_ctrl);
@@ -663,7 +667,6 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
UHD_MSG(status) << "Setup RF frontend clocking..." << std::endl;
//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*/,
mb.hw_rev,
@@ -842,7 +845,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
// and do the misc mboard sensors
////////////////////////////////////////////////////////////////////
_tree->create<sensor_value_t>(mb_path / "sensors" / "ref_locked")
- .publish(boost::bind(&x300_impl::get_ref_locked, this, mb.zpu_ctrl));
+ .publish(boost::bind(&x300_impl::get_ref_locked, this, mb));
////////////////////////////////////////////////////////////////////
// do some post-init tasks
@@ -860,6 +863,14 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
_tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(rx_fe_spec);
_tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(tx_fe_spec);
+ mb.regmap_db = boost::make_shared<uhd::soft_regmap_db_t>();
+ mb.regmap_db->add(*mb.fw_regmap);
+ mb.regmap_db->add(*mb.radio_perifs[0].regmap);
+ mb.regmap_db->add(*mb.radio_perifs[1].regmap);
+
+ _tree->create<uhd::soft_regmap_accessor_t::sptr>(mb_path / "registers")
+ .set(mb.regmap_db);
+
mb.initialization_done = true;
}
@@ -870,12 +881,12 @@ x300_impl::~x300_impl(void)
BOOST_FOREACH(mboard_members_t &mb, _mb)
{
//Disable/reset ADC/DAC
- mb.radio_perifs[0].misc_outs->set(radio_misc_outs_reg::ADC_RESET, 1);
- mb.radio_perifs[0].misc_outs->set(radio_misc_outs_reg::DAC_RESET_N, 0);
- mb.radio_perifs[0].misc_outs->set(radio_misc_outs_reg::DAC_ENABLED, 0);
- mb.radio_perifs[0].misc_outs->flush();
- mb.radio_perifs[1].misc_outs->set(radio_misc_outs_reg::DAC_ENABLED, 0);
- mb.radio_perifs[1].misc_outs->flush();
+ mb.radio_perifs[0].regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1);
+ mb.radio_perifs[0].regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0);
+ mb.radio_perifs[0].regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_ENABLED, 0);
+ mb.radio_perifs[0].regmap->misc_outs_reg.flush();
+ mb.radio_perifs[1].regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_ENABLED, 0);
+ mb.radio_perifs[1].regmap->misc_outs_reg.flush();
//kill the claimer task and unclaim the device
mb.claimer_task.reset();
@@ -913,21 +924,19 @@ void x300_impl::setup_radio(const size_t mb_i, const std::string &slot_name, con
both_xports_t xport = this->make_transport(mb_i, dest, X300_RADIO_DEST_PREFIX_CTRL, device_addr_t(), ctrl_sid);
perif.ctrl = radio_ctrl_core_3000::make(mb.if_pkt_is_big_endian, xport.recv, xport.send, ctrl_sid, slot_name);
- perif.misc_outs = boost::make_shared<radio_misc_outs_reg>();
- perif.misc_ins = boost::make_shared<radio_misc_ins_reg>();
- perif.misc_outs->initialize(*perif.ctrl, true);
- perif.misc_ins->initialize(*perif.ctrl);
+ perif.regmap = boost::make_shared<radio_regmap_t>(radio_index);
+ perif.regmap->initialize(*perif.ctrl, true);
//Only Radio0 has the ADC/DAC reset bits. Those bits are reserved for Radio1
if (radio_index == 0) {
- perif.misc_outs->set(radio_misc_outs_reg::ADC_RESET, 1);
- perif.misc_outs->set(radio_misc_outs_reg::DAC_RESET_N, 0);
- perif.misc_outs->flush();
- perif.misc_outs->set(radio_misc_outs_reg::ADC_RESET, 0);
- perif.misc_outs->set(radio_misc_outs_reg::DAC_RESET_N, 1);
- perif.misc_outs->flush();
+ perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1);
+ perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0);
+ perif.regmap->misc_outs_reg.flush();
+ perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 0);
+ perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 1);
+ perif.regmap->misc_outs_reg.flush();
}
- perif.misc_outs->write(radio_misc_outs_reg::DAC_ENABLED, 1);
+ perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_ENABLED, 1);
this->register_loopback_self_test(perif.ctrl);
@@ -1345,32 +1354,9 @@ void x300_impl::register_loopback_self_test(wb_iface::sptr iface)
* clock and time control logic
**********************************************************************/
-void x300_impl::update_clock_control(mboard_members_t &mb)
-{
- const size_t reg = mb.clock_control_regs_clock_source
- | (mb.clock_control_regs_pps_select << 2)
- | (mb.clock_control_regs_pps_out_enb << 4)
- | (mb.clock_control_regs_tcxo_enb << 5)
- | (mb.clock_control_regs_gpsdo_pwr << 6)
- ;
- mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_CLOCK_CTRL), reg);
-}
-
-void x300_impl::initialize_clock_control(mboard_members_t &mb)
-{
- //Initialize clock control register soft copies
- mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_INTERNAL;
- mb.clock_control_regs_pps_select = ZPU_SR_CLOCK_CTRL_PPS_SRC_INTERNAL;
- mb.clock_control_regs_pps_out_enb = 0;
- mb.clock_control_regs_tcxo_enb = 1;
- mb.clock_control_regs_gpsdo_pwr = 1; //GPSDO power always ON
- this->update_clock_control(mb);
-}
-
void x300_impl::set_time_source_out(mboard_members_t &mb, const bool enb)
{
- mb.clock_control_regs_pps_out_enb = enb? 1 : 0;
- this->update_clock_control(mb);
+ mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::fw_regmap_t::clk_ctrl_reg_t::PPS_OUT_EN, enb?1:0);
}
void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &source)
@@ -1381,19 +1367,19 @@ void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &sou
const bool reconfigure_clks = (mb.current_refclk_src != "internal") or (source != "internal");
if (reconfigure_clks) {
//Update the clock MUX on the motherboard to select the requested source
- mb.clock_control_regs_clock_source = 0;
- mb.clock_control_regs_tcxo_enb = 0;
if (source == "internal") {
- mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_INTERNAL;
- mb.clock_control_regs_tcxo_enb = 1;
+ mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, fw_regmap_t::clk_ctrl_reg_t::SRC_INTERNAL);
+ mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::TCXO_EN, 1);
} else if (source == "external") {
- mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_EXTERNAL;
+ mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, fw_regmap_t::clk_ctrl_reg_t::SRC_EXTERNAL);
+ mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::TCXO_EN, 0);
} else if (source == "gpsdo") {
- mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_GPSDO;
+ mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, fw_regmap_t::clk_ctrl_reg_t::SRC_GPSDO);
+ mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::TCXO_EN, 0);
} else {
throw uhd::key_error("update_clock_source: unknown source: " + source);
}
- this->update_clock_control(mb);
+ mb.fw_regmap->clock_ctrl_reg.flush();
//Reset the LMK to make sure it re-locks to the new reference
mb.clock->reset_clocks();
@@ -1408,7 +1394,7 @@ void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &sou
//The programming code in x300_clock_ctrl is not compatible with revs <= 4 and may
//lead to locking issues. So, disable the ref-locked check for older (unsupported) boards.
if (mb.hw_rev > 4) {
- if (not wait_for_clk_locked(mb.zpu_ctrl, ZPU_RB_CLK_STATUS_LMK_LOCK, timeout)) {
+ if (not wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, timeout)) {
//failed to lock on reference
if (mb.initialization_done) {
throw uhd::runtime_error((boost::format("Reference Clock PLL failed to lock to %s source.") % source).str());
@@ -1426,7 +1412,7 @@ void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &sou
mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), 0);
//Wait for radio clock PLL to lock
- if (not wait_for_clk_locked(mb.zpu_ctrl, ZPU_RB_CLK_STATUS_RADIO_CLK_LOCK, 0.01)) {
+ if (not wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::RADIO_CLK_LOCK, 0.01)) {
throw uhd::runtime_error((boost::format("Reference Clock PLL in FPGA failed to lock to %s source.") % source).str());
}
@@ -1435,20 +1421,20 @@ void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &sou
mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), 0);
//Wait for the ADC IDELAYCTRL to be ready
- if (not wait_for_clk_locked(mb.zpu_ctrl, ZPU_RB_CLK_STATUS_IDELAYCTRL_LOCK, 0.01)) {
+ if (not wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::IDELAYCTRL_LOCK, 0.01)) {
throw uhd::runtime_error((boost::format("ADC Calibration Clock in FPGA failed to lock to %s source.") % source).str());
}
// Reset ADCs and DACs
for (size_t r = 0; r < mboard_members_t::NUM_RADIOS; r++) {
radio_perifs_t &perif = mb.radio_perifs[r];
- if (perif.misc_outs && r==0) { //ADC/DAC reset lines only exist in Radio0
- perif.misc_outs->set(radio_misc_outs_reg::ADC_RESET, 1);
- perif.misc_outs->set(radio_misc_outs_reg::DAC_RESET_N, 0);
- perif.misc_outs->flush();
- perif.misc_outs->set(radio_misc_outs_reg::ADC_RESET, 0);
- perif.misc_outs->set(radio_misc_outs_reg::DAC_RESET_N, 1);
- perif.misc_outs->flush();
+ if (perif.regmap && r==0) { //ADC/DAC reset lines only exist in Radio0
+ perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1);
+ perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0);
+ perif.regmap->misc_outs_reg.flush();
+ perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 0);
+ perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 1);
+ perif.regmap->misc_outs_reg.flush();
}
if (perif.adc) perif.adc->reset();
if (perif.dac) perif.dac->reset();
@@ -1462,61 +1448,54 @@ void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &sou
void x300_impl::update_time_source(mboard_members_t &mb, const std::string &source)
{
if (source == "internal") {
- mb.clock_control_regs_pps_select = ZPU_SR_CLOCK_CTRL_PPS_SRC_INTERNAL;
+ mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, fw_regmap_t::clk_ctrl_reg_t::SRC_INTERNAL);
} else if (source == "external") {
- mb.clock_control_regs_pps_select = ZPU_SR_CLOCK_CTRL_PPS_SRC_EXTERNAL;
+ mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, fw_regmap_t::clk_ctrl_reg_t::SRC_EXTERNAL);
} else if (source == "gpsdo") {
- mb.clock_control_regs_pps_select = ZPU_SR_CLOCK_CTRL_PPS_SRC_GPSDO;
+ mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, fw_regmap_t::clk_ctrl_reg_t::SRC_GPSDO);
} else {
throw uhd::key_error("update_time_source: unknown source: " + source);
}
- this->update_clock_control(mb);
-
//check for valid pps
- if (!is_pps_present(mb.zpu_ctrl))
+ if (!is_pps_present(mb))
{
// TODO - Implement intelligent PPS detection
/* throw uhd::runtime_error((boost::format("The %d PPS was not detected. Please check the PPS source and try again.") % source).str()); */
}
}
-static bool get_clk_locked(wb_iface::sptr ctrl, boost::uint32_t which)
-{
- return (ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_CLK_STATUS)) & which) != 0;
-}
-
-bool x300_impl::wait_for_clk_locked(wb_iface::sptr ctrl, boost::uint32_t which, double timeout)
+bool x300_impl::wait_for_clk_locked(mboard_members_t& mb, boost::uint32_t which, double timeout)
{
boost::system_time timeout_time = boost::get_system_time() + boost::posix_time::milliseconds(timeout * 1000.0);
do {
- if (get_clk_locked(ctrl, which))
+ if (mb.fw_regmap->clock_status_reg.read(which)==1)
return true;
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
} while (boost::get_system_time() < timeout_time);
//Check one last time
- return get_clk_locked(ctrl, which);
+ return (mb.fw_regmap->clock_status_reg.read(which)==1);
}
-sensor_value_t x300_impl::get_ref_locked(wb_iface::sptr ctrl)
+sensor_value_t x300_impl::get_ref_locked(mboard_members_t& mb)
{
- const bool lock = get_clk_locked(ctrl, ZPU_RB_CLK_STATUS_LMK_LOCK) &&
- get_clk_locked(ctrl, ZPU_RB_CLK_STATUS_RADIO_CLK_LOCK) &&
- get_clk_locked(ctrl, ZPU_RB_CLK_STATUS_IDELAYCTRL_LOCK);
+ mb.fw_regmap->clock_status_reg.refresh();
+ const bool lock = (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::LMK_LOCK)==1) &&
+ (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::RADIO_CLK_LOCK)==1) &&
+ (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::IDELAYCTRL_LOCK)==1);
return sensor_value_t("Ref", lock, "locked", "unlocked");
}
-bool x300_impl::is_pps_present(wb_iface::sptr ctrl)
+bool x300_impl::is_pps_present(mboard_members_t& mb)
{
// The ZPU_RB_CLK_STATUS_PPS_DETECT bit toggles with each rising edge of the PPS.
// We monitor it for up to 1.5 seconds looking for it to toggle.
- boost::uint32_t pps_detect = ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_CLK_STATUS)) & ZPU_RB_CLK_STATUS_PPS_DETECT;
+ boost::uint32_t pps_detect = mb.fw_regmap->clock_status_reg.read(fw_regmap_t::clk_status_reg_t::PPS_DETECT);
for (int i = 0; i < 15; i++)
{
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
- boost::uint32_t clk_status = ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_CLK_STATUS));
- if (pps_detect != (clk_status & ZPU_RB_CLK_STATUS_PPS_DETECT))
+ if (pps_detect != mb.fw_regmap->clock_status_reg.read(fw_regmap_t::clk_status_reg_t::PPS_DETECT))
return true;
}
return false;
diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp
index 20cd4d754..78c497ad9 100644
--- a/host/lib/usrp/x300/x300_impl.hpp
+++ b/host/lib/usrp/x300/x300_impl.hpp
@@ -49,7 +49,6 @@
#include <uhd/transport/nirio/niusrprio_session.h>
#include <uhd/transport/vrt_if_packet.hpp>
#include "recv_packet_demuxer_3000.hpp"
-#include <uhd/utils/soft_register.hpp>
#include "x300_regs.hpp"
static const std::string X300_FW_FILE_NAME = "usrp_x300_fw.bin";
@@ -173,39 +172,6 @@ public:
private:
boost::shared_ptr<async_md_type> _async_md;
- class radio_misc_outs_reg : public uhd::soft_reg32_wo_t {
- public:
- UHD_DEFINE_SOFT_REG_FIELD(DAC_ENABLED, /*width*/ 1, /*shift*/ 0); //[0]
- UHD_DEFINE_SOFT_REG_FIELD(DAC_RESET_N, /*width*/ 1, /*shift*/ 1); //[1]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_RESET, /*width*/ 1, /*shift*/ 2); //[2]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_STB, /*width*/ 1, /*shift*/ 3); //[3]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_VAL, /*width*/ 5, /*shift*/ 4); //[8:4]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER_ENABLED, /*width*/ 1, /*shift*/ 9); //[9]
-
- radio_misc_outs_reg(): uhd::soft_reg32_wo_t(TOREG(SR_MISC_OUTS)) {
- //Initial values
- set(DAC_ENABLED, 0);
- set(DAC_RESET_N, 0);
- set(ADC_RESET, 0);
- set(ADC_DATA_DLY_STB, 0);
- set(ADC_DATA_DLY_VAL, 16);
- set(ADC_CHECKER_ENABLED, 0);
- }
- };
- class radio_misc_ins_reg : public uhd::soft_reg32_ro_t {
- public:
- UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_Q_LOCKED, /*width*/ 1, /*shift*/ 0); //[0]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_I_LOCKED, /*width*/ 1, /*shift*/ 1); //[1]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_Q_LOCKED, /*width*/ 1, /*shift*/ 2); //[2]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_I_LOCKED, /*width*/ 1, /*shift*/ 3); //[3]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_Q_ERROR, /*width*/ 1, /*shift*/ 4); //[4]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_I_ERROR, /*width*/ 1, /*shift*/ 5); //[5]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_Q_ERROR, /*width*/ 1, /*shift*/ 6); //[6]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_I_ERROR, /*width*/ 1, /*shift*/ 7); //[7]
-
- radio_misc_ins_reg(): uhd::soft_reg32_ro_t(RB32_MISC_INS) { }
- };
-
//perifs in the radio core
struct radio_perifs_t
{
@@ -223,8 +189,7 @@ private:
rx_frontend_core_200::sptr rx_fe;
tx_frontend_core_200::sptr tx_fe;
//Registers
- radio_misc_outs_reg::sptr misc_outs;
- radio_misc_ins_reg::sptr misc_ins;
+ uhd::usrp::x300::radio_regmap_t::sptr regmap;
};
//overflow recovery impl
@@ -266,18 +231,15 @@ private:
uhd::gps_ctrl::sptr gps;
gpio_core_200::sptr fp_gpio;
- //clock control register bits
- int clock_control_regs_clock_source;
- int clock_control_regs_pps_select;
- int clock_control_regs_pps_out_enb;
- int clock_control_regs_tcxo_enb;
- int clock_control_regs_gpsdo_pwr;
+ uhd::usrp::x300::fw_regmap_t::sptr fw_regmap;
//which FPGA image is loaded
std::string loaded_fpga_image;
size_t hw_rev;
std::string current_refclk_src;
+
+ uhd::soft_regmap_db_t::sptr regmap_db;
};
std::vector<mboard_members_t> _mb;
@@ -391,9 +353,9 @@ private:
void update_clock_source(mboard_members_t&, const std::string &);
void update_time_source(mboard_members_t&, const std::string &);
- uhd::sensor_value_t get_ref_locked(uhd::wb_iface::sptr);
- bool wait_for_clk_locked(uhd::wb_iface::sptr, boost::uint32_t which, double timeout);
- bool is_pps_present(uhd::wb_iface::sptr);
+ uhd::sensor_value_t get_ref_locked(mboard_members_t& mb);
+ bool wait_for_clk_locked(mboard_members_t& mb, boost::uint32_t which, double timeout);
+ bool is_pps_present(mboard_members_t& mb);
void set_db_eeprom(uhd::i2c_iface::sptr i2c, const size_t, const uhd::usrp::dboard_eeprom_t &);
void set_mb_eeprom(uhd::i2c_iface::sptr i2c, const uhd::usrp::mboard_eeprom_t &);
diff --git a/host/lib/usrp/x300/x300_regs.hpp b/host/lib/usrp/x300/x300_regs.hpp
index 6e92a6dbc..350845f28 100644
--- a/host/lib/usrp/x300/x300_regs.hpp
+++ b/host/lib/usrp/x300/x300_regs.hpp
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <boost/cstdint.hpp>
+#include <uhd/utils/soft_register.hpp>
#define TOREG(x) ((x)*4)
@@ -76,28 +77,12 @@ localparam ZPU_SR_ETHINT1 = 56;
#define ZPU_SR_SW_RST_RADIO_CLK_PLL (1<<2)
#define ZPU_SR_SW_RST_ADC_IDELAYCTRL (1<<3)
-//clock controls
-#define ZPU_SR_CLOCK_CTRL_CLK_SRC_EXTERNAL 0x00
-#define ZPU_SR_CLOCK_CTRL_CLK_SRC_INTERNAL 0x02
-#define ZPU_SR_CLOCK_CTRL_CLK_SRC_GPSDO 0x03
-#define ZPU_SR_CLOCK_CTRL_PPS_SRC_EXTERNAL 0x00
-#define ZPU_SR_CLOCK_CTRL_PPS_SRC_INTERNAL 0x02
-#define ZPU_SR_CLOCK_CTRL_PPS_SRC_GPSDO 0x03
-
localparam ZPU_RB_SPI = 2;
localparam ZPU_RB_CLK_STATUS = 3;
localparam ZPU_RB_COMPAT_NUM = 6;
localparam ZPU_RB_ETH_TYPE0 = 4;
localparam ZPU_RB_ETH_TYPE1 = 5;
-//clock status
-#define ZPU_RB_CLK_STATUS_LMK_STATUS (0x3 << 0)
-#define ZPU_RB_CLK_STATUS_LMK_LOCK (0x1 << 2)
-#define ZPU_RB_CLK_STATUS_LMK_HOLDOVER (0x1 << 3)
-#define ZPU_RB_CLK_STATUS_PPS_DETECT (0x1 << 4)
-#define ZPU_RB_CLK_STATUS_RADIO_CLK_LOCK (0x1 << 5)
-#define ZPU_RB_CLK_STATUS_IDELAYCTRL_LOCK (0x1 << 6)
-
//spi slaves on radio
#define DB_DAC_SEN (1 << 7)
#define DB_ADC_SEN (1 << 6)
@@ -202,5 +187,97 @@ static const uint32_t PCIE_ZPU_READ_CLOBBER = 0x80000000;
static const uint32_t PCIE_ZPU_STATUS_BUSY = 0x1;
static const uint32_t PCIE_ZPU_STATUS_SUSPENDED = 0x80000000;
+//-------------------------------------------------------------------
+// Register Maps
+//-------------------------------------------------------------------
+namespace uhd { namespace usrp { namespace x300 {
+ class fw_regmap_t : public uhd::soft_regmap_t {
+ public:
+ typedef boost::shared_ptr<fw_regmap_t> sptr;
+
+ class clk_ctrl_reg_t : public uhd::soft_reg32_wo_t {
+ public:
+ UHD_DEFINE_SOFT_REG_FIELD(CLK_SOURCE, /*width*/ 2, /*shift*/ 0); //[1:0]
+ UHD_DEFINE_SOFT_REG_FIELD(PPS_SELECT, /*width*/ 2, /*shift*/ 2); //[3:2]
+ UHD_DEFINE_SOFT_REG_FIELD(PPS_OUT_EN, /*width*/ 1, /*shift*/ 4); //[4]
+ UHD_DEFINE_SOFT_REG_FIELD(TCXO_EN, /*width*/ 1, /*shift*/ 5); //[5]
+ UHD_DEFINE_SOFT_REG_FIELD(GPSDO_PWR_EN, /*width*/ 1, /*shift*/ 6); //[6]
+
+ static const boost::uint32_t SRC_EXTERNAL = 0x0;
+ static const boost::uint32_t SRC_INTERNAL = 0x2;
+ static const boost::uint32_t SRC_GPSDO = 0x3;
+
+ clk_ctrl_reg_t(): uhd::soft_reg32_wo_t(SR_ADDR(SET0_BASE, ZPU_SR_CLOCK_CTRL)) {
+ //Initial values
+ set(CLK_SOURCE, SRC_INTERNAL);
+ set(PPS_SELECT, SRC_INTERNAL);
+ set(PPS_OUT_EN, 0);
+ set(TCXO_EN, 1);
+ set(GPSDO_PWR_EN, 1); //GPSDO power always ON
+ }
+ } clock_ctrl_reg;
+
+ class clk_status_reg_t : public uhd::soft_reg32_ro_t {
+ public:
+ UHD_DEFINE_SOFT_REG_FIELD(LMK_STATUS, /*width*/ 2, /*shift*/ 0); //[1:0]
+ UHD_DEFINE_SOFT_REG_FIELD(LMK_LOCK, /*width*/ 1, /*shift*/ 2); //[2]
+ UHD_DEFINE_SOFT_REG_FIELD(LMK_HOLDOVER, /*width*/ 1, /*shift*/ 3); //[3]
+ UHD_DEFINE_SOFT_REG_FIELD(PPS_DETECT, /*width*/ 1, /*shift*/ 4); //[4]
+ UHD_DEFINE_SOFT_REG_FIELD(RADIO_CLK_LOCK, /*width*/ 1, /*shift*/ 5); //[5]
+ UHD_DEFINE_SOFT_REG_FIELD(IDELAYCTRL_LOCK, /*width*/ 1, /*shift*/ 6); //[6]
+
+ clk_status_reg_t(): uhd::soft_reg32_ro_t(SR_ADDR(SET0_BASE, ZPU_RB_CLK_STATUS)) {}
+ } clock_status_reg;
+
+ fw_regmap_t() : soft_regmap_t("fw_regmap") {
+ add_to_map(clock_ctrl_reg, "clock_ctrl_reg", PUBLIC);
+ add_to_map(clock_status_reg, "clock_status_reg", PUBLIC);
+ }
+ };
+
+ class radio_regmap_t : public uhd::soft_regmap_t {
+ public:
+ typedef boost::shared_ptr<radio_regmap_t> sptr;
+ class misc_outs_reg_t : public uhd::soft_reg32_wo_t {
+ public:
+ UHD_DEFINE_SOFT_REG_FIELD(DAC_ENABLED, /*width*/ 1, /*shift*/ 0); //[0]
+ UHD_DEFINE_SOFT_REG_FIELD(DAC_RESET_N, /*width*/ 1, /*shift*/ 1); //[1]
+ UHD_DEFINE_SOFT_REG_FIELD(ADC_RESET, /*width*/ 1, /*shift*/ 2); //[2]
+ UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_STB, /*width*/ 1, /*shift*/ 3); //[3]
+ UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_VAL, /*width*/ 5, /*shift*/ 4); //[8:4]
+ UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER_ENABLED, /*width*/ 1, /*shift*/ 9); //[9]
+
+ misc_outs_reg_t(): uhd::soft_reg32_wo_t(TOREG(SR_MISC_OUTS)) {
+ //Initial values
+ set(DAC_ENABLED, 0);
+ set(DAC_RESET_N, 0);
+ set(ADC_RESET, 0);
+ set(ADC_DATA_DLY_STB, 0);
+ set(ADC_DATA_DLY_VAL, 16);
+ set(ADC_CHECKER_ENABLED, 0);
+ }
+ } misc_outs_reg;
+
+ class misc_ins_reg_t : public uhd::soft_reg32_ro_t {
+ public:
+ UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_Q_LOCKED, /*width*/ 1, /*shift*/ 0); //[0]
+ UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_I_LOCKED, /*width*/ 1, /*shift*/ 1); //[1]
+ UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_Q_LOCKED, /*width*/ 1, /*shift*/ 2); //[2]
+ UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_I_LOCKED, /*width*/ 1, /*shift*/ 3); //[3]
+ UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_Q_ERROR, /*width*/ 1, /*shift*/ 4); //[4]
+ UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_I_ERROR, /*width*/ 1, /*shift*/ 5); //[5]
+ UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_Q_ERROR, /*width*/ 1, /*shift*/ 6); //[6]
+ UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_I_ERROR, /*width*/ 1, /*shift*/ 7); //[7]
+
+ misc_ins_reg_t(): uhd::soft_reg32_ro_t(RB32_MISC_INS) { }
+ } misc_ins_reg;
+
+ radio_regmap_t(int radio_num) : soft_regmap_t("radio" + boost::lexical_cast<std::string>(radio_num) + "_regmap") {
+ add_to_map(misc_outs_reg, "misc_outs_reg", PUBLIC);
+ add_to_map(misc_ins_reg, "misc_ins_reg", PUBLIC);
+ }
+ };
+
+}}}
#endif /* INCLUDED_X300_REGS_HPP */