aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp70
-rw-r--r--host/lib/usrp/b200/b200_impl.hpp13
-rw-r--r--host/lib/usrp/b200/b200_io_impl.cpp1
-rw-r--r--host/lib/usrp/common/ad9361_ctrl.hpp6
-rw-r--r--host/lib/usrp/common/ad9361_driver/ad9361_device.cpp5
-rw-r--r--host/lib/usrp/common/ad9361_driver/ad9361_device.h1
-rw-r--r--host/lib/usrp/cores/CMakeLists.txt2
-rw-r--r--host/lib/usrp/cores/dma_fifo_core_3000.cpp397
-rw-r--r--host/lib/usrp/cores/dma_fifo_core_3000.hpp86
-rw-r--r--host/lib/usrp/cores/gpio_atr_3000.cpp297
-rw-r--r--host/lib/usrp/cores/gpio_atr_3000.hpp175
-rw-r--r--host/lib/usrp/cores/gpio_core_200.cpp24
-rw-r--r--host/lib/usrp/cores/gpio_core_200.hpp23
-rw-r--r--host/lib/usrp/cores/tx_vita_core_3000.cpp59
-rw-r--r--host/lib/usrp/cores/tx_vita_core_3000.hpp14
-rw-r--r--host/lib/usrp/dboard/db_rfx.cpp34
-rw-r--r--host/lib/usrp/dboard/db_sbx_common.cpp62
-rw-r--r--host/lib/usrp/dboard/db_ubx.cpp79
-rw-r--r--host/lib/usrp/dboard/db_wbx_simple.cpp36
-rw-r--r--host/lib/usrp/dboard/db_wbx_version2.cpp18
-rw-r--r--host/lib/usrp/dboard/db_wbx_version3.cpp20
-rw-r--r--host/lib/usrp/dboard/db_wbx_version4.cpp20
-rw-r--r--host/lib/usrp/dboard/db_xcvr2450.cpp22
-rw-r--r--host/lib/usrp/e300/e300_fpga_defs.hpp2
-rw-r--r--host/lib/usrp/e300/e300_impl.cpp52
-rw-r--r--host/lib/usrp/e300/e300_impl.hpp12
-rw-r--r--host/lib/usrp/e300/e300_io_impl.cpp1
-rw-r--r--host/lib/usrp/multi_usrp.cpp20
-rw-r--r--host/lib/usrp/usrp1/dboard_iface.cpp1
-rw-r--r--host/lib/usrp/x300/x300_fw_common.h2
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp116
-rw-r--r--host/lib/usrp/x300/x300_impl.hpp24
-rw-r--r--host/lib/usrp/x300/x300_io_impl.cpp10
-rw-r--r--host/lib/usrp/x300/x300_regs.hpp4
34 files changed, 1319 insertions, 389 deletions
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index ffce08567..3aaf28ab3 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -41,6 +41,7 @@
using namespace uhd;
using namespace uhd::usrp;
+using namespace uhd::usrp::gpio_atr;
using namespace uhd::transport;
static const boost::posix_time::milliseconds REENUMERATION_TIMEOUT_MS(3000);
@@ -656,15 +657,15 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
////////////////////////////////////////////////////////////////////
// front panel gpio
////////////////////////////////////////////////////////////////////
- _radio_perifs[0].fp_gpio = gpio_core_200::make(_radio_perifs[0].ctrl, TOREG(SR_FP_GPIO), RB32_FP_GPIO);
+ _radio_perifs[0].fp_gpio = gpio_atr_3000::make(_radio_perifs[0].ctrl, TOREG(SR_FP_GPIO), RB32_FP_GPIO);
BOOST_FOREACH(const gpio_attr_map_t::value_type attr, gpio_attr_map)
{
_tree->create<boost::uint32_t>(mb_path / "gpio" / "FP0" / attr.second)
.set(0)
- .subscribe(boost::bind(&b200_impl::set_fp_gpio, this, _radio_perifs[0].fp_gpio, attr.first, _1));
+ .subscribe(boost::bind(&gpio_atr_3000::set_gpio_attr, _radio_perifs[0].fp_gpio, attr.first, _1));
}
_tree->create<boost::uint32_t>(mb_path / "gpio" / "FP0" / "READBACK")
- .publish(boost::bind(&b200_impl::get_fp_gpio, this, _radio_perifs[0].fp_gpio));
+ .publish(boost::bind(&gpio_atr_3000::read_gpio, _radio_perifs[0].fp_gpio));
////////////////////////////////////////////////////////////////////
// dboard eeproms but not really
@@ -677,10 +678,14 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
////////////////////////////////////////////////////////////////////
// do some post-init tasks
////////////////////////////////////////////////////////////////////
-
- //init the clock rate to something reasonable
- double default_tick_rate = device_addr.cast<double>("master_clock_rate", ad936x_manager::DEFAULT_TICK_RATE);
+ // Init the clock rate and the auto mcr appropriately
+ if (not device_addr.has_key("master_clock_rate")) {
+ UHD_MSG(status) << "Setting master clock rate selection to 'automatic'." << std::endl;
+ }
+ // We can automatically choose a master clock rate, but not if the user specifies one
+ const double default_tick_rate = device_addr.cast<double>("master_clock_rate", ad936x_manager::DEFAULT_TICK_RATE);
_tree->access<double>(mb_path / "tick_rate").set(default_tick_rate);
+ _tree->access<bool>(mb_path / "auto_tick_rate").set(not device_addr.has_key("master_clock_rate"));
//subdev spec contains full width of selections
subdev_spec_t rx_spec, tx_spec;
@@ -704,12 +709,6 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
_radio_perifs[i].ddc->set_host_rate(default_tick_rate / ad936x_manager::DEFAULT_DECIM);
_radio_perifs[i].duc->set_host_rate(default_tick_rate / ad936x_manager::DEFAULT_INTERP);
}
- // We can automatically choose a master clock rate, but not if the user specifies one
- _tree->access<bool>(mb_path / "auto_tick_rate").set(not device_addr.has_key("master_clock_rate"));
- if (not device_addr.has_key("master_clock_rate")) {
- UHD_MSG(status) << "Setting master clock rate selection to 'automatic'." << std::endl;
- }
-
}
b200_impl::~b200_impl(void)
@@ -753,14 +752,15 @@ void b200_impl::setup_radio(const size_t dspno)
////////////////////////////////////////////////////////////////////
// Set up peripherals
////////////////////////////////////////////////////////////////////
- perif.atr = gpio_core_200_32wo::make(perif.ctrl, TOREG(SR_ATR));
+ perif.atr = gpio_atr_3000::make_write_only(perif.ctrl, TOREG(SR_ATR));
+ perif.atr->set_atr_mode(MODE_ATR, 0xFFFFFFFF);
// create rx dsp control objects
perif.framer = rx_vita_core_3000::make(perif.ctrl, TOREG(SR_RX_CTRL));
perif.ddc = rx_dsp_core_3000::make(perif.ctrl, TOREG(SR_RX_DSP), true /*is_b200?*/);
perif.ddc->set_link_rate(10e9/8); //whatever
perif.ddc->set_mux("IQ", false, dspno == 1 ? true : false, dspno == 1 ? true : false);
perif.ddc->set_freq(rx_dsp_core_3000::DEFAULT_CORDIC_FREQ);
- perif.deframer = tx_vita_core_3000::make(perif.ctrl, TOREG(SR_TX_CTRL));
+ perif.deframer = tx_vita_core_3000::make_no_radio_buff(perif.ctrl, TOREG(SR_TX_CTRL));
perif.duc = tx_dsp_core_3000::make(perif.ctrl, TOREG(SR_TX_DSP));
perif.duc->set_link_rate(10e9/8); //whatever
perif.duc->set_freq(tx_dsp_core_3000::DEFAULT_CORDIC_FREQ);
@@ -792,7 +792,6 @@ void b200_impl::setup_radio(const size_t dspno)
// create tx dsp control objects
////////////////////////////////////////////////////////////////////
_tree->access<double>(mb_path / "tick_rate")
- .subscribe(boost::bind(&tx_vita_core_3000::set_tick_rate, perif.deframer, _1))
.subscribe(boost::bind(&tx_dsp_core_3000::set_tick_rate, perif.duc, _1));
const fs_path tx_dsp_path = mb_path / "tx_dsps" / dspno;
perif.duc->populate_subtree(_tree->subtree(tx_dsp_path));
@@ -964,27 +963,6 @@ void b200_impl::set_mb_eeprom(const uhd::usrp::mboard_eeprom_t &mb_eeprom)
mb_eeprom.commit(*_iface, "B200");
}
-
-boost::uint32_t b200_impl::get_fp_gpio(gpio_core_200::sptr gpio)
-{
- return boost::uint32_t(gpio->read_gpio(dboard_iface::UNIT_RX));
-}
-
-void b200_impl::set_fp_gpio(gpio_core_200::sptr gpio, const gpio_attr_t attr, const boost::uint32_t value)
-{
- switch (attr)
- {
- case GPIO_CTRL: return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value);
- case GPIO_DDR: return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value);
- case GPIO_OUT: return gpio->set_gpio_out(dboard_iface::UNIT_RX, value);
- case GPIO_ATR_0X: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value);
- case GPIO_ATR_RX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value);
- case GPIO_ATR_TX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value);
- case GPIO_ATR_XX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value);
- default: UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
/***********************************************************************
* Reference time and clock
**********************************************************************/
@@ -1154,11 +1132,11 @@ void b200_impl::update_atrs(void)
if (enb_rx and enb_tx) fd = STATE_FDX1_TXRX;
if (enb_rx and not enb_tx) fd = rxonly;
if (not enb_rx and enb_tx) fd = txonly;
- gpio_core_200_32wo::sptr atr = perif.atr;
- atr->set_atr_reg(dboard_iface::ATR_REG_IDLE, STATE_OFF);
- atr->set_atr_reg(dboard_iface::ATR_REG_RX_ONLY, rxonly);
- atr->set_atr_reg(dboard_iface::ATR_REG_TX_ONLY, txonly);
- atr->set_atr_reg(dboard_iface::ATR_REG_FULL_DUPLEX, fd);
+ gpio_atr_3000::sptr atr = perif.atr;
+ atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF);
+ atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly);
+ atr->set_atr_reg(ATR_REG_TX_ONLY, txonly);
+ atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd);
}
if (_radio_perifs.size() > _fe2 and _radio_perifs[_fe2].atr)
{
@@ -1172,11 +1150,11 @@ void b200_impl::update_atrs(void)
if (enb_rx and enb_tx) fd = STATE_FDX2_TXRX;
if (enb_rx and not enb_tx) fd = rxonly;
if (not enb_rx and enb_tx) fd = txonly;
- gpio_core_200_32wo::sptr atr = perif.atr;
- atr->set_atr_reg(dboard_iface::ATR_REG_IDLE, STATE_OFF);
- atr->set_atr_reg(dboard_iface::ATR_REG_RX_ONLY, rxonly);
- atr->set_atr_reg(dboard_iface::ATR_REG_TX_ONLY, txonly);
- atr->set_atr_reg(dboard_iface::ATR_REG_FULL_DUPLEX, fd);
+ gpio_atr_3000::sptr atr = perif.atr;
+ atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF);
+ atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly);
+ atr->set_atr_reg(ATR_REG_TX_ONLY, txonly);
+ atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd);
}
}
diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp
index 25fef7d4b..b406572fb 100644
--- a/host/lib/usrp/b200/b200_impl.hpp
+++ b/host/lib/usrp/b200/b200_impl.hpp
@@ -27,7 +27,7 @@
#include "rx_vita_core_3000.hpp"
#include "tx_vita_core_3000.hpp"
#include "time_core_3000.hpp"
-#include "gpio_core_200.hpp"
+#include "gpio_atr_3000.hpp"
#include "radio_ctrl_core_3000.hpp"
#include "rx_dsp_core_3000.hpp"
#include "tx_dsp_core_3000.hpp"
@@ -49,8 +49,8 @@
#include "recv_packet_demuxer_3000.hpp"
static const boost::uint8_t B200_FW_COMPAT_NUM_MAJOR = 8;
static const boost::uint8_t B200_FW_COMPAT_NUM_MINOR = 0;
-static const boost::uint16_t B200_FPGA_COMPAT_NUM = 11;
-static const boost::uint16_t B205_FPGA_COMPAT_NUM = 2;
+static const boost::uint16_t B200_FPGA_COMPAT_NUM = 12;
+static const boost::uint16_t B205_FPGA_COMPAT_NUM = 3;
static const double B200_BUS_CLOCK_RATE = 100e6;
static const boost::uint32_t B200_GPSDO_ST_NONE = 0x83;
static const size_t B200_MAX_RATE_USB2 = 53248000; // bytes/s
@@ -177,8 +177,8 @@ private:
struct radio_perifs_t
{
radio_ctrl_core_3000::sptr ctrl;
- gpio_core_200_32wo::sptr atr;
- gpio_core_200::sptr fp_gpio;
+ uhd::usrp::gpio_atr::gpio_atr_3000::sptr atr;
+ uhd::usrp::gpio_atr::gpio_atr_3000::sptr fp_gpio;
time_core_3000::sptr time64;
rx_vita_core_3000::sptr framer;
rx_dsp_core_3000::sptr ddc;
@@ -226,9 +226,6 @@ private:
void update_enables(void);
void update_atrs(void);
- boost::uint32_t get_fp_gpio(gpio_core_200::sptr);
- void set_fp_gpio(gpio_core_200::sptr, const gpio_attr_t, const boost::uint32_t);
-
double _tick_rate;
double get_tick_rate(void){return _tick_rate;}
double set_tick_rate(const double rate);
diff --git a/host/lib/usrp/b200/b200_io_impl.cpp b/host/lib/usrp/b200/b200_io_impl.cpp
index 7fcd04823..41b4b8a74 100644
--- a/host/lib/usrp/b200/b200_io_impl.cpp
+++ b/host/lib/usrp/b200/b200_io_impl.cpp
@@ -159,7 +159,6 @@ void b200_impl::update_tick_rate(const double new_tick_rate)
boost::shared_ptr<sph::send_packet_streamer> my_streamer =
boost::dynamic_pointer_cast<sph::send_packet_streamer>(perif.tx_streamer.lock());
if (my_streamer) my_streamer->set_tick_rate(new_tick_rate);
- perif.deframer->set_tick_rate(new_tick_rate);
}
}
diff --git a/host/lib/usrp/common/ad9361_ctrl.hpp b/host/lib/usrp/common/ad9361_ctrl.hpp
index 5c438ee9c..8cd75d539 100644
--- a/host/lib/usrp/common/ad9361_ctrl.hpp
+++ b/host/lib/usrp/common/ad9361_ctrl.hpp
@@ -89,8 +89,10 @@ public:
//! get the clock rate range for the frontend
static uhd::meta_range_t get_clock_rate_range(void)
{
- //return uhd::meta_range_t(220e3, 61.44e6);
- return uhd::meta_range_t(5e6, ad9361_device_t::AD9361_MAX_CLOCK_RATE); //5 MHz DCM low end
+ return uhd::meta_range_t(
+ ad9361_device_t::AD9361_MIN_CLOCK_RATE,
+ ad9361_device_t::AD9361_MAX_CLOCK_RATE
+ );
}
//! set the filter bandwidth for the frontend's analog low pass
diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp
index 0a8a61575..bb25379c0 100644
--- a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp
+++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp
@@ -91,6 +91,7 @@ int get_num_taps(int max_num_taps) {
}
const double ad9361_device_t::AD9361_MAX_GAIN = 89.75;
+const double ad9361_device_t::AD9361_MIN_CLOCK_RATE = 220e3;
const double ad9361_device_t::AD9361_MAX_CLOCK_RATE = 61.44e6;
const double ad9361_device_t::AD9361_CAL_VALID_WINDOW = 100e6;
// Max bandwdith is due to filter rolloff in analog filter stage
@@ -770,7 +771,7 @@ void ad9361_device_t::_calibrate_rf_dc_offset()
size_t count = 0;
_io_iface->poke8(0x016, 0x02);
while (_io_iface->peek8(0x016) & 0x02) {
- if (count > 100) {
+ if (count > 200) {
throw uhd::runtime_error("[ad9361_device_t] RF DC Offset Calibration Failure");
break;
}
@@ -821,7 +822,7 @@ void ad9361_device_t::_calibrate_rx_quadrature()
size_t count = 0;
_io_iface->poke8(0x016, 0x20);
while (_io_iface->peek8(0x016) & 0x20) {
- if (count > 100) {
+ if (count > 1000) {
throw uhd::runtime_error("[ad9361_device_t] Rx Quadrature Calibration Failure");
break;
}
diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.h b/host/lib/usrp/common/ad9361_driver/ad9361_device.h
index 66bc2e8b9..73b1d9a35 100644
--- a/host/lib/usrp/common/ad9361_driver/ad9361_device.h
+++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.h
@@ -157,6 +157,7 @@ public:
//Constants
static const double AD9361_MAX_GAIN;
static const double AD9361_MAX_CLOCK_RATE;
+ static const double AD9361_MIN_CLOCK_RATE;
static const double AD9361_CAL_VALID_WINDOW;
static const double AD9361_RECOMMENDED_MAX_BANDWIDTH;
static const double DEFAULT_RX_FREQ;
diff --git a/host/lib/usrp/cores/CMakeLists.txt b/host/lib/usrp/cores/CMakeLists.txt
index f28ae040f..7a0f6cc93 100644
--- a/host/lib/usrp/cores/CMakeLists.txt
+++ b/host/lib/usrp/cores/CMakeLists.txt
@@ -40,4 +40,6 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/rx_dsp_core_3000.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tx_dsp_core_3000.cpp
${CMAKE_CURRENT_SOURCE_DIR}/radio_ctrl_core_3000.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/gpio_atr_3000.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/dma_fifo_core_3000.cpp
)
diff --git a/host/lib/usrp/cores/dma_fifo_core_3000.cpp b/host/lib/usrp/cores/dma_fifo_core_3000.cpp
new file mode 100644
index 000000000..1a9d5dd5c
--- /dev/null
+++ b/host/lib/usrp/cores/dma_fifo_core_3000.cpp
@@ -0,0 +1,397 @@
+//
+// Copyright 2015 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "dma_fifo_core_3000.hpp"
+#include <uhd/exception.hpp>
+#include <boost/thread/thread.hpp> //sleep
+#include <uhd/utils/soft_register.hpp>
+#include <uhd/utils/msg.hpp>
+
+using namespace uhd;
+
+#define SR_DRAM_BIST_BASE 16
+
+dma_fifo_core_3000::~dma_fifo_core_3000(void) {
+ /* NOP */
+}
+
+class dma_fifo_core_3000_impl : public dma_fifo_core_3000
+{
+protected:
+ class rb_addr_reg_t : public soft_reg32_wo_t {
+ public:
+ UHD_DEFINE_SOFT_REG_FIELD(ADDR, /*width*/ 3, /*shift*/ 0); //[2:0]
+
+ static const boost::uint32_t RB_FIFO_STATUS = 0;
+ static const boost::uint32_t RB_BIST_STATUS = 1;
+ static const boost::uint32_t RB_BIST_XFER_CNT = 2;
+ static const boost::uint32_t RB_BIST_CYC_CNT = 3;
+
+ rb_addr_reg_t(boost::uint32_t base):
+ soft_reg32_wo_t(base + 0)
+ {
+ //Initial values
+ set(ADDR, RB_FIFO_STATUS);
+ }
+ };
+
+ class fifo_ctrl_reg_t : public soft_reg32_wo_t {
+ public:
+ UHD_DEFINE_SOFT_REG_FIELD(CLEAR_FIFO, /*width*/ 1, /*shift*/ 0); //[0]
+ UHD_DEFINE_SOFT_REG_FIELD(RD_SUPPRESS_EN, /*width*/ 1, /*shift*/ 1); //[1]
+ UHD_DEFINE_SOFT_REG_FIELD(BURST_TIMEOUT, /*width*/ 12, /*shift*/ 4); //[15:4]
+ UHD_DEFINE_SOFT_REG_FIELD(RD_SUPPRESS_THRESH, /*width*/ 16, /*shift*/ 16); //[31:16]
+
+ fifo_ctrl_reg_t(boost::uint32_t base):
+ soft_reg32_wo_t(base + 4)
+ {
+ //Initial values
+ set(CLEAR_FIFO, 1);
+ set(RD_SUPPRESS_EN, 0);
+ set(BURST_TIMEOUT, 256);
+ set(RD_SUPPRESS_THRESH, 0);
+ }
+ };
+
+ class base_addr_reg_t : public soft_reg32_wo_t {
+ public:
+ UHD_DEFINE_SOFT_REG_FIELD(BASE_ADDR, /*width*/ 30, /*shift*/ 0); //[29:0]
+
+ base_addr_reg_t(boost::uint32_t base):
+ soft_reg32_wo_t(base + 8)
+ {
+ //Initial values
+ set(BASE_ADDR, 0x00000000);
+ }
+ };
+
+ class addr_mask_reg_t : public soft_reg32_wo_t {
+ public:
+ UHD_DEFINE_SOFT_REG_FIELD(ADDR_MASK, /*width*/ 30, /*shift*/ 0); //[29:0]
+
+ addr_mask_reg_t(boost::uint32_t base):
+ soft_reg32_wo_t(base + 12)
+ {
+ //Initial values
+ set(ADDR_MASK, 0xFF000000);
+ }
+ };
+
+ class bist_ctrl_reg_t : public soft_reg32_wo_t {
+ public:
+ UHD_DEFINE_SOFT_REG_FIELD(GO, /*width*/ 1, /*shift*/ 0); //[0]
+ UHD_DEFINE_SOFT_REG_FIELD(CONTINUOUS_MODE, /*width*/ 1, /*shift*/ 1); //[1]
+ UHD_DEFINE_SOFT_REG_FIELD(TEST_PATT, /*width*/ 2, /*shift*/ 4); //[5:4]
+
+ static const boost::uint32_t TEST_PATT_ZERO_ONE = 0;
+ static const boost::uint32_t TEST_PATT_CHECKERBOARD = 1;
+ static const boost::uint32_t TEST_PATT_COUNT = 2;
+ static const boost::uint32_t TEST_PATT_COUNT_INV = 3;
+
+ bist_ctrl_reg_t(boost::uint32_t base):
+ soft_reg32_wo_t(base + 16)
+ {
+ //Initial values
+ set(GO, 0);
+ set(CONTINUOUS_MODE, 0);
+ set(TEST_PATT, TEST_PATT_ZERO_ONE);
+ }
+ };
+
+ class bist_cfg_reg_t : public soft_reg32_wo_t {
+ public:
+ UHD_DEFINE_SOFT_REG_FIELD(MAX_PKTS, /*width*/ 18, /*shift*/ 0); //[17:0]
+ UHD_DEFINE_SOFT_REG_FIELD(MAX_PKT_SIZE, /*width*/ 13, /*shift*/ 18); //[30:18]
+ UHD_DEFINE_SOFT_REG_FIELD(PKT_SIZE_RAMP, /*width*/ 1, /*shift*/ 31); //[31]
+
+ bist_cfg_reg_t(boost::uint32_t base):
+ soft_reg32_wo_t(base + 20)
+ {
+ //Initial values
+ set(MAX_PKTS, 0);
+ set(MAX_PKT_SIZE, 0);
+ set(PKT_SIZE_RAMP, 0);
+ }
+ };
+
+ class bist_delay_reg_t : public soft_reg32_wo_t {
+ public:
+ UHD_DEFINE_SOFT_REG_FIELD(TX_PKT_DELAY, /*width*/ 16, /*shift*/ 0); //[15:0]
+ UHD_DEFINE_SOFT_REG_FIELD(RX_SAMP_DELAY, /*width*/ 8, /*shift*/ 16); //[23:16]
+
+ bist_delay_reg_t(boost::uint32_t base):
+ soft_reg32_wo_t(base + 24)
+ {
+ //Initial values
+ set(TX_PKT_DELAY, 0);
+ set(RX_SAMP_DELAY, 0);
+ }
+ };
+
+ class bist_sid_reg_t : public soft_reg32_wo_t {
+ public:
+ UHD_DEFINE_SOFT_REG_FIELD(SID, /*width*/ 32, /*shift*/ 0); //[31:0]
+
+ bist_sid_reg_t(boost::uint32_t base):
+ soft_reg32_wo_t(base + 28)
+ {
+ //Initial values
+ set(SID, 0);
+ }
+ };
+
+public:
+ class fifo_readback {
+ public:
+ fifo_readback(wb_iface::sptr iface, const size_t base, const size_t rb_addr) :
+ _iface(iface), _addr_reg(base), _rb_addr(rb_addr)
+ {
+ _addr_reg.initialize(*iface, true);
+ }
+
+ bool is_fifo_instantiated() {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+ _addr_reg.write(rb_addr_reg_t::ADDR, rb_addr_reg_t::RB_FIFO_STATUS);
+ return _iface->peek32(_rb_addr) & 0x80000000;
+ }
+
+ boost::uint32_t get_occupied_cnt() {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+ _addr_reg.write(rb_addr_reg_t::ADDR, rb_addr_reg_t::RB_FIFO_STATUS);
+ return _iface->peek32(_rb_addr) & 0x7FFFFFF;
+ }
+
+ boost::uint32_t is_fifo_busy() {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+ _addr_reg.write(rb_addr_reg_t::ADDR, rb_addr_reg_t::RB_FIFO_STATUS);
+ return _iface->peek32(_rb_addr) & 0x40000000;
+ }
+
+ struct bist_status_t {
+ bool running;
+ bool finished;
+ boost::uint8_t error;
+ };
+
+ bist_status_t get_bist_status() {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+ _addr_reg.write(rb_addr_reg_t::ADDR, rb_addr_reg_t::RB_BIST_STATUS);
+ boost::uint32_t st32 = _iface->peek32(_rb_addr) & 0xF;
+ bist_status_t status;
+ status.running = st32 & 0x1;
+ status.finished = st32 & 0x2;
+ status.error = static_cast<boost::uint8_t>((st32>>2) & 0x3);
+ return status;
+ }
+
+ bool is_ext_bist_supported() {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+ _addr_reg.write(rb_addr_reg_t::ADDR, rb_addr_reg_t::RB_BIST_STATUS);
+ return _iface->peek32(_rb_addr) & 0x80000000;
+ }
+
+ double get_xfer_ratio() {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+ boost::uint32_t xfer_cnt = 0, cyc_cnt = 0;
+ _addr_reg.write(rb_addr_reg_t::ADDR, rb_addr_reg_t::RB_BIST_XFER_CNT);
+ xfer_cnt = _iface->peek32(_rb_addr);
+ _addr_reg.write(rb_addr_reg_t::ADDR, rb_addr_reg_t::RB_BIST_CYC_CNT);
+ cyc_cnt = _iface->peek32(_rb_addr);
+ return (static_cast<double>(xfer_cnt)/cyc_cnt);
+ }
+
+ private:
+ wb_iface::sptr _iface;
+ rb_addr_reg_t _addr_reg;
+ const size_t _rb_addr;
+ boost::mutex _mutex;
+ };
+
+public:
+ dma_fifo_core_3000_impl(wb_iface::sptr iface, const size_t base, const size_t readback):
+ _iface(iface), _base(base), _fifo_readback(iface, base, readback),
+ _fifo_ctrl_reg(base), _base_addr_reg(base), _addr_mask_reg(base),
+ _bist_ctrl_reg(base), _bist_cfg_reg(base), _bist_delay_reg(base), _bist_sid_reg(base)
+ {
+ _fifo_ctrl_reg.initialize(*iface, true);
+ _base_addr_reg.initialize(*iface, true);
+ _addr_mask_reg.initialize(*iface, true);
+ _bist_ctrl_reg.initialize(*iface, true);
+ _bist_cfg_reg.initialize(*iface, true);
+ _has_ext_bist = _fifo_readback.is_ext_bist_supported();
+ if (_has_ext_bist) {
+ _bist_delay_reg.initialize(*iface, true);
+ _bist_sid_reg.initialize(*iface, true);
+ }
+ flush();
+ }
+
+ virtual void flush() {
+ //Clear the FIFO and hold it in that state
+ _fifo_ctrl_reg.write(fifo_ctrl_reg_t::CLEAR_FIFO, 1);
+ //Re-arm the FIFO
+ _wait_for_fifo_empty();
+ _fifo_ctrl_reg.write(fifo_ctrl_reg_t::CLEAR_FIFO, 0);
+ }
+
+ virtual void resize(const boost::uint32_t base_addr, const boost::uint32_t size) {
+ //Validate parameters
+ if (size < 8192) throw uhd::runtime_error("DMA FIFO must be larger than 8KiB");
+ boost::uint32_t size_mask = size - 1;
+ if (size & size_mask) throw uhd::runtime_error("DMA FIFO size must be a power of 2");
+
+ //Clear the FIFO and hold it in that state
+ _fifo_ctrl_reg.write(fifo_ctrl_reg_t::CLEAR_FIFO, 1);
+ //Write base address and mask
+ _base_addr_reg.write(base_addr_reg_t::BASE_ADDR, base_addr);
+ _addr_mask_reg.write(addr_mask_reg_t::ADDR_MASK, ~size_mask);
+
+ //Re-arm the FIFO
+ flush();
+ }
+
+ virtual boost::uint32_t get_bytes_occupied() {
+ return _fifo_readback.get_occupied_cnt() * 8;
+ }
+
+ virtual bool ext_bist_supported() {
+ return _fifo_readback.is_ext_bist_supported();
+ }
+
+ virtual boost::uint8_t run_bist(bool finite = true, boost::uint32_t timeout_ms = 500) {
+ return run_ext_bist(finite, 0, 0, 0, timeout_ms);
+ }
+
+ virtual boost::uint8_t run_ext_bist(
+ bool finite,
+ boost::uint32_t rx_samp_delay,
+ boost::uint32_t tx_pkt_delay,
+ boost::uint32_t sid,
+ boost::uint32_t timeout_ms = 500
+ ) {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+
+ _wait_for_bist_done(timeout_ms, true); //Stop previous BIST and wait (if running)
+ _bist_ctrl_reg.write(bist_ctrl_reg_t::GO, 0); //Reset
+
+ _bist_cfg_reg.set(bist_cfg_reg_t::MAX_PKTS, (2^18)-1);
+ _bist_cfg_reg.set(bist_cfg_reg_t::MAX_PKT_SIZE, 8000);
+ _bist_cfg_reg.set(bist_cfg_reg_t::PKT_SIZE_RAMP, 0);
+ _bist_cfg_reg.flush();
+
+ if (_has_ext_bist) {
+ _bist_delay_reg.set(bist_delay_reg_t::RX_SAMP_DELAY, rx_samp_delay);
+ _bist_delay_reg.set(bist_delay_reg_t::TX_PKT_DELAY, tx_pkt_delay);
+ _bist_delay_reg.flush();
+
+ _bist_sid_reg.write(bist_sid_reg_t::SID, sid);
+ } else {
+ if (rx_samp_delay != 0 || tx_pkt_delay != 0 || sid != 0) {
+ throw uhd::not_implemented_error(
+ "dma_fifo_core_3000: Runtime delay and SID support only available on FPGA images with extended BIST enabled");
+ }
+ }
+
+ _bist_ctrl_reg.set(bist_ctrl_reg_t::TEST_PATT, bist_ctrl_reg_t::TEST_PATT_COUNT);
+ _bist_ctrl_reg.set(bist_ctrl_reg_t::CONTINUOUS_MODE, finite ? 0 : 1);
+ _bist_ctrl_reg.write(bist_ctrl_reg_t::GO, 1);
+
+ if (!finite) {
+ boost::this_thread::sleep(boost::posix_time::milliseconds(timeout_ms));
+ }
+
+ _wait_for_bist_done(timeout_ms, !finite);
+ if (!_fifo_readback.get_bist_status().finished) {
+ throw uhd::runtime_error("dma_fifo_core_3000: DRAM BIST state machine is in a bad state.");
+ }
+
+ return _fifo_readback.get_bist_status().error;
+ }
+
+ virtual double get_bist_throughput(double fifo_clock_rate) {
+ if (_has_ext_bist) {
+ _wait_for_bist_done(1000);
+ static const double BYTES_PER_CYC = 8;
+ return _fifo_readback.get_xfer_ratio() * fifo_clock_rate * BYTES_PER_CYC;
+ } else {
+ throw uhd::not_implemented_error(
+ "dma_fifo_core_3000: Throughput counter only available on FPGA images with extended BIST enabled");
+ }
+ }
+
+private:
+ void _wait_for_fifo_empty()
+ {
+ boost::posix_time::ptime start_time = boost::posix_time::microsec_clock::local_time();
+ boost::posix_time::time_duration elapsed;
+
+ while (_fifo_readback.is_fifo_busy()) {
+ boost::this_thread::sleep(boost::posix_time::microsec(1000));
+ elapsed = boost::posix_time::microsec_clock::local_time() - start_time;
+ if (elapsed.total_milliseconds() > 100) break;
+ }
+ }
+
+ void _wait_for_bist_done(boost::uint32_t timeout_ms, bool force_stop = false)
+ {
+ boost::posix_time::ptime start_time = boost::posix_time::microsec_clock::local_time();
+ boost::posix_time::time_duration elapsed;
+
+ while (_fifo_readback.get_bist_status().running) {
+ if (force_stop) {
+ _bist_ctrl_reg.write(bist_ctrl_reg_t::GO, 0);
+ force_stop = false;
+ }
+ boost::this_thread::sleep(boost::posix_time::microsec(1000));
+ elapsed = boost::posix_time::microsec_clock::local_time() - start_time;
+ if (elapsed.total_milliseconds() > timeout_ms) break;
+ }
+ }
+
+private:
+ wb_iface::sptr _iface;
+ const size_t _base;
+ boost::mutex _mutex;
+ bool _has_ext_bist;
+
+ fifo_readback _fifo_readback;
+ fifo_ctrl_reg_t _fifo_ctrl_reg;
+ base_addr_reg_t _base_addr_reg;
+ addr_mask_reg_t _addr_mask_reg;
+ bist_ctrl_reg_t _bist_ctrl_reg;
+ bist_cfg_reg_t _bist_cfg_reg;
+ bist_delay_reg_t _bist_delay_reg;
+ bist_sid_reg_t _bist_sid_reg;
+};
+
+//
+// Static make function
+//
+dma_fifo_core_3000::sptr dma_fifo_core_3000::make(wb_iface::sptr iface, const size_t set_base, const size_t rb_addr)
+{
+ if (check(iface, set_base, rb_addr)) {
+ return sptr(new dma_fifo_core_3000_impl(iface, set_base, rb_addr));
+ } else {
+ throw uhd::runtime_error("");
+ }
+}
+
+bool dma_fifo_core_3000::check(wb_iface::sptr iface, const size_t set_base, const size_t rb_addr)
+{
+ dma_fifo_core_3000_impl::fifo_readback fifo_rb(iface, set_base, rb_addr);
+ return fifo_rb.is_fifo_instantiated();
+}
diff --git a/host/lib/usrp/cores/dma_fifo_core_3000.hpp b/host/lib/usrp/cores/dma_fifo_core_3000.hpp
new file mode 100644
index 000000000..41430e5c3
--- /dev/null
+++ b/host/lib/usrp/cores/dma_fifo_core_3000.hpp
@@ -0,0 +1,86 @@
+//
+// Copyright 2015 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_LIBUHD_USRP_DMA_FIFO_CORE_3000_HPP
+#define INCLUDED_LIBUHD_USRP_DMA_FIFO_CORE_3000_HPP
+
+#include <uhd/config.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/noncopyable.hpp>
+#include <uhd/types/wb_iface.hpp>
+
+
+class dma_fifo_core_3000 : boost::noncopyable
+{
+public:
+ typedef boost::shared_ptr<dma_fifo_core_3000> sptr;
+ virtual ~dma_fifo_core_3000(void) = 0;
+
+ /*!
+ * Create a DMA FIFO controller using the given bus, settings and readback base
+ * Throws uhd::runtime_error if a DMA FIFO is not instantiated in the FPGA
+ */
+ static sptr make(uhd::wb_iface::sptr iface, const size_t set_base, const size_t rb_addr);
+
+ /*!
+ * Check if a DMA FIFO is instantiated in the FPGA
+ */
+ static bool check(uhd::wb_iface::sptr iface, const size_t set_base, const size_t rb_addr);
+
+ /*!
+ * Flush the DMA FIFO. Will clear all contents.
+ */
+ virtual void flush() = 0;
+
+ /*!
+ * Resize and rebase the DMA FIFO. Will clear all contents.
+ */
+ virtual void resize(const boost::uint32_t base_addr, const boost::uint32_t size) = 0;
+
+ /*!
+ * Get the (approx) number of bytes currently in the DMA FIFO
+ */
+ virtual boost::uint32_t get_bytes_occupied() = 0;
+
+ /*!
+ * Run the built-in-self-test routine for the DMA FIFO
+ */
+ virtual boost::uint8_t run_bist(bool finite = true, boost::uint32_t timeout_ms = 500) = 0;
+
+ /*!
+ * Is extended BIST supported
+ */
+ virtual bool ext_bist_supported() = 0;
+
+ /*!
+ * Run the built-in-self-test routine for the DMA FIFO (extended BIST only)
+ */
+ virtual boost::uint8_t run_ext_bist(
+ bool finite,
+ boost::uint32_t rx_samp_delay,
+ boost::uint32_t tx_pkt_delay,
+ boost::uint32_t sid,
+ boost::uint32_t timeout_ms = 500) = 0;
+
+ /*!
+ * Get the throughput measured from the last invocation of the BIST (extended BIST only)
+ */
+ virtual double get_bist_throughput(double fifo_clock_rate) = 0;
+
+};
+
+#endif /* INCLUDED_LIBUHD_USRP_DMA_FIFO_CORE_3000_HPP */
diff --git a/host/lib/usrp/cores/gpio_atr_3000.cpp b/host/lib/usrp/cores/gpio_atr_3000.cpp
new file mode 100644
index 000000000..3e0aa1f03
--- /dev/null
+++ b/host/lib/usrp/cores/gpio_atr_3000.cpp
@@ -0,0 +1,297 @@
+//
+// Copyright 2011,2014 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "gpio_atr_3000.hpp"
+#include <uhd/types/dict.hpp>
+#include <uhd/utils/soft_register.hpp>
+
+using namespace uhd;
+using namespace usrp;
+
+//-------------------------------------------------------------
+// gpio_atr_3000
+//-------------------------------------------------------------
+
+#define REG_ATR_IDLE_OFFSET (base + 0)
+#define REG_ATR_RX_OFFSET (base + 4)
+#define REG_ATR_TX_OFFSET (base + 8)
+#define REG_ATR_FDX_OFFSET (base + 12)
+#define REG_DDR_OFFSET (base + 16)
+#define REG_ATR_DISABLE_OFFSET (base + 20)
+
+namespace uhd { namespace usrp { namespace gpio_atr {
+
+class gpio_atr_3000_impl : public gpio_atr_3000{
+public:
+ gpio_atr_3000_impl(
+ wb_iface::sptr iface,
+ const wb_iface::wb_addr_type base,
+ const wb_iface::wb_addr_type rb_addr = READBACK_DISABLED
+ ):
+ _iface(iface), _rb_addr(rb_addr),
+ _atr_idle_reg(REG_ATR_IDLE_OFFSET, _atr_disable_reg),
+ _atr_rx_reg(REG_ATR_RX_OFFSET),
+ _atr_tx_reg(REG_ATR_TX_OFFSET),
+ _atr_fdx_reg(REG_ATR_FDX_OFFSET),
+ _ddr_reg(REG_DDR_OFFSET),
+ _atr_disable_reg(REG_ATR_DISABLE_OFFSET)
+ {
+ _atr_idle_reg.initialize(*_iface, true);
+ _atr_rx_reg.initialize(*_iface, true);
+ _atr_tx_reg.initialize(*_iface, true);
+ _atr_fdx_reg.initialize(*_iface, true);
+ _ddr_reg.initialize(*_iface, true);
+ _atr_disable_reg.initialize(*_iface, true);
+ }
+
+ virtual void set_atr_mode(const gpio_atr_mode_t mode, const boost::uint32_t mask)
+ {
+ //Each bit in the "ATR Disable" register determines whether the respective bit in the GPIO
+ //output bus is driven by the ATR engine or a static register.
+ //For each bit position, a 1 means that the bit is static and 0 means that the bit
+ //is driven by the ATR state machine.
+ //This setting will only get applied to all bits in the "mask" that are 1. All other
+ //bits will retain their old value.
+ _atr_disable_reg.set_with_mask((mode==MODE_ATR) ? ~MASK_SET_ALL : MASK_SET_ALL, mask);
+ _atr_disable_reg.flush();
+ }
+
+ virtual void set_gpio_ddr(const gpio_ddr_t dir, const boost::uint32_t mask)
+ {
+ //Each bit in the "DDR" register determines whether the respective bit in the GPIO
+ //bus is an input or an output.
+ //For each bit position, a 1 means that the bit is an output and 0 means that the bit
+ //is an input.
+ //This setting will only get applied to all bits in the "mask" that are 1. All other
+ //bits will retain their old value.
+ _ddr_reg.set_with_mask((dir==DDR_INPUT) ? ~MASK_SET_ALL : MASK_SET_ALL, mask);
+ _ddr_reg.flush();
+ }
+
+ virtual void set_atr_reg(const gpio_atr_reg_t atr, const boost::uint32_t value, const boost::uint32_t mask = MASK_SET_ALL)
+ {
+ //Set the value of the specified ATR register. For bits with ATR Disable set to 1,
+ //the IDLE register will hold the output state
+ //This setting will only get applied to all bits in the "mask" that are 1. All other
+ //bits will retain their old value.
+ masked_reg_t* reg = NULL;
+ switch (atr) {
+ case ATR_REG_IDLE: reg = &_atr_idle_reg; break;
+ case ATR_REG_RX_ONLY: reg = &_atr_rx_reg; break;
+ case ATR_REG_TX_ONLY: reg = &_atr_tx_reg; break;
+ case ATR_REG_FULL_DUPLEX: reg = &_atr_fdx_reg; break;
+ default: reg = &_atr_idle_reg; break;
+ }
+ //For protection we only write to bits that have the mode ATR by masking the user
+ //specified "mask" with ~atr_disable.
+ reg->set_with_mask(value, mask);
+ reg->flush();
+ }
+
+ virtual void set_gpio_out(const boost::uint32_t value, const boost::uint32_t mask = MASK_SET_ALL) {
+ //Set the value of the specified GPIO output register.
+ //This setting will only get applied to all bits in the "mask" that are 1. All other
+ //bits will retain their old value.
+
+ //For protection we only write to bits that have the mode GPIO by masking the user
+ //specified "mask" with atr_disable.
+ _atr_idle_reg.set_gpio_out_with_mask(value, mask);
+ _atr_idle_reg.flush();
+ }
+
+ virtual boost::uint32_t read_gpio()
+ {
+ //Read the state of the GPIO pins
+ //If a pin is configured as an input, reads the actual value of the pin
+ //If a pin is configured as an output, reads the last value written to the pin
+ if (_rb_addr != READBACK_DISABLED) {
+ return _iface->peek32(_rb_addr);
+ } else {
+ throw uhd::runtime_error("read_gpio not supported for write-only interface.");
+ }
+ }
+
+ inline virtual void set_gpio_attr(const gpio_attr_t attr, const boost::uint32_t value)
+ {
+ //An attribute based API to configure all settings for the GPIO bus in one function
+ //call. This API does not have a mask so it configures all bits at the same time.
+ switch (attr)
+ {
+ case GPIO_CTRL:
+ set_atr_mode(MODE_ATR, value); //Configure mode=ATR for all bits that are set
+ set_atr_mode(MODE_GPIO, ~value); //Configure mode=GPIO for all bits that are unset
+ break;
+ case GPIO_DDR:
+ set_gpio_ddr(DDR_OUTPUT, value); //Configure as output for all bits that are set
+ set_gpio_ddr(DDR_INPUT, ~value); //Configure as input for all bits that are unset
+ break;
+ case GPIO_OUT:
+ //Only set bits that are driven statically
+ set_gpio_out(value);
+ break;
+ case GPIO_ATR_0X:
+ //Only set bits that are driven by the ATR engine
+ set_atr_reg(ATR_REG_IDLE, value);
+ break;
+ case GPIO_ATR_RX:
+ //Only set bits that are driven by the ATR engine
+ set_atr_reg(ATR_REG_RX_ONLY, value);
+ break;
+ case GPIO_ATR_TX:
+ //Only set bits that are driven by the ATR engine
+ set_atr_reg(ATR_REG_TX_ONLY, value);
+ break;
+ case GPIO_ATR_XX:
+ //Only set bits that are driven by the ATR engine
+ set_atr_reg(ATR_REG_FULL_DUPLEX, value);
+ break;
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
+ }
+ }
+
+private:
+ //Special RB addr value to indicate no readback
+ //This value is invalid as a real address because it is not a multiple of 4
+ static const wb_iface::wb_addr_type READBACK_DISABLED = 0xFFFFFFFF;
+
+ class masked_reg_t : public uhd::soft_reg32_wo_t {
+ public:
+ masked_reg_t(const wb_iface::wb_addr_type offset): uhd::soft_reg32_wo_t(offset) {
+ set(REGISTER, 0);
+ }
+
+ virtual void set_with_mask(const boost::uint32_t value, const boost::uint32_t mask) {
+ set(REGISTER, (value&mask)|(get(REGISTER)&(~mask)));
+ }
+
+ virtual void flush() {
+ uhd::soft_reg32_wo_t::flush();
+ }
+ };
+
+ class atr_idle_reg_t : public masked_reg_t {
+ public:
+ atr_idle_reg_t(const wb_iface::wb_addr_type offset, masked_reg_t& atr_disable_reg):
+ masked_reg_t(offset),
+ _atr_idle_cache(0), _gpio_out_cache(0),
+ _atr_disable_reg(atr_disable_reg)
+ { }
+
+ virtual void set_with_mask(const boost::uint32_t value, const boost::uint32_t mask) {
+ _atr_idle_cache = (value&mask)|(_atr_idle_cache&(~mask));
+ }
+
+ void set_gpio_out_with_mask(const boost::uint32_t value, const boost::uint32_t mask) {
+ _gpio_out_cache = (value&mask)|(_gpio_out_cache&(~mask));
+ }
+
+ virtual void flush() {
+ set(REGISTER,
+ (_atr_idle_cache & (~_atr_disable_reg.get(REGISTER))) |
+ (_gpio_out_cache & _atr_disable_reg.get(REGISTER))
+ );
+ masked_reg_t::flush();
+ }
+
+ private:
+ boost::uint32_t _atr_idle_cache;
+ boost::uint32_t _gpio_out_cache;
+ masked_reg_t& _atr_disable_reg;
+ };
+
+ wb_iface::sptr _iface;
+ wb_iface::wb_addr_type _rb_addr;
+ atr_idle_reg_t _atr_idle_reg;
+ masked_reg_t _atr_rx_reg;
+ masked_reg_t _atr_tx_reg;
+ masked_reg_t _atr_fdx_reg;
+ masked_reg_t _ddr_reg;
+ masked_reg_t _atr_disable_reg;
+};
+
+gpio_atr_3000::sptr gpio_atr_3000::make(
+ wb_iface::sptr iface, const wb_iface::wb_addr_type base, const wb_iface::wb_addr_type rb_addr
+) {
+ return sptr(new gpio_atr_3000_impl(iface, base, rb_addr));
+}
+
+gpio_atr_3000::sptr gpio_atr_3000::make_write_only(
+ wb_iface::sptr iface, const wb_iface::wb_addr_type base
+) {
+ gpio_atr_3000::sptr gpio_iface(new gpio_atr_3000_impl(iface, base));
+ gpio_iface->set_gpio_ddr(DDR_OUTPUT, MASK_SET_ALL);
+ return gpio_iface;
+}
+
+//-------------------------------------------------------------
+// db_gpio_atr_3000
+//-------------------------------------------------------------
+
+class db_gpio_atr_3000_impl : public gpio_atr_3000_impl, public db_gpio_atr_3000 {
+public:
+ db_gpio_atr_3000_impl(wb_iface::sptr iface, const wb_iface::wb_addr_type base, const wb_iface::wb_addr_type rb_addr):
+ gpio_atr_3000_impl(iface, base, rb_addr) { /* NOP */ }
+
+ inline void set_pin_ctrl(const db_unit_t unit, const boost::uint16_t value)
+ {
+ gpio_atr_3000_impl::set_atr_mode(MODE_ATR, compute_mask(unit, value));
+ gpio_atr_3000_impl::set_atr_mode(MODE_GPIO, compute_mask(unit, ~value));
+ }
+
+ inline void set_gpio_ddr(const db_unit_t unit, const boost::uint16_t value)
+ {
+ gpio_atr_3000_impl::set_gpio_ddr(DDR_OUTPUT, compute_mask(unit, value));
+ gpio_atr_3000_impl::set_gpio_ddr(DDR_INPUT, compute_mask(unit, ~value));
+ }
+
+ inline void set_atr_reg(const db_unit_t unit, const gpio_atr_reg_t atr, const boost::uint16_t value)
+ {
+ gpio_atr_3000_impl::set_atr_reg(atr,
+ static_cast<boost::uint32_t>(value) << compute_shift(unit),
+ compute_mask(unit, 0xFFFF));
+ }
+
+ inline void set_gpio_out(const db_unit_t unit, const boost::uint16_t value)
+ {
+ gpio_atr_3000_impl::set_gpio_out(
+ static_cast<boost::uint32_t>(value) << compute_shift(unit),
+ compute_mask(unit, 0xFFFF));
+ }
+
+ inline boost::uint16_t read_gpio(const db_unit_t unit)
+ {
+ return boost::uint16_t(gpio_atr_3000_impl::read_gpio() >> compute_shift(unit));
+ }
+
+private:
+ inline boost::uint32_t compute_shift(const db_unit_t unit) {
+ return (unit == dboard_iface::UNIT_RX) ? 0 : 16;
+ }
+
+ inline boost::uint32_t compute_mask(const db_unit_t unit, const boost::uint16_t mask) {
+ return static_cast<boost::uint32_t>(mask) << (compute_shift(unit));
+ }
+};
+
+db_gpio_atr_3000::sptr db_gpio_atr_3000::make(
+ wb_iface::sptr iface, const wb_iface::wb_addr_type base, const wb_iface::wb_addr_type rb_addr
+) {
+ return sptr(new db_gpio_atr_3000_impl(iface, base, rb_addr));
+}
+
+}}}
diff --git a/host/lib/usrp/cores/gpio_atr_3000.hpp b/host/lib/usrp/cores/gpio_atr_3000.hpp
new file mode 100644
index 000000000..b30cd3b85
--- /dev/null
+++ b/host/lib/usrp/cores/gpio_atr_3000.hpp
@@ -0,0 +1,175 @@
+//
+// Copyright 2011,2014,2015 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_LIBUHD_USRP_GPIO_CORE_3000_HPP
+#define INCLUDED_LIBUHD_USRP_GPIO_CORE_3000_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/usrp/dboard_iface.hpp>
+#include <uhd/usrp/gpio_defs.hpp>
+#include <boost/shared_ptr.hpp>
+#include <uhd/types/wb_iface.hpp>
+
+namespace uhd { namespace usrp { namespace gpio_atr {
+
+class gpio_atr_3000 : boost::noncopyable {
+public:
+ typedef boost::shared_ptr<gpio_atr_3000> sptr;
+
+ static const boost::uint32_t MASK_SET_ALL = 0xFFFFFFFF;
+
+ virtual ~gpio_atr_3000(void) {};
+
+ /*!
+ * Create a read-write GPIO ATR interface object
+ *
+ * \param iface register iface to GPIO ATR registers
+ * \param base base settings offset for GPIO ATR registers
+ * \param base readback offset for GPIO ATR registers
+ */
+ static sptr make(
+ uhd::wb_iface::sptr iface,
+ const uhd::wb_iface::wb_addr_type base,
+ const uhd::wb_iface::wb_addr_type rb_addr);
+
+ /*!
+ * Create a write-only GPIO ATR interface object
+ *
+ * \param iface register iface to GPIO ATR registers
+ * \param base base settings offset for GPIO ATR registers
+ */
+ static sptr make_write_only(
+ uhd::wb_iface::sptr iface, const uhd::wb_iface::wb_addr_type base);
+
+ /*!
+ * Select the ATR mode for all bits in the mask
+ *
+ * \param mode the mode to apply {ATR = outputs driven by ATR state machine, GPIO = outputs static}
+ * \param mask apply the mode to all non-zero bits in the mask
+ */
+ virtual void set_atr_mode(const gpio_atr_mode_t mode, const boost::uint32_t mask) = 0;
+
+ /*!
+ * Select the data direction for all bits in the mask
+ *
+ * \param dir the direction {OUTPUT, INPUT}
+ * \param mask apply the mode to all non-zero bits in the mask
+ */
+ virtual void set_gpio_ddr(const gpio_ddr_t dir, const boost::uint32_t mask) = 0;
+
+ /*!
+ * Write the specified (masked) value to the ATR register
+ *
+ * \param atr the type of ATR register to write to {IDLE, RX, TX, FDX}
+ * \param value the value to write
+ * \param mask only writes to the bits where mask is non-zero
+ */
+ virtual void set_atr_reg(const gpio_atr_reg_t atr, const boost::uint32_t value, const boost::uint32_t mask = MASK_SET_ALL) = 0;
+
+ /*!
+ * Write to a static GPIO output
+ *
+ * \param value the value to write
+ * \param mask only writes to the bits where mask is non-zero
+ */
+ virtual void set_gpio_out(const boost::uint32_t value, const boost::uint32_t mask = MASK_SET_ALL) = 0;
+
+ /*!
+ * Read the state of the GPIO pins
+ * If a pin is configured as an input, reads the actual value of the pin
+ * If a pin is configured as an output, reads the last value written to the pin
+ *
+ * \return the value read back
+ */
+ virtual boost::uint32_t read_gpio() = 0;
+
+ /*!
+ * Set a GPIO attribute
+ *
+ * \param attr the attribute to set
+ * \param value the value to write to the attribute
+ */
+ virtual void set_gpio_attr(const gpio_attr_t attr, const boost::uint32_t value) = 0;
+};
+
+class db_gpio_atr_3000 {
+public:
+ typedef boost::shared_ptr<db_gpio_atr_3000> sptr;
+
+ typedef uhd::usrp::dboard_iface::unit_t db_unit_t;
+
+ virtual ~db_gpio_atr_3000(void) {};
+
+ /*!
+ * Create a read-write GPIO ATR interface object for a daughterboard connector
+ *
+ * \param iface register iface to GPIO ATR registers
+ * \param base base settings offset for GPIO ATR registers
+ * \param base readback offset for GPIO ATR registers
+ */
+ static sptr make(
+ uhd::wb_iface::sptr iface,
+ const uhd::wb_iface::wb_addr_type base,
+ const uhd::wb_iface::wb_addr_type rb_addr);
+
+ /*!
+ * Configure the GPIO mode for all pins in the daughterboard connector
+ *
+ * \param unit the side of the daughterboard interface to configure (TX or RX)
+ * \param value if value[i] is 1, the i'th bit is in ATR mode otherwise it is in GPIO mode
+ */
+ virtual void set_pin_ctrl(const db_unit_t unit, const boost::uint16_t value) = 0;
+
+ /*!
+ * Configure the direction for all pins in the daughterboard connector
+ *
+ * \param unit the side of the daughterboard interface to configure (TX or RX)
+ * \param value if value[i] is 1, the i'th bit is an output otherwise it is an input
+ */
+ virtual void set_gpio_ddr(const db_unit_t unit, const boost::uint16_t value) = 0;
+
+ /*!
+ * Write the specified value to the ATR register (all bits)
+ *
+ * \param atr the type of ATR register to write to {IDLE, RX, TX, FDX}
+ * \param unit the side of the daughterboard interface to configure (TX or RX)
+ * \param value the value to write
+ */
+ virtual void set_atr_reg(const db_unit_t unit, const gpio_atr_reg_t atr, const boost::uint16_t value) = 0;
+
+ /*!
+ * Write the specified value to the GPIO register (all bits)
+ *
+ * \param atr the type of ATR register to write to {IDLE, RX, TX, FDX}
+ * \param value the value to write
+ */
+ virtual void set_gpio_out(const db_unit_t unit, const boost::uint16_t value) = 0;
+
+ /*!
+ * Read the state of the GPIO pins
+ * If a pin is configured as an input, reads the actual value of the pin
+ * If a pin is configured as an output, reads the last value written to the pin
+ *
+ * \param unit the side of the daughterboard interface to configure (TX or RX)
+ * \return the value read back
+ */
+ virtual boost::uint16_t read_gpio(const db_unit_t unit) = 0;
+};
+
+}}} //namespaces
+
+#endif /* INCLUDED_LIBUHD_USRP_GPIO_CORE_3000_HPP */
diff --git a/host/lib/usrp/cores/gpio_core_200.cpp b/host/lib/usrp/cores/gpio_core_200.cpp
index 4f1c25a0b..05a689845 100644
--- a/host/lib/usrp/cores/gpio_core_200.cpp
+++ b/host/lib/usrp/cores/gpio_core_200.cpp
@@ -77,10 +77,10 @@ private:
}
void update(void){
- this->update(dboard_iface::ATR_REG_IDLE, REG_GPIO_IDLE);
- this->update(dboard_iface::ATR_REG_TX_ONLY, REG_GPIO_TX_ONLY);
- this->update(dboard_iface::ATR_REG_RX_ONLY, REG_GPIO_RX_ONLY);
- this->update(dboard_iface::ATR_REG_FULL_DUPLEX, REG_GPIO_BOTH);
+ this->update(gpio_atr::ATR_REG_IDLE, REG_GPIO_IDLE);
+ this->update(gpio_atr::ATR_REG_TX_ONLY, REG_GPIO_TX_ONLY);
+ this->update(gpio_atr::ATR_REG_RX_ONLY, REG_GPIO_RX_ONLY);
+ this->update(gpio_atr::ATR_REG_FULL_DUPLEX, REG_GPIO_BOTH);
}
void update(const atr_reg_t atr, const size_t addr){
@@ -122,17 +122,17 @@ public:
}
void set_atr_reg(const atr_reg_t atr, const boost::uint32_t value){
- if (atr == dboard_iface::ATR_REG_IDLE) _iface->poke32(REG_GPIO_IDLE, value);
- if (atr == dboard_iface::ATR_REG_TX_ONLY) _iface->poke32(REG_GPIO_TX_ONLY, value);
- if (atr == dboard_iface::ATR_REG_RX_ONLY) _iface->poke32(REG_GPIO_RX_ONLY, value);
- if (atr == dboard_iface::ATR_REG_FULL_DUPLEX) _iface->poke32(REG_GPIO_BOTH, value);
+ if (atr == gpio_atr::ATR_REG_IDLE) _iface->poke32(REG_GPIO_IDLE, value);
+ if (atr == gpio_atr::ATR_REG_TX_ONLY) _iface->poke32(REG_GPIO_TX_ONLY, value);
+ if (atr == gpio_atr::ATR_REG_RX_ONLY) _iface->poke32(REG_GPIO_RX_ONLY, value);
+ if (atr == gpio_atr::ATR_REG_FULL_DUPLEX) _iface->poke32(REG_GPIO_BOTH, value);
}
void set_all_regs(const boost::uint32_t value){
- this->set_atr_reg(dboard_iface::ATR_REG_IDLE, value);
- this->set_atr_reg(dboard_iface::ATR_REG_TX_ONLY, value);
- this->set_atr_reg(dboard_iface::ATR_REG_RX_ONLY, value);
- this->set_atr_reg(dboard_iface::ATR_REG_FULL_DUPLEX, value);
+ this->set_atr_reg(gpio_atr::ATR_REG_IDLE, value);
+ this->set_atr_reg(gpio_atr::ATR_REG_TX_ONLY, value);
+ this->set_atr_reg(gpio_atr::ATR_REG_RX_ONLY, value);
+ this->set_atr_reg(gpio_atr::ATR_REG_FULL_DUPLEX, value);
}
private:
diff --git a/host/lib/usrp/cores/gpio_core_200.hpp b/host/lib/usrp/cores/gpio_core_200.hpp
index e22834fd9..c60507792 100644
--- a/host/lib/usrp/cores/gpio_core_200.hpp
+++ b/host/lib/usrp/cores/gpio_core_200.hpp
@@ -20,6 +20,7 @@
#include <uhd/config.hpp>
#include <uhd/usrp/dboard_iface.hpp>
+#include <uhd/usrp/gpio_defs.hpp>
#include <boost/assign.hpp>
#include <boost/cstdint.hpp>
#include <boost/utility.hpp>
@@ -27,28 +28,6 @@
#include <uhd/types/wb_iface.hpp>
#include <map>
-typedef enum {
- GPIO_CTRL,
- GPIO_DDR,
- GPIO_OUT,
- GPIO_ATR_0X,
- GPIO_ATR_RX,
- GPIO_ATR_TX,
- GPIO_ATR_XX
-} gpio_attr_t;
-
-typedef std::map<gpio_attr_t,std::string> gpio_attr_map_t;
-static const gpio_attr_map_t gpio_attr_map =
- boost::assign::map_list_of
- (GPIO_CTRL, "CTRL")
- (GPIO_DDR, "DDR")
- (GPIO_OUT, "OUT")
- (GPIO_ATR_0X, "ATR_0X")
- (GPIO_ATR_RX, "ATR_RX")
- (GPIO_ATR_TX, "ATR_TX")
- (GPIO_ATR_XX, "ATR_XX")
-;
-
class gpio_core_200 : boost::noncopyable{
public:
typedef boost::shared_ptr<gpio_core_200> sptr;
diff --git a/host/lib/usrp/cores/tx_vita_core_3000.cpp b/host/lib/usrp/cores/tx_vita_core_3000.cpp
index 71a2b7e21..c76b384d9 100644
--- a/host/lib/usrp/cores/tx_vita_core_3000.cpp
+++ b/host/lib/usrp/cores/tx_vita_core_3000.cpp
@@ -18,9 +18,11 @@
#include "tx_vita_core_3000.hpp"
#include <uhd/utils/safe_call.hpp>
-#define REG_CTRL_ERROR_POLICY _base + 0
-#define REG_DEFRAMER_CYCLE_FC_UPS _base + 2*4 + 0
-#define REG_DEFRAMER_PACKET_FC_UPS _base + 2*4 + 4
+#define REG_CTRL_ERROR_POLICY (_base + 0)
+#define REG_FC_PRE_RADIO_RESP_BASE (_base + 2*4)
+#define REG_FC_PRE_FIFO_RESP_BASE (_base + 4*4)
+#define REG_CTRL_FC_CYCLE_OFFSET (0*4)
+#define REG_CTRL_FC_PACKET_OFFSET (1*4)
using namespace uhd;
@@ -32,12 +34,22 @@ struct tx_vita_core_3000_impl : tx_vita_core_3000
{
tx_vita_core_3000_impl(
wb_iface::sptr iface,
- const size_t base
+ const size_t base,
+ fc_monitor_loc fc_location
):
_iface(iface),
- _base(base)
+ _base(base),
+ _fc_base((fc_location==FC_PRE_RADIO or fc_location==FC_DEFAULT) ?
+ REG_FC_PRE_RADIO_RESP_BASE : REG_FC_PRE_FIFO_RESP_BASE),
+ _fc_location(fc_location)
{
- this->set_tick_rate(1); //init to non zero
+ if (fc_location != FC_DEFAULT) {
+ //Turn off the other FC monitoring module
+ const size_t other_fc_base = (fc_location==FC_PRE_RADIO) ?
+ REG_FC_PRE_FIFO_RESP_BASE : REG_FC_PRE_RADIO_RESP_BASE;
+ _iface->poke32(other_fc_base + REG_CTRL_FC_CYCLE_OFFSET, 0);
+ _iface->poke32(other_fc_base + REG_CTRL_FC_PACKET_OFFSET, 0);
+ }
this->set_underflow_policy("next_packet");
this->clear();
}
@@ -56,11 +68,6 @@ struct tx_vita_core_3000_impl : tx_vita_core_3000
this->set_underflow_policy(_policy); //clears the seq
}
- void set_tick_rate(const double rate)
- {
- _tick_rate = rate;
- }
-
void set_underflow_policy(const std::string &policy)
{
if (policy == "next_packet")
@@ -89,23 +96,35 @@ struct tx_vita_core_3000_impl : tx_vita_core_3000
void configure_flow_control(const size_t cycs_per_up, const size_t pkts_per_up)
{
- if (cycs_per_up == 0) _iface->poke32(REG_DEFRAMER_CYCLE_FC_UPS, 0);
- else _iface->poke32(REG_DEFRAMER_CYCLE_FC_UPS, (1 << 31) | ((cycs_per_up) & 0xffffff));
+ if (cycs_per_up == 0) _iface->poke32(_fc_base + REG_CTRL_FC_CYCLE_OFFSET, 0);
+ else _iface->poke32(_fc_base + REG_CTRL_FC_CYCLE_OFFSET, (1 << 31) | ((cycs_per_up) & 0xffffff));
- if (pkts_per_up == 0) _iface->poke32(REG_DEFRAMER_PACKET_FC_UPS, 0);
- else _iface->poke32(REG_DEFRAMER_PACKET_FC_UPS, (1 << 31) | ((pkts_per_up) & 0xffff));
+ if (pkts_per_up == 0) _iface->poke32(_fc_base + REG_CTRL_FC_PACKET_OFFSET, 0);
+ else _iface->poke32(_fc_base + REG_CTRL_FC_PACKET_OFFSET, (1 << 31) | ((pkts_per_up) & 0xffff));
}
- wb_iface::sptr _iface;
- const size_t _base;
- double _tick_rate;
- std::string _policy;
+ wb_iface::sptr _iface;
+ const size_t _base;
+ const size_t _fc_base;
+ std::string _policy;
+ fc_monitor_loc _fc_location;
+
};
tx_vita_core_3000::sptr tx_vita_core_3000::make(
wb_iface::sptr iface,
+ const size_t base,
+ fc_monitor_loc fc_location
+)
+{
+ return tx_vita_core_3000::sptr(new tx_vita_core_3000_impl(iface, base, fc_location));
+}
+
+tx_vita_core_3000::sptr tx_vita_core_3000::make_no_radio_buff(
+ wb_iface::sptr iface,
const size_t base
)
{
- return tx_vita_core_3000::sptr(new tx_vita_core_3000_impl(iface, base));
+ //No internal radio buffer so only pre-radio monitoring is supported.
+ return tx_vita_core_3000::sptr(new tx_vita_core_3000_impl(iface, base, FC_DEFAULT));
}
diff --git a/host/lib/usrp/cores/tx_vita_core_3000.hpp b/host/lib/usrp/cores/tx_vita_core_3000.hpp
index 4c0052d4f..bd0f20ba4 100644
--- a/host/lib/usrp/cores/tx_vita_core_3000.hpp
+++ b/host/lib/usrp/cores/tx_vita_core_3000.hpp
@@ -32,17 +32,27 @@ class tx_vita_core_3000 : boost::noncopyable
public:
typedef boost::shared_ptr<tx_vita_core_3000> sptr;
+ enum fc_monitor_loc {
+ FC_DEFAULT,
+ FC_PRE_RADIO,
+ FC_PRE_FIFO
+ };
+
virtual ~tx_vita_core_3000(void) = 0;
static sptr make(
uhd::wb_iface::sptr iface,
+ const size_t base,
+ fc_monitor_loc fc_location = FC_PRE_RADIO
+ );
+
+ static sptr make_no_radio_buff(
+ uhd::wb_iface::sptr iface,
const size_t base
);
virtual void clear(void) = 0;
- virtual void set_tick_rate(const double rate) = 0;
-
virtual void setup(const uhd::stream_args_t &stream_args) = 0;
virtual void configure_flow_control(const size_t cycs_per_up, const size_t pkts_per_up) = 0;
diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp
index 1342c913d..3e7df9a39 100644
--- a/host/lib/usrp/dboard/db_rfx.cpp
+++ b/host/lib/usrp/dboard/db_rfx.cpp
@@ -248,15 +248,15 @@ rfx_xcvr::rfx_xcvr(
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, output_enables);
//setup the tx atr (this does not change with antenna)
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY, _power_up | ANT_RX | MIXER_DIS);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, _power_up | ANT_TX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, _power_up | ANT_RX | MIXER_DIS);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_TX | MIXER_ENB);
//setup the rx atr (this does not change with antenna)
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX2| MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX2| MIXER_ENB);
}
rfx_xcvr::~rfx_xcvr(void){
@@ -272,14 +272,14 @@ void rfx_xcvr::set_rx_ant(const std::string &ant){
//set the rx atr regs that change with antenna setting
if (ant == "CAL") {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, _power_up | ANT_TXRX | MIXER_ENB);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, _power_up | ANT_TXRX | MIXER_ENB);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, _power_up | MIXER_ENB | ANT_TXRX );
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TXRX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_TXRX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _power_up | MIXER_ENB | ANT_TXRX );
}
else {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX2| MIXER_ENB);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, _power_up | MIXER_ENB |
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX2| MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _power_up | MIXER_ENB |
((ant == "TX/RX")? ANT_TXRX : ANT_RX2));
}
@@ -292,12 +292,12 @@ void rfx_xcvr::set_tx_ant(const std::string &ant){
//set the tx atr regs that change with antenna setting
if (ant == "CAL") {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, _power_up | ANT_RX | MIXER_ENB);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_RX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX | MIXER_ENB);
}
else {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, _power_up | ANT_TX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_TX | MIXER_ENB);
}
}
diff --git a/host/lib/usrp/dboard/db_sbx_common.cpp b/host/lib/usrp/dboard/db_sbx_common.cpp
index ce5166c4c..c575bba01 100644
--- a/host/lib/usrp/dboard/db_sbx_common.cpp
+++ b/host/lib/usrp/dboard/db_sbx_common.cpp
@@ -237,8 +237,8 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO));
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
- //flash LEDs
- flash_leds();
+ //Initialize ATR registers after direction and pin ctrl configuration
+ update_atr();
UHD_LOGV(often) << boost::format(
"SBX GPIO Direction: RX: 0x%08x, TX: 0x%08x"
@@ -265,39 +265,39 @@ void sbx_xcvr::update_atr(void){
//setup the tx atr (this does not change with antenna)
this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_IDLE, 0 | tx_lo_lpf_en \
+ gpio_atr::ATR_REG_IDLE, 0 | tx_lo_lpf_en \
| tx_ld_led | tx_ant_led | TX_POWER_UP | ANT_XX | TX_MIXER_DIS);
//setup the rx atr (this does not change with antenna)
this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_IDLE, rx_pga0_iobits | rx_lo_lpf_en \
+ gpio_atr::ATR_REG_IDLE, rx_pga0_iobits | rx_lo_lpf_en \
| rx_ld_led | rx_ant_led | RX_POWER_UP | ANT_XX | RX_MIXER_DIS);
//set the RX atr regs that change with antenna setting
this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_RX_ONLY, rx_pga0_iobits | rx_lo_lpf_en \
+ gpio_atr::ATR_REG_RX_ONLY, rx_pga0_iobits | rx_lo_lpf_en \
| rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_ENB \
| ((_rx_ant != "RX2")? ANT_TXRX : ANT_RX2));
this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_TX_ONLY, rx_pga0_iobits | rx_lo_lpf_en \
+ gpio_atr::ATR_REG_TX_ONLY, rx_pga0_iobits | rx_lo_lpf_en \
| rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_DIS \
| ((_rx_ant == "CAL")? ANT_TXRX : ANT_RX2));
this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_FULL_DUPLEX, rx_pga0_iobits | rx_lo_lpf_en \
+ gpio_atr::ATR_REG_FULL_DUPLEX, rx_pga0_iobits | rx_lo_lpf_en \
| rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_ENB \
| ((_rx_ant == "CAL")? ANT_TXRX : ANT_RX2));
//set the TX atr regs that change with antenna setting
this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_RX_ONLY, 0 | tx_lo_lpf_en \
+ gpio_atr::ATR_REG_RX_ONLY, 0 | tx_lo_lpf_en \
| tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_DIS \
| ((_rx_ant != "RX2")? ANT_RX : ANT_TX));
this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_TX_ONLY, tx_pga0_iobits | tx_lo_lpf_en \
+ gpio_atr::ATR_REG_TX_ONLY, tx_pga0_iobits | tx_lo_lpf_en \
| tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_ENB \
| ((_tx_ant == "CAL")? ANT_RX : ANT_TX));
this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_FULL_DUPLEX, tx_pga0_iobits | tx_lo_lpf_en \
+ gpio_atr::ATR_REG_FULL_DUPLEX, tx_pga0_iobits | tx_lo_lpf_en \
| tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_ENB \
| ((_tx_ant == "CAL")? ANT_RX : ANT_TX));
}
@@ -352,45 +352,3 @@ sensor_value_t sbx_xcvr::get_locked(dboard_iface::unit_t unit) {
return sensor_value_t("LO", locked, "locked", "unlocked");
}
-
-
-void sbx_xcvr::flash_leds(void) {
- //Remove LED gpios from ATR control temporarily and set to outputs
- this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, TXIO_MASK);
- this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXIO_MASK);
- this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK|RX_LED_IO));
- this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, TX_LED_LD, TX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, \
- TX_LED_TXRX|TX_LED_LD, TX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, RX_LED_LD, RX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, \
- RX_LED_RX1RX2|RX_LED_LD, RX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, RX_LED_LD, RX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, 0, RX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, TX_LED_LD, TX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, 0, TX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- //Put LED gpios back in ATR control and update atr
- this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO));
- this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
- this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO));
- this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
-}
-
diff --git a/host/lib/usrp/dboard/db_ubx.cpp b/host/lib/usrp/dboard/db_ubx.cpp
index 7cb4b2d6b..db9f21f43 100644
--- a/host/lib/usrp/dboard/db_ubx.cpp
+++ b/host/lib/usrp/dboard/db_ubx.cpp
@@ -26,6 +26,7 @@
#include <uhd/usrp/dboard_manager.hpp>
#include <uhd/utils/assert_has.hpp>
#include <uhd/utils/log.hpp>
+#include <uhd/utils/msg.hpp>
#include <uhd/utils/static.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/shared_ptr.hpp>
@@ -318,14 +319,14 @@ public:
write_gpio();
// Configure ATR
- _iface->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE, _tx_gpio_reg.atr_idle);
- _iface->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, _tx_gpio_reg.atr_tx);
- _iface->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY, _tx_gpio_reg.atr_rx);
- _iface->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, _tx_gpio_reg.atr_full_duplex);
- _iface->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, _rx_gpio_reg.atr_idle);
- _iface->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, _rx_gpio_reg.atr_tx);
- _iface->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, _rx_gpio_reg.atr_rx);
- _iface->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, _rx_gpio_reg.atr_full_duplex);
+ _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, _tx_gpio_reg.atr_idle);
+ _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _tx_gpio_reg.atr_tx);
+ _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, _tx_gpio_reg.atr_rx);
+ _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _tx_gpio_reg.atr_full_duplex);
+ _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, _rx_gpio_reg.atr_idle);
+ _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _rx_gpio_reg.atr_tx);
+ _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _rx_gpio_reg.atr_rx);
+ _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _rx_gpio_reg.atr_full_duplex);
// Engage ATR control (1 is ATR control, 0 is manual control)
_iface->set_pin_ctrl(dboard_iface::UNIT_TX, _tx_gpio_reg.atr_mask);
@@ -683,6 +684,20 @@ private:
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
UHD_LOGV(rarely) << boost::format("UBX TX: the requested frequency is %f MHz") % (freq/1e6) << std::endl;
+ double target_pfd_freq = _tx_target_pfd_freq;
+ if (is_int_n and tune_args.has_key("int_n_step"))
+ {
+ target_pfd_freq = tune_args.cast<double>("int_n_step", _tx_target_pfd_freq);
+ if (target_pfd_freq > _tx_target_pfd_freq)
+ {
+ UHD_MSG(warning)
+ << boost::format("Requested int_n_step of %f MHz too large, clipping to %f MHz")
+ % (target_pfd_freq/1e6)
+ % (_tx_target_pfd_freq/1e6)
+ << std::endl;
+ target_pfd_freq = _tx_target_pfd_freq;
+ }
+ }
// Clip the frequency to the valid range
freq = ubx_freq_range.clip(freq);
@@ -704,10 +719,10 @@ private:
set_cpld_field(TXLB_SEL, 1);
set_cpld_field(TXHB_SEL, 0);
// Set LO1 to IF of 2100 MHz (offset from RX IF to reduce leakage)
- freq_lo1 = _txlo1->set_frequency(2100*fMHz, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo1 = _txlo1->set_frequency(2100*fMHz, ref_freq, target_pfd_freq, is_int_n);
_txlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
// Set LO2 to IF minus desired frequency
- freq_lo2 = _txlo2->set_frequency(freq_lo1 - freq, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo2 = _txlo2->set_frequency(freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n);
_txlo2->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= (500*fMHz)) && (freq <= (800*fMHz)))
@@ -717,7 +732,7 @@ private:
set_cpld_field(TXLO1_FSEL1, 1);
set_cpld_field(TXLB_SEL, 0);
set_cpld_field(TXHB_SEL, 1);
- freq_lo1 = _txlo1->set_frequency(freq, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_txlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq > (800*fMHz)) && (freq <= (1000*fMHz)))
@@ -727,7 +742,7 @@ private:
set_cpld_field(TXLO1_FSEL1, 1);
set_cpld_field(TXLB_SEL, 0);
set_cpld_field(TXHB_SEL, 1);
- freq_lo1 = _txlo1->set_frequency(freq, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_txlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
}
else if ((freq > (1000*fMHz)) && (freq <= (2200*fMHz)))
@@ -737,7 +752,7 @@ private:
set_cpld_field(TXLO1_FSEL1, 0);
set_cpld_field(TXLB_SEL, 0);
set_cpld_field(TXHB_SEL, 1);
- freq_lo1 = _txlo1->set_frequency(freq, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_txlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq > (2200*fMHz)) && (freq <= (2500*fMHz)))
@@ -747,7 +762,7 @@ private:
set_cpld_field(TXLO1_FSEL1, 0);
set_cpld_field(TXLB_SEL, 0);
set_cpld_field(TXHB_SEL, 1);
- freq_lo1 = _txlo1->set_frequency(freq, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_txlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq > (2500*fMHz)) && (freq <= (6000*fMHz)))
@@ -757,7 +772,7 @@ private:
set_cpld_field(TXLO1_FSEL1, 0);
set_cpld_field(TXLB_SEL, 0);
set_cpld_field(TXHB_SEL, 1);
- freq_lo1 = _txlo1->set_frequency(freq, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_txlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
}
@@ -825,6 +840,20 @@ private:
property_tree::sptr subtree = this->get_rx_subtree();
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
+ double target_pfd_freq = _rx_target_pfd_freq;
+ if (is_int_n and tune_args.has_key("int_n_step"))
+ {
+ target_pfd_freq = tune_args.cast<double>("int_n_step", _rx_target_pfd_freq);
+ if (target_pfd_freq > _rx_target_pfd_freq)
+ {
+ UHD_MSG(warning)
+ << boost::format("Requested int_n_step of %f Mhz too large, clipping to %f MHz")
+ % (target_pfd_freq/1e6)
+ % (_rx_target_pfd_freq/1e6)
+ << std::endl;
+ target_pfd_freq = _rx_target_pfd_freq;
+ }
+ }
// Clip the frequency to the valid range
freq = ubx_freq_range.clip(freq);
@@ -848,10 +877,10 @@ private:
set_cpld_field(RXLB_SEL, 1);
set_cpld_field(RXHB_SEL, 0);
// Set LO1 to IF of 2380 MHz (2440 MHz filter center minus 60 MHz offset to minimize LO leakage)
- freq_lo1 = _rxlo1->set_frequency(2380*fMHz, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(2380*fMHz, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
// Set LO2 to IF minus desired frequency
- freq_lo2 = _rxlo2->set_frequency(freq_lo1 - freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo2 = _rxlo2->set_frequency(freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo2->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= 100*fMHz) && (freq < 500*fMHz))
@@ -864,10 +893,10 @@ private:
set_cpld_field(RXLB_SEL, 1);
set_cpld_field(RXHB_SEL, 0);
// Set LO1 to IF of 2440 (center of filter)
- freq_lo1 = _rxlo1->set_frequency(2440*fMHz, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(2440*fMHz, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
// Set LO2 to IF minus desired frequency
- freq_lo2 = _rxlo2->set_frequency(freq_lo1 - freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo2 = _rxlo2->set_frequency(freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= 500*fMHz) && (freq < 800*fMHz))
@@ -879,7 +908,7 @@ private:
set_cpld_field(RXLO1_FSEL1, 1);
set_cpld_field(RXLB_SEL, 0);
set_cpld_field(RXHB_SEL, 1);
- freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= 800*fMHz) && (freq < 1000*fMHz))
@@ -891,7 +920,7 @@ private:
set_cpld_field(RXLO1_FSEL1, 1);
set_cpld_field(RXLB_SEL, 0);
set_cpld_field(RXHB_SEL, 1);
- freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
}
else if ((freq >= 1000*fMHz) && (freq < 1500*fMHz))
@@ -903,7 +932,7 @@ private:
set_cpld_field(RXLO1_FSEL1, 0);
set_cpld_field(RXLB_SEL, 0);
set_cpld_field(RXHB_SEL, 1);
- freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= 1500*fMHz) && (freq < 2200*fMHz))
@@ -915,7 +944,7 @@ private:
set_cpld_field(RXLO1_FSEL1, 0);
set_cpld_field(RXLB_SEL, 0);
set_cpld_field(RXHB_SEL, 1);
- freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= 2200*fMHz) && (freq < 2500*fMHz))
@@ -927,7 +956,7 @@ private:
set_cpld_field(RXLO1_FSEL1, 0);
set_cpld_field(RXLB_SEL, 0);
set_cpld_field(RXHB_SEL, 1);
- freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= 2500*fMHz) && (freq <= 6000*fMHz))
@@ -939,7 +968,7 @@ private:
set_cpld_field(RXLO1_FSEL1, 0);
set_cpld_field(RXLB_SEL, 0);
set_cpld_field(RXHB_SEL, 1);
- freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
}
diff --git a/host/lib/usrp/dboard/db_wbx_simple.cpp b/host/lib/usrp/dboard/db_wbx_simple.cpp
index c8f2be155..dda2def95 100644
--- a/host/lib/usrp/dboard/db_wbx_simple.cpp
+++ b/host/lib/usrp/dboard/db_wbx_simple.cpp
@@ -112,14 +112,14 @@ wbx_simple::wbx_simple(ctor_args_t args) : wbx_base(args){
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, ANTSW_IO, ANTSW_IO);
//setup ATR for the antenna switches (constant)
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE, ANT_RX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY, ANT_RX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO);
-
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, ANT_TXRX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, ANT_RX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, ANT_RX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO);
+
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, ANT_TXRX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO);
}
wbx_simple::~wbx_simple(void){
@@ -138,14 +138,14 @@ void wbx_simple::set_rx_ant(const std::string &ant){
//write the new antenna setting to atr regs
if (_rx_ant == "CAL") {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, ANT_TXRX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_TXRX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, ANT_TXRX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_TXRX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TXRX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, ANT_TXRX, ANTSW_IO);
}
else {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, ((_rx_ant == "TX/RX")? ANT_TXRX : ANT_RX2), ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, ((_rx_ant == "TX/RX")? ANT_TXRX : ANT_RX2), ANTSW_IO);
}
}
@@ -154,11 +154,11 @@ void wbx_simple::set_tx_ant(const std::string &ant){
//write the new antenna setting to atr regs
if (ant == "CAL") {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, ANT_RX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_RX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX, ANTSW_IO);
}
else {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO);
}
}
diff --git a/host/lib/usrp/dboard/db_wbx_version2.cpp b/host/lib/usrp/dboard/db_wbx_version2.cpp
index 93047fb7a..78b5b2871 100644
--- a/host/lib/usrp/dboard/db_wbx_version2.cpp
+++ b/host/lib/usrp/dboard/db_wbx_version2.cpp
@@ -117,15 +117,15 @@ wbx_base::wbx_version2::wbx_version2(wbx_base *_self_wbx_base) {
self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, RX_PUP_5V|RX_PUP_3V|ADF435X_CE|RXBB_PDB|ADF435X_PDBRF|RX_ATTN_MASK);
//setup ATR for the mixer enables (always enabled to prevent phase slip between bursts)
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
-
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
+
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
}
wbx_base::wbx_version2::~wbx_version2(void){
diff --git a/host/lib/usrp/dboard/db_wbx_version3.cpp b/host/lib/usrp/dboard/db_wbx_version3.cpp
index 6927ae4e4..a5821ffc2 100644
--- a/host/lib/usrp/dboard/db_wbx_version3.cpp
+++ b/host/lib/usrp/dboard/db_wbx_version3.cpp
@@ -129,29 +129,29 @@ wbx_base::wbx_version3::wbx_version3(wbx_base *_self_wbx_base) {
//slip between bursts). set TX gain iobits to min gain (max attenuation)
//when RX_ONLY or IDLE to suppress LO leakage
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_IDLE, v3_tx_mod, \
+ gpio_atr::ATR_REG_IDLE, v3_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_RX_ONLY, v3_tx_mod, \
+ gpio_atr::ATR_REG_RX_ONLY, v3_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_TX_ONLY, v3_tx_mod, \
+ gpio_atr::ATR_REG_TX_ONLY, v3_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_FULL_DUPLEX, v3_tx_mod, \
+ gpio_atr::ATR_REG_FULL_DUPLEX, v3_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_IDLE, \
+ gpio_atr::ATR_REG_IDLE, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_TX_ONLY, \
+ gpio_atr::ATR_REG_TX_ONLY, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_RX_ONLY, \
+ gpio_atr::ATR_REG_RX_ONLY, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_FULL_DUPLEX, \
+ gpio_atr::ATR_REG_FULL_DUPLEX, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
}
@@ -181,8 +181,8 @@ double wbx_base::wbx_version3::set_tx_gain(double gain, const std::string &name)
//write the new gain to tx gpio outputs
//Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR states
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK);
}
else UHD_THROW_INVALID_CODE_PATH();
return self_base->_tx_gains[name]; //shadow
diff --git a/host/lib/usrp/dboard/db_wbx_version4.cpp b/host/lib/usrp/dboard/db_wbx_version4.cpp
index 81cdaefac..327ae675b 100644
--- a/host/lib/usrp/dboard/db_wbx_version4.cpp
+++ b/host/lib/usrp/dboard/db_wbx_version4.cpp
@@ -136,29 +136,29 @@ wbx_base::wbx_version4::wbx_version4(wbx_base *_self_wbx_base) {
//between bursts) set TX gain iobits to min gain (max attenuation) when
//RX_ONLY or IDLE to suppress LO leakage
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_IDLE, v4_tx_mod, \
+ gpio_atr::ATR_REG_IDLE, v4_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_RX_ONLY, v4_tx_mod, \
+ gpio_atr::ATR_REG_RX_ONLY, v4_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_TX_ONLY, v4_tx_mod, \
+ gpio_atr::ATR_REG_TX_ONLY, v4_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_FULL_DUPLEX, v4_tx_mod, \
+ gpio_atr::ATR_REG_FULL_DUPLEX, v4_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_IDLE, \
+ gpio_atr::ATR_REG_IDLE, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_TX_ONLY, \
+ gpio_atr::ATR_REG_TX_ONLY, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_RX_ONLY, \
+ gpio_atr::ATR_REG_RX_ONLY, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_FULL_DUPLEX, \
+ gpio_atr::ATR_REG_FULL_DUPLEX, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
}
@@ -188,8 +188,8 @@ double wbx_base::wbx_version4::set_tx_gain(double gain, const std::string &name)
//write the new gain to tx gpio outputs
//Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR states
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK);
}
else UHD_THROW_INVALID_CODE_PATH();
diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp
index 50c67991a..092f84548 100644
--- a/host/lib/usrp/dboard/db_xcvr2450.cpp
+++ b/host/lib/usrp/dboard/db_xcvr2450.cpp
@@ -315,12 +315,12 @@ xcvr2450::~xcvr2450(void){
void xcvr2450::spi_reset(void){
//spi reset mode: global enable = off, tx and rx enable = on
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE, TX_ENB_TXIO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, RX_ENB_RXIO | POWER_DOWN_RXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, TX_ENB_TXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_ENB_RXIO | POWER_DOWN_RXIO);
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
//take it back out of spi reset mode and wait a bit
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, RX_DIS_RXIO | POWER_UP_RXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_DIS_RXIO | POWER_UP_RXIO);
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
}
@@ -337,16 +337,16 @@ void xcvr2450::update_atr(void){
int ad9515div = (_ad9515div == 3)? AD9515DIV_3_TXIO : AD9515DIV_2_TXIO;
//set the tx registers
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE, band_sel | ad9515div | TX_DIS_TXIO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY, band_sel | ad9515div | TX_DIS_TXIO | rx_ant_sel);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, band_sel | ad9515div | TX_ENB_TXIO | tx_ant_sel);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, band_sel | ad9515div | TX_ENB_TXIO | xx_ant_sel);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, band_sel | ad9515div | TX_DIS_TXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, band_sel | ad9515div | TX_DIS_TXIO | rx_ant_sel);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, band_sel | ad9515div | TX_ENB_TXIO | tx_ant_sel);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, band_sel | ad9515div | TX_ENB_TXIO | xx_ant_sel);
//set the rx registers
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, POWER_UP_RXIO | RX_DIS_RXIO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, POWER_UP_RXIO | RX_ENB_RXIO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, POWER_UP_RXIO | RX_DIS_RXIO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, POWER_UP_RXIO | RX_DIS_RXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, POWER_UP_RXIO | RX_DIS_RXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, POWER_UP_RXIO | RX_ENB_RXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, POWER_UP_RXIO | RX_DIS_RXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, POWER_UP_RXIO | RX_DIS_RXIO);
}
/***********************************************************************
diff --git a/host/lib/usrp/e300/e300_fpga_defs.hpp b/host/lib/usrp/e300/e300_fpga_defs.hpp
index a8fa60d9d..3b21468ba 100644
--- a/host/lib/usrp/e300/e300_fpga_defs.hpp
+++ b/host/lib/usrp/e300/e300_fpga_defs.hpp
@@ -21,7 +21,7 @@ namespace uhd { namespace usrp { namespace e300 { namespace fpga {
static const size_t NUM_RADIOS = 2;
-static const boost::uint32_t COMPAT_MAJOR = 11;
+static const boost::uint32_t COMPAT_MAJOR = 12;
static const boost::uint32_t COMPAT_MINOR = 0;
}}}} // namespace
diff --git a/host/lib/usrp/e300/e300_impl.cpp b/host/lib/usrp/e300/e300_impl.cpp
index 6d66e83c0..c82ab3d0e 100644
--- a/host/lib/usrp/e300/e300_impl.cpp
+++ b/host/lib/usrp/e300/e300_impl.cpp
@@ -48,6 +48,7 @@
using namespace uhd;
using namespace uhd::usrp;
+using namespace uhd::usrp::gpio_atr;
using namespace uhd::transport;
namespace fs = boost::filesystem;
namespace asio = boost::asio;
@@ -512,15 +513,15 @@ e300_impl::e300_impl(const uhd::device_addr_t &device_addr)
////////////////////////////////////////////////////////////////////
// internal gpios
////////////////////////////////////////////////////////////////////
- gpio_core_200::sptr fp_gpio = gpio_core_200::make(_radio_perifs[0].ctrl, radio::sr_addr(radio::FP_GPIO), radio::RB32_FP_GPIO);
+ gpio_atr_3000::sptr fp_gpio = gpio_atr_3000::make(_radio_perifs[0].ctrl, radio::sr_addr(radio::FP_GPIO), radio::RB32_FP_GPIO);
BOOST_FOREACH(const gpio_attr_map_t::value_type attr, gpio_attr_map)
{
_tree->create<boost::uint32_t>(mb_path / "gpio" / "INT0" / attr.second)
- .subscribe(boost::bind(&e300_impl::_set_internal_gpio, this, fp_gpio, attr.first, _1))
+ .subscribe(boost::bind(&gpio_atr_3000::set_gpio_attr, fp_gpio, attr.first, _1))
.set(0);
}
_tree->create<boost::uint8_t>(mb_path / "gpio" / "INT0" / "READBACK")
- .publish(boost::bind(&e300_impl::_get_internal_gpio, this, fp_gpio));
+ .publish(boost::bind(&gpio_atr_3000::read_gpio, fp_gpio));
////////////////////////////////////////////////////////////////////
@@ -623,37 +624,6 @@ e300_impl::e300_impl(const uhd::device_addr_t &device_addr)
_tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(tx_spec);
}
-boost::uint8_t e300_impl::_get_internal_gpio(gpio_core_200::sptr gpio)
-{
- return boost::uint32_t(gpio->read_gpio(dboard_iface::UNIT_RX));
-}
-
-void e300_impl::_set_internal_gpio(
- gpio_core_200::sptr gpio,
- const gpio_attr_t attr,
- const boost::uint32_t value)
-{
- switch (attr)
- {
- case GPIO_CTRL:
- return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value);
- case GPIO_DDR:
- return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value);
- case GPIO_OUT:
- return gpio->set_gpio_out(dboard_iface::UNIT_RX, value);
- case GPIO_ATR_0X:
- return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value);
- case GPIO_ATR_RX:
- return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value);
- case GPIO_ATR_TX:
- return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value);
- case GPIO_ATR_XX:
- return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value);
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
uhd::sensor_value_t e300_impl::_get_fe_pll_lock(const bool is_tx)
{
const boost::uint32_t st =
@@ -978,7 +948,8 @@ void e300_impl::_setup_radio(const size_t dspno)
////////////////////////////////////////////////////////////////////
// Set up peripherals
////////////////////////////////////////////////////////////////////
- perif.atr = gpio_core_200_32wo::make(perif.ctrl, radio::sr_addr(radio::GPIO));
+ perif.atr = gpio_atr_3000::make_write_only(perif.ctrl, radio::sr_addr(radio::GPIO));
+ perif.atr->set_atr_mode(MODE_ATR, 0xFFFFFFFF);
perif.rx_fe = rx_frontend_core_200::make(perif.ctrl, radio::sr_addr(radio::RX_FRONT));
perif.rx_fe->set_dc_offset(rx_frontend_core_200::DEFAULT_DC_OFFSET_VALUE);
perif.rx_fe->set_dc_offset_auto(rx_frontend_core_200::DEFAULT_DC_OFFSET_ENABLE);
@@ -1027,7 +998,6 @@ void e300_impl::_setup_radio(const size_t dspno)
// create tx dsp control objects
////////////////////////////////////////////////////////////////////
_tree->access<double>(mb_path / "tick_rate")
- .subscribe(boost::bind(&tx_vita_core_3000::set_tick_rate, perif.deframer, _1))
.subscribe(boost::bind(&tx_dsp_core_3000::set_tick_rate, perif.duc, _1));
const fs_path tx_dsp_path = mb_path / "tx_dsps" / str(boost::format("%u") % dspno);
perif.duc->populate_subtree(_tree->subtree(tx_dsp_path));
@@ -1291,11 +1261,11 @@ void e300_impl::_update_atrs(void)
if (enb_tx)
fd_reg |= tx_enables | xx_leds;
- gpio_core_200_32wo::sptr atr = _radio_perifs[instance].atr;
- atr->set_atr_reg(dboard_iface::ATR_REG_IDLE, oo_reg);
- atr->set_atr_reg(dboard_iface::ATR_REG_RX_ONLY, rx_reg);
- atr->set_atr_reg(dboard_iface::ATR_REG_TX_ONLY, tx_reg);
- atr->set_atr_reg(dboard_iface::ATR_REG_FULL_DUPLEX, fd_reg);
+ gpio_atr_3000::sptr atr = _radio_perifs[instance].atr;
+ atr->set_atr_reg(ATR_REG_IDLE, oo_reg);
+ atr->set_atr_reg(ATR_REG_RX_ONLY, rx_reg);
+ atr->set_atr_reg(ATR_REG_TX_ONLY, tx_reg);
+ atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd_reg);
}
}
diff --git a/host/lib/usrp/e300/e300_impl.hpp b/host/lib/usrp/e300/e300_impl.hpp
index 8aff51466..9b39c7468 100644
--- a/host/lib/usrp/e300/e300_impl.hpp
+++ b/host/lib/usrp/e300/e300_impl.hpp
@@ -41,7 +41,7 @@
#include "tx_dsp_core_3000.hpp"
#include "ad9361_ctrl.hpp"
#include "ad936x_manager.hpp"
-#include "gpio_core_200.hpp"
+#include "gpio_atr_3000.hpp"
#include "e300_global_regs.hpp"
#include "e300_i2c.hpp"
@@ -146,7 +146,7 @@ private: // types
struct radio_perifs_t
{
radio_ctrl_core_3000::sptr ctrl;
- gpio_core_200_32wo::sptr atr;
+ gpio_atr::gpio_atr_3000::sptr atr;
time_core_3000::sptr time64;
rx_vita_core_3000::sptr framer;
rx_dsp_core_3000::sptr ddc;
@@ -277,14 +277,6 @@ private: // methods
// get frontend lock sensor
uhd::sensor_value_t _get_fe_pll_lock(const bool is_tx);
- // internal gpios
- boost::uint8_t _get_internal_gpio(gpio_core_200::sptr);
-
- void _set_internal_gpio(
- gpio_core_200::sptr gpio,
- const gpio_attr_t attr,
- const boost::uint32_t value);
-
private: // members
uhd::device_addr_t _device_addr;
xport_t _xport_path;
diff --git a/host/lib/usrp/e300/e300_io_impl.cpp b/host/lib/usrp/e300/e300_io_impl.cpp
index 29d250c8f..209a73077 100644
--- a/host/lib/usrp/e300/e300_io_impl.cpp
+++ b/host/lib/usrp/e300/e300_io_impl.cpp
@@ -87,7 +87,6 @@ void e300_impl::_update_tick_rate(const double rate)
boost::dynamic_pointer_cast<sph::send_packet_streamer>(perif.tx_streamer.lock());
if (my_streamer)
my_streamer->set_tick_rate(rate);
- perif.deframer->set_tick_rate(_tick_rate);
}
}
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index 396237e24..dbc0ebed2 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -438,8 +438,10 @@ public:
******************************************************************/
void set_master_clock_rate(double rate, size_t mboard){
if (mboard != ALL_MBOARDS){
- if (_tree->exists(mb_root(mboard) / "auto_tick_rate")) {
+ if (_tree->exists(mb_root(mboard) / "auto_tick_rate")
+ and _tree->access<bool>(mb_root(mboard) / "auto_tick_rate").get()) {
_tree->access<bool>(mb_root(mboard) / "auto_tick_rate").set(false);
+ UHD_MSG(status) << "Setting master clock rate selection to 'manual'." << std::endl;
}
_tree->access<double>(mb_root(mboard) / "tick_rate").set(rate);
return;
@@ -1346,10 +1348,10 @@ public:
if (attr == "CTRL") iface->set_pin_ctrl(unit, boost::uint16_t(value), boost::uint16_t(mask));
if (attr == "DDR") iface->set_gpio_ddr(unit, boost::uint16_t(value), boost::uint16_t(mask));
if (attr == "OUT") iface->set_gpio_out(unit, boost::uint16_t(value), boost::uint16_t(mask));
- if (attr == "ATR_0X") iface->set_atr_reg(unit, dboard_iface::ATR_REG_IDLE, boost::uint16_t(value), boost::uint16_t(mask));
- if (attr == "ATR_RX") iface->set_atr_reg(unit, dboard_iface::ATR_REG_RX_ONLY, boost::uint16_t(value), boost::uint16_t(mask));
- if (attr == "ATR_TX") iface->set_atr_reg(unit, dboard_iface::ATR_REG_TX_ONLY, boost::uint16_t(value), boost::uint16_t(mask));
- if (attr == "ATR_XX") iface->set_atr_reg(unit, dboard_iface::ATR_REG_FULL_DUPLEX, boost::uint16_t(value), boost::uint16_t(mask));
+ if (attr == "ATR_0X") iface->set_atr_reg(unit, gpio_atr::ATR_REG_IDLE, boost::uint16_t(value), boost::uint16_t(mask));
+ if (attr == "ATR_RX") iface->set_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY, boost::uint16_t(value), boost::uint16_t(mask));
+ if (attr == "ATR_TX") iface->set_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY, boost::uint16_t(value), boost::uint16_t(mask));
+ if (attr == "ATR_XX") iface->set_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX, boost::uint16_t(value), boost::uint16_t(mask));
}
}
@@ -1367,10 +1369,10 @@ public:
if (attr == "CTRL") return iface->get_pin_ctrl(unit);
if (attr == "DDR") return iface->get_gpio_ddr(unit);
if (attr == "OUT") return iface->get_gpio_out(unit);
- if (attr == "ATR_0X") return iface->get_atr_reg(unit, dboard_iface::ATR_REG_IDLE);
- if (attr == "ATR_RX") return iface->get_atr_reg(unit, dboard_iface::ATR_REG_RX_ONLY);
- if (attr == "ATR_TX") return iface->get_atr_reg(unit, dboard_iface::ATR_REG_TX_ONLY);
- if (attr == "ATR_XX") return iface->get_atr_reg(unit, dboard_iface::ATR_REG_FULL_DUPLEX);
+ if (attr == "ATR_0X") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_IDLE);
+ if (attr == "ATR_RX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY);
+ if (attr == "ATR_TX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY);
+ if (attr == "ATR_XX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX);
if (attr == "READBACK") return iface->read_gpio(unit);
}
return 0;
diff --git a/host/lib/usrp/usrp1/dboard_iface.cpp b/host/lib/usrp/usrp1/dboard_iface.cpp
index 4c3141d9e..502d0fbe3 100644
--- a/host/lib/usrp/usrp1/dboard_iface.cpp
+++ b/host/lib/usrp/usrp1/dboard_iface.cpp
@@ -63,6 +63,7 @@
using namespace uhd;
using namespace uhd::usrp;
+using namespace uhd::usrp::gpio_atr;
using namespace boost::assign;
static const dboard_id_t tvrx_id(0x0040);
diff --git a/host/lib/usrp/x300/x300_fw_common.h b/host/lib/usrp/x300/x300_fw_common.h
index 1b88db69a..cc3f81401 100644
--- a/host/lib/usrp/x300/x300_fw_common.h
+++ b/host/lib/usrp/x300/x300_fw_common.h
@@ -33,7 +33,7 @@ extern "C" {
#define X300_REVISION_MIN 2
#define X300_FW_COMPAT_MAJOR 4
#define X300_FW_COMPAT_MINOR 0
-#define X300_FPGA_COMPAT_MAJOR 15
+#define X300_FPGA_COMPAT_MAJOR 17
//shared memory sections - in between the stack and the program space
#define X300_FW_SHMEM_BASE 0x6000
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index 1e424414e..0483ecf11 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -47,23 +47,38 @@ using namespace uhd;
using namespace uhd::usrp;
using namespace uhd::transport;
using namespace uhd::niusrprio;
+using namespace uhd::usrp::gpio_atr;
using namespace uhd::usrp::x300;
namespace asio = boost::asio;
-/***********************************************************************
- * Discovery over the udp and pcie transport
- **********************************************************************/
+static bool has_dram_buff(wb_iface::sptr zpu_ctrl) {
+ bool dramR0 = dma_fifo_core_3000::check(
+ zpu_ctrl, SR_ADDR(SET0_BASE, ZPU_SR_DRAM_FIFO0), SR_ADDR(SET0_BASE, ZPU_RB_DRAM_FIFO0));
+ bool dramR1 = dma_fifo_core_3000::check(
+ zpu_ctrl, SR_ADDR(SET0_BASE, ZPU_SR_DRAM_FIFO1), SR_ADDR(SET0_BASE, ZPU_RB_DRAM_FIFO1));
+ return (dramR0 and dramR1);
+}
+
static std::string get_fpga_option(wb_iface::sptr zpu_ctrl) {
- //1G = {0:1G, 1:1G} w/ DRAM, HG = {0:1G, 1:10G} w/ DRAM, XG = {0:10G, 1:10G} w/ DRAM
- //HGS = {0:1G, 1:10G} w/ SRAM, XGS = {0:10G, 1:10G} w/ SRAM
+ //Possible options:
+ //1G = {0:1G, 1:1G} w/ DRAM, HG = {0:1G, 1:10G} w/ DRAM, XG = {0:10G, 1:10G} w/ DRAM
+ //1GS = {0:1G, 1:1G} w/ SRAM, HGS = {0:1G, 1:10G} w/ SRAM, XGS = {0:10G, 1:10G} w/ SRAM
- //In the default configuration, UHD does not support the HG and XG images so
- //they are never autodetected.
+ std::string option;
bool eth0XG = (zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_ETH_TYPE0)) == 0x1);
bool eth1XG = (zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_ETH_TYPE1)) == 0x1);
- return (eth0XG && eth1XG) ? "XGS" : (eth1XG ? "HGS" : "1G");
+ option = (eth0XG && eth1XG) ? "XG" : (eth1XG ? "HG" : "1G");
+
+ if (not has_dram_buff(zpu_ctrl)) {
+ option += "S";
+ }
+ return option;
}
+/***********************************************************************
+ * Discovery over the udp and pcie transport
+ **********************************************************************/
+
//@TODO: Refactor the find functions to collapse common code for ethernet and PCIe
static device_addrs_t x300_find_with_addr(const device_addr_t &hint)
{
@@ -729,6 +744,36 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
}
////////////////////////////////////////////////////////////////////
+ // DRAM FIFO initialization
+ ////////////////////////////////////////////////////////////////////
+ mb.has_dram_buff = has_dram_buff(mb.zpu_ctrl);
+ if (mb.has_dram_buff) {
+ for (size_t i = 0; i < mboard_members_t::NUM_RADIOS; i++) {
+ static const size_t NUM_REGS = 8;
+ mb.dram_buff_ctrl[i] = dma_fifo_core_3000::make(
+ mb.zpu_ctrl,
+ SR_ADDR(SET0_BASE, ZPU_SR_DRAM_FIFO0+(i*NUM_REGS)),
+ SR_ADDR(SET0_BASE, ZPU_RB_DRAM_FIFO0+i));
+ mb.dram_buff_ctrl[i]->resize(X300_DRAM_FIFO_SIZE * i, X300_DRAM_FIFO_SIZE);
+
+ if (mb.dram_buff_ctrl[i]->ext_bist_supported()) {
+ UHD_MSG(status) << boost::format("Running BIST for DRAM FIFO %d... ") % i;
+ boost::uint32_t bisterr = mb.dram_buff_ctrl[i]->run_bist();
+ if (bisterr != 0) {
+ throw uhd::runtime_error(str(boost::format("DRAM FIFO BIST failed! (code: %d)\n") % bisterr));
+ } else {
+ double throughput = mb.dram_buff_ctrl[i]->get_bist_throughput(X300_BUS_CLOCK_RATE);
+ UHD_MSG(status) << (boost::format("pass (Throughput: %.1fMB/s)") % (throughput/1e6)) << std::endl;
+ }
+ } else {
+ if (mb.dram_buff_ctrl[i]->run_bist() != 0) {
+ throw uhd::runtime_error(str(boost::format("DRAM FIFO %d BIST failed!\n") % i));
+ }
+ }
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////
// setup radios
////////////////////////////////////////////////////////////////////
this->setup_radio(mb_i, "A", dev_addr);
@@ -749,15 +794,15 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
////////////////////////////////////////////////////////////////////
// front panel gpio
////////////////////////////////////////////////////////////////////
- mb.fp_gpio = gpio_core_200::make(mb.radio_perifs[0].ctrl, radio::sr_addr(radio::FP_GPIO), radio::RB32_FP_GPIO);
+ mb.fp_gpio = gpio_atr_3000::make(mb.radio_perifs[0].ctrl, radio::sr_addr(radio::FP_GPIO), radio::RB32_FP_GPIO);
BOOST_FOREACH(const gpio_attr_map_t::value_type attr, gpio_attr_map)
{
_tree->create<boost::uint32_t>(mb_path / "gpio" / "FP0" / attr.second)
.set(0)
- .subscribe(boost::bind(&x300_impl::set_fp_gpio, this, mb.fp_gpio, attr.first, _1));
+ .subscribe(boost::bind(&gpio_atr_3000::set_gpio_attr, mb.fp_gpio, attr.first, _1));
}
_tree->create<boost::uint32_t>(mb_path / "gpio" / "FP0" / "READBACK")
- .publish(boost::bind(&x300_impl::get_fp_gpio, this, mb.fp_gpio));
+ .publish(boost::bind(&gpio_atr_3000::read_gpio, mb.fp_gpio));
////////////////////////////////////////////////////////////////////
// register the time keepers - only one can be the highlander
@@ -930,7 +975,8 @@ void x300_impl::setup_radio(const size_t mb_i, const std::string &slot_name, con
perif.spi = spi_core_3000::make(perif.ctrl, radio::sr_addr(radio::SPI), radio::RB32_SPI);
perif.adc = x300_adc_ctrl::make(perif.spi, DB_ADC_SEN);
perif.dac = x300_dac_ctrl::make(perif.spi, DB_DAC_SEN, mb.clock->get_master_clock_rate());
- perif.leds = gpio_core_200_32wo::make(perif.ctrl, radio::sr_addr(radio::LEDS));
+ perif.leds = gpio_atr_3000::make_write_only(perif.ctrl, radio::sr_addr(radio::LEDS));
+ perif.leds->set_atr_mode(MODE_ATR, 0xFFFFFFFF);
perif.rx_fe = rx_frontend_core_200::make(perif.ctrl, radio::sr_addr(radio::RX_FRONT));
perif.rx_fe->set_dc_offset(rx_frontend_core_200::DEFAULT_DC_OFFSET_VALUE);
perif.rx_fe->set_dc_offset_auto(rx_frontend_core_200::DEFAULT_DC_OFFSET_ENABLE);
@@ -940,7 +986,10 @@ void x300_impl::setup_radio(const size_t mb_i, const std::string &slot_name, con
perif.framer = rx_vita_core_3000::make(perif.ctrl, radio::sr_addr(radio::RX_CTRL));
perif.ddc = rx_dsp_core_3000::make(perif.ctrl, radio::sr_addr(radio::RX_DSP));
perif.ddc->set_link_rate(10e9/8); //whatever
- perif.deframer = tx_vita_core_3000::make(perif.ctrl, radio::sr_addr(radio::TX_CTRL));
+ //The DRAM FIFO is treated as in internal radio FIFO for flow control purposes
+ tx_vita_core_3000::fc_monitor_loc fc_loc =
+ mb.has_dram_buff ? tx_vita_core_3000::FC_PRE_FIFO : tx_vita_core_3000::FC_PRE_RADIO;
+ perif.deframer = tx_vita_core_3000::make(perif.ctrl, radio::sr_addr(radio::TX_CTRL), fc_loc);
perif.duc = tx_dsp_core_3000::make(perif.ctrl, radio::sr_addr(radio::TX_DSP));
perif.duc->set_link_rate(10e9/8); //whatever
@@ -1014,7 +1063,7 @@ void x300_impl::setup_radio(const size_t mb_i, const std::string &slot_name, con
//create a new dboard interface
x300_dboard_iface_config_t db_config;
- db_config.gpio = gpio_core_200::make(perif.ctrl, radio::sr_addr(radio::GPIO), radio::RB32_GPIO);
+ db_config.gpio = db_gpio_atr_3000::make(perif.ctrl, radio::sr_addr(radio::GPIO), radio::RB32_GPIO);
db_config.spi = perif.spi;
db_config.rx_spi_slaveno = DB_RX_SEN;
db_config.tx_spi_slaveno = DB_TX_SEN;
@@ -1143,7 +1192,7 @@ x300_impl::both_xports_t x300_impl::make_transport(
* connection type.*/
size_t eth_data_rec_frame_size = 0;
- if (mb.loaded_fpga_image == "HGS") {
+ if (mb.loaded_fpga_image.substr(0,2) == "HG") {
if (mb.router_dst_here == X300_XB_DST_E0) {
eth_data_rec_frame_size = X300_1GE_DATA_FRAME_MAX_SIZE;
_tree->access<double>("/mboards/"+boost::lexical_cast<std::string>(mb_index) / "link_max_rate").set(X300_MAX_RATE_1GIGE);
@@ -1151,7 +1200,7 @@ x300_impl::both_xports_t x300_impl::make_transport(
eth_data_rec_frame_size = X300_10GE_DATA_FRAME_MAX_SIZE;
_tree->access<double>("/mboards/"+boost::lexical_cast<std::string>(mb_index) / "link_max_rate").set(X300_MAX_RATE_10GIGE);
}
- } else if (mb.loaded_fpga_image == "XGS") {
+ } else if (mb.loaded_fpga_image.substr(0,2) == "XG") {
eth_data_rec_frame_size = X300_10GE_DATA_FRAME_MAX_SIZE;
_tree->access<double>("/mboards/"+boost::lexical_cast<std::string>(mb_index) / "link_max_rate").set(X300_MAX_RATE_10GIGE);
}
@@ -1295,16 +1344,16 @@ boost::uint32_t x300_impl::allocate_sid(mboard_members_t &mb, const sid_config_t
return sid;
}
-void x300_impl::update_atr_leds(gpio_core_200_32wo::sptr leds, const std::string &rx_ant)
+void x300_impl::update_atr_leds(gpio_atr_3000::sptr leds, const std::string &rx_ant)
{
const bool is_txrx = (rx_ant == "TX/RX");
const int rx_led = (1 << 2);
const int tx_led = (1 << 1);
const int txrx_led = (1 << 0);
- leds->set_atr_reg(dboard_iface::ATR_REG_IDLE, 0);
- leds->set_atr_reg(dboard_iface::ATR_REG_RX_ONLY, is_txrx? txrx_led : rx_led);
- leds->set_atr_reg(dboard_iface::ATR_REG_TX_ONLY, tx_led);
- leds->set_atr_reg(dboard_iface::ATR_REG_FULL_DUPLEX, rx_led | tx_led);
+ leds->set_atr_reg(ATR_REG_IDLE, 0);
+ leds->set_atr_reg(ATR_REG_RX_ONLY, is_txrx? txrx_led : rx_led);
+ leds->set_atr_reg(ATR_REG_TX_ONLY, tx_led);
+ leds->set_atr_reg(ATR_REG_FULL_DUPLEX, rx_led | tx_led);
}
void x300_impl::set_tick_rate(mboard_members_t &mb, const double rate)
@@ -1314,7 +1363,6 @@ void x300_impl::set_tick_rate(mboard_members_t &mb, const double rate)
perif.time64->set_tick_rate(rate);
perif.framer->set_tick_rate(rate);
perif.ddc->set_tick_rate(rate);
- perif.deframer->set_tick_rate(rate);
perif.duc->set_tick_rate(rate);
}
}
@@ -1509,30 +1557,6 @@ void x300_impl::set_mb_eeprom(i2c_iface::sptr i2c, const mboard_eeprom_t &mb_eep
}
/***********************************************************************
- * front-panel GPIO
- **********************************************************************/
-
-boost::uint32_t x300_impl::get_fp_gpio(gpio_core_200::sptr gpio)
-{
- return boost::uint32_t(gpio->read_gpio(dboard_iface::UNIT_RX));
-}
-
-void x300_impl::set_fp_gpio(gpio_core_200::sptr gpio, const gpio_attr_t attr, const boost::uint32_t value)
-{
- switch (attr)
- {
- case GPIO_CTRL: return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value);
- case GPIO_DDR: return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value);
- case GPIO_OUT: return gpio->set_gpio_out(dboard_iface::UNIT_RX, value);
- case GPIO_ATR_0X: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value);
- case GPIO_ATR_RX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value);
- case GPIO_ATR_TX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value);
- case GPIO_ATR_XX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value);
- default: UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-/***********************************************************************
* claimer logic
**********************************************************************/
diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp
index 1630047af..521ce8a0e 100644
--- a/host/lib/usrp/x300/x300_impl.hpp
+++ b/host/lib/usrp/x300/x300_impl.hpp
@@ -41,7 +41,8 @@
#include "radio_ctrl_core_3000.hpp"
#include "rx_frontend_core_200.hpp"
#include "tx_frontend_core_200.hpp"
-#include "gpio_core_200.hpp"
+#include "gpio_atr_3000.hpp"
+#include "dma_fifo_core_3000.hpp"
#include <boost/weak_ptr.hpp>
#include <uhd/usrp/gps_ctrl.hpp>
#include <uhd/usrp/mboard_eeprom.hpp>
@@ -56,8 +57,11 @@ static const std::string X300_FW_FILE_NAME = "usrp_x300_fw.bin";
static const double X300_DEFAULT_TICK_RATE = 200e6; //Hz
static const double X300_BUS_CLOCK_RATE = 166.666667e6; //Hz
-static const size_t X300_TX_HW_BUFF_SIZE = 520*1024; //512K SRAM buffer + 8K 2Clk FIFO
-static const size_t X300_TX_FC_RESPONSE_FREQ = 8; //per flow-control window
+static const size_t X300_TX_HW_BUFF_SIZE_SRAM = 520*1024; //512K SRAM buffer + 8K 2Clk FIFO
+static const size_t X300_TX_FC_RESPONSE_FREQ_SRAM = 8; //per flow-control window
+static const size_t X300_TX_HW_BUFF_SIZE_DRAM = 128*1024;
+static const size_t X300_TX_FC_RESPONSE_FREQ_DRAM = 32;
+static const boost::uint32_t X300_DRAM_FIFO_SIZE = 32*1024*1024;
static const size_t X300_RX_SW_BUFF_SIZE_ETH = 0x2000000;//32MiB For an ~8k frame size any size >32MiB is just wasted buffer space
static const size_t X300_RX_SW_BUFF_SIZE_ETH_MACOS = 0x100000; //1Mib
@@ -123,7 +127,7 @@ enum
struct x300_dboard_iface_config_t
{
- gpio_core_200::sptr gpio;
+ uhd::usrp::gpio_atr::db_gpio_atr_3000::sptr gpio;
spi_core_3000::sptr spi;
size_t rx_spi_slaveno;
size_t tx_spi_slaveno;
@@ -185,7 +189,7 @@ private:
rx_dsp_core_3000::sptr ddc;
tx_vita_core_3000::sptr deframer;
tx_dsp_core_3000::sptr duc;
- gpio_core_200_32wo::sptr leds;
+ uhd::usrp::gpio_atr::gpio_atr_3000::sptr leds;
rx_frontend_core_200::sptr rx_fe;
tx_frontend_core_200::sptr tx_fe;
//Registers
@@ -226,10 +230,14 @@ private:
return slot_name == "A" ? 0 : 1;
}
+ bool has_dram_buff;
+ dma_fifo_core_3000::sptr dram_buff_ctrl[NUM_RADIOS];
+
+
//other perifs on mboard
x300_clock_ctrl::sptr clock;
uhd::gps_ctrl::sptr gps;
- gpio_core_200::sptr fp_gpio;
+ uhd::usrp::gpio_atr::gpio_atr_3000::sptr fp_gpio;
uhd::usrp::x300::fw_regmap_t::sptr fw_regmap;
@@ -365,9 +373,7 @@ private:
void check_fw_compat(const uhd::fs_path &mb_path, uhd::wb_iface::sptr iface);
void check_fpga_compat(const uhd::fs_path &mb_path, const mboard_members_t &members);
- void update_atr_leds(gpio_core_200_32wo::sptr, const std::string &ant);
- boost::uint32_t get_fp_gpio(gpio_core_200::sptr);
- void set_fp_gpio(gpio_core_200::sptr, const gpio_attr_t, const boost::uint32_t);
+ void update_atr_leds(uhd::usrp::gpio_atr::gpio_atr_3000::sptr, const std::string &ant);
void self_cal_adc_capture_delay(mboard_members_t& mb, const size_t radio_i, bool print_status = false);
double self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay = false);
diff --git a/host/lib/usrp/x300/x300_io_impl.cpp b/host/lib/usrp/x300/x300_io_impl.cpp
index e3515af0c..1356daec5 100644
--- a/host/lib/usrp/x300/x300_io_impl.cpp
+++ b/host/lib/usrp/x300/x300_io_impl.cpp
@@ -216,9 +216,10 @@ struct x300_tx_fc_guts_t
* FC credit we have is C = F + M - N (i.e. we can send C more packets
* before getting another ack).
*/
-static size_t get_tx_flow_control_window(size_t frame_size, const device_addr_t& tx_args)
+static size_t get_tx_flow_control_window(size_t frame_size, const bool dram_buff, const device_addr_t& tx_args)
{
- double hw_buff_size = tx_args.cast<double>("send_buff_size", X300_TX_HW_BUFF_SIZE);
+ double default_buff_size = dram_buff ? X300_TX_HW_BUFF_SIZE_DRAM : X300_TX_HW_BUFF_SIZE_SRAM;
+ double hw_buff_size = tx_args.cast<double>("send_buff_size", default_buff_size);
size_t window_in_pkts = (static_cast<size_t>(hw_buff_size) / frame_size);
if (window_in_pkts == 0) {
throw uhd::value_error("send_buff_size must be larger than the send_frame_size.");
@@ -580,8 +581,9 @@ tx_streamer::sptr x300_impl::get_tx_stream(const uhd::stream_args_t &args_)
perif.duc->setup(args);
//flow control setup
- size_t fc_window = get_tx_flow_control_window(xport.send->get_send_frame_size(), device_addr); //In packets
- const size_t fc_handle_window = std::max<size_t>(1, fc_window/X300_TX_FC_RESPONSE_FREQ);
+ size_t fc_window = get_tx_flow_control_window(xport.send->get_send_frame_size(), mb.has_dram_buff, device_addr); //In packets
+ const size_t fc_handle_window = std::max<size_t>(1,
+ fc_window/ (mb.has_dram_buff ? X300_TX_FC_RESPONSE_FREQ_DRAM : X300_TX_FC_RESPONSE_FREQ_SRAM));
UHD_LOG << "TX Flow Control Window = " << fc_window << ", TX Flow Control Handler Window = " << fc_handle_window << std::endl;
diff --git a/host/lib/usrp/x300/x300_regs.hpp b/host/lib/usrp/x300/x300_regs.hpp
index eba30abb5..7173c0660 100644
--- a/host/lib/usrp/x300/x300_regs.hpp
+++ b/host/lib/usrp/x300/x300_regs.hpp
@@ -77,6 +77,8 @@ localparam ZPU_SR_XB_LOCAL = 03;
localparam ZPU_SR_SPI = 32;
localparam ZPU_SR_ETHINT0 = 40;
localparam ZPU_SR_ETHINT1 = 56;
+localparam ZPU_SR_DRAM_FIFO0 = 72;
+localparam ZPU_SR_DRAM_FIFO1 = 80;
//reset bits
#define ZPU_SR_SW_RST_ETH_PHY (1<<0)
@@ -89,6 +91,8 @@ localparam ZPU_RB_CLK_STATUS = 3;
localparam ZPU_RB_COMPAT_NUM = 6;
localparam ZPU_RB_ETH_TYPE0 = 4;
localparam ZPU_RB_ETH_TYPE1 = 5;
+localparam ZPU_RB_DRAM_FIFO0 = 10;
+localparam ZPU_RB_DRAM_FIFO1 = 11;
//spi slaves on radio
#define DB_DAC_SEN (1 << 7)