aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/e300
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2015-07-09 16:56:34 -0700
committerMartin Braun <martin.braun@ettus.com>2015-07-29 16:50:34 -0700
commit9813505968e3c9beb1c8f16116cd8665524992b6 (patch)
treef9b66313c6a138dbabeb7f113e1e6ce802a1a22d /host/lib/usrp/e300
parente94223d4b5db34b407a72f9aed56fe3ef4eeec75 (diff)
downloaduhd-9813505968e3c9beb1c8f16116cd8665524992b6.tar.gz
uhd-9813505968e3c9beb1c8f16116cd8665524992b6.tar.bz2
uhd-9813505968e3c9beb1c8f16116cd8665524992b6.zip
ad9361/b200/e300: Refactored AD936x + perifs management
- Created AD936x manager class - Moved functionality from B2x0 and E310 into manager - Separated property tree + perifs initialization in both device classes
Diffstat (limited to 'host/lib/usrp/e300')
-rw-r--r--host/lib/usrp/e300/e300_defaults.hpp4
-rw-r--r--host/lib/usrp/e300/e300_impl.cpp102
-rw-r--r--host/lib/usrp/e300/e300_impl.hpp2
-rw-r--r--host/lib/usrp/e300/e300_io_impl.cpp12
4 files changed, 27 insertions, 93 deletions
diff --git a/host/lib/usrp/e300/e300_defaults.hpp b/host/lib/usrp/e300/e300_defaults.hpp
index 32b3c33ef..267897e03 100644
--- a/host/lib/usrp/e300/e300_defaults.hpp
+++ b/host/lib/usrp/e300/e300_defaults.hpp
@@ -30,10 +30,6 @@ static const double DEFAULT_RX_SAMP_RATE = 1.0e6;
static const double DEFAULT_DDC_FREQ = 0.0;
static const double DEFAULT_DUC_FREQ = 0.0;
-static const double DEFAULT_FE_GAIN = 0.0;
-static const double DEFAULT_FE_FREQ = 1.0e9;
-static const double DEFAULT_FE_BW = 56e6;
-
static const std::string DEFAULT_TIME_SRC = "internal";
static const std::string DEFAULT_CLOCK_SRC = "internal";
diff --git a/host/lib/usrp/e300/e300_impl.cpp b/host/lib/usrp/e300/e300_impl.cpp
index e8a201916..3607c6036 100644
--- a/host/lib/usrp/e300/e300_impl.cpp
+++ b/host/lib/usrp/e300/e300_impl.cpp
@@ -395,6 +395,7 @@ e300_impl::e300_impl(const uhd::device_addr_t &device_addr)
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
_eeprom_manager = boost::make_shared<e300_eeprom_manager>(i2c::make_i2cdev(E300_I2CDEV_DEVICE));
}
+ _codec_mgr = ad936x_manager::make(_codec_ctrl, fpga::NUM_RADIOS);
UHD_MSG(status) << "Detecting internal GPSDO.... " << std::flush;
if (_xport_path == AXI) {
@@ -478,14 +479,10 @@ e300_impl::e300_impl(const uhd::device_addr_t &device_addr)
for(size_t instance = 0; instance < fpga::NUM_RADIOS; instance++)
this->_setup_radio(instance);
- _codec_ctrl->data_port_loopback(true);
-
// Radio 0 loopback through AD9361
- this->_codec_loopback_self_test(_radio_perifs[0].ctrl);
+ _codec_mgr->loopback_self_test(_radio_perifs[0].ctrl, TOREG(SR_CODEC_IDLE), RB64_CODEC_READBACK);
// Radio 1 loopback through AD9361
- this->_codec_loopback_self_test(_radio_perifs[1].ctrl);
-
- _codec_ctrl->data_port_loopback(false);
+ _codec_mgr->loopback_self_test(_radio_perifs[1].ctrl, TOREG(SR_CODEC_IDLE), RB64_CODEC_READBACK);
////////////////////////////////////////////////////////////////////
// internal gpios
@@ -581,7 +578,7 @@ e300_impl::e300_impl(const uhd::device_addr_t &device_addr)
// init the clock rate to something reasonable
_tree->access<double>(mb_path / "tick_rate").set(
- device_addr.cast<double>("master_clock_rate", e300::DEFAULT_TICK_RATE));
+ device_addr.cast<double>("master_clock_rate", ad936x_manager::DEFAULT_TICK_RATE));
// subdev spec contains full width of selections
subdev_spec_t rx_spec, tx_spec;
@@ -741,30 +738,6 @@ std::string e300_impl::_get_version_hash(void)
% ((git_hash & 0xF000000) ? "-dirty" : ""));
}
-void e300_impl::_codec_loopback_self_test(wb_iface::sptr iface)
-{
- bool test_fail = false;
- UHD_ASSERT_THROW(bool(iface));
- UHD_MSG(status) << "Performing CODEC loopback test... " << std::flush;
- size_t hash = size_t(time(NULL));
- for (size_t i = 0; i < 100; i++)
- {
- boost::hash_combine(hash, i);
- const boost::uint32_t word32 = boost::uint32_t(hash) & 0xfff0fff0;
- iface->poke32(TOREG(SR_CODEC_IDLE), word32);
- iface->peek64(RB64_CODEC_READBACK); //enough idleness for loopback to propagate
- const boost::uint64_t rb_word64 = iface->peek64(RB64_CODEC_READBACK);
- const boost::uint32_t rb_tx = boost::uint32_t(rb_word64 >> 32);
- const boost::uint32_t rb_rx = boost::uint32_t(rb_word64 & 0xffffffff);
- test_fail = word32 != rb_tx or word32 != rb_rx;
- if (test_fail) break; //exit loop on any failure
- }
- UHD_MSG(status) << ((test_fail)? " fail" : "pass") << std::endl;
-
- /* Zero out the idle data. */
- iface->poke32(TOREG(SR_CODEC_IDLE), 0);
-}
-
boost::uint32_t e300_impl::_allocate_sid(const sid_config_t &config)
{
const boost::uint32_t stream = (config.dst_prefix | (config.router_dst_there << 2)) & 0xff;
@@ -1060,67 +1033,38 @@ void e300_impl::_setup_radio(const size_t dspno)
////////////////////////////////////////////////////////////////////
// create RF frontend interfacing
////////////////////////////////////////////////////////////////////
- static const std::vector<std::string> data_directions = boost::assign::list_of("rx")("tx");
- BOOST_FOREACH(const std::string& direction, data_directions)
- {
- const std::string key = boost::to_upper_copy(direction) + std::string(((dspno == FE0)? "1" : "2"));
+ static const std::vector<direction_t> dirs = boost::assign::list_of(RX_DIRECTION)(TX_DIRECTION);
+ BOOST_FOREACH(direction_t dir, dirs) {
+ const std::string x = (dir == RX_DIRECTION) ? "rx" : "tx";
+ const std::string key = boost::to_upper_copy(x) + std::string(((dspno == FE0)? "1" : "2"));
const fs_path rf_fe_path
= mb_path / "dboards" / "A" / (direction + "_frontends") / ((dspno == 0) ? "A" : "B");
- _tree->create<std::string>(rf_fe_path / "name").set("FE-"+key);
- _tree->create<int>(rf_fe_path / "sensors"); //empty TODO
+ // This will connect all the AD936x-specific items
+ _codec_mgr->populate_frontend_subtree(
+ _tree->subtree(rf_fe_path), key, dir
+ );
+
+ // This will connect all the e300_impl-specific items
_tree->create<sensor_value_t>(rf_fe_path / "sensors" / "lo_locked")
- .publish(boost::bind(&e300_impl::_get_fe_pll_lock, this, direction == "tx"));
- _tree->create<sensor_value_t>(rf_fe_path / "sensors" / "temp")
- .publish(boost::bind(&ad9361_ctrl::get_temperature, _codec_ctrl));
- BOOST_FOREACH(const std::string &name, ad9361_ctrl::get_gain_names(key))
- {
- _tree->create<meta_range_t>(rf_fe_path / "gains" / name / "range")
- .set(ad9361_ctrl::get_gain_range(key));
+ .publish(boost::bind(&e300_impl::_get_fe_pll_lock, this, direction == "tx"))
+ ;
- _tree->create<double>(rf_fe_path / "gains" / name / "value")
- .coerce(boost::bind(&ad9361_ctrl::set_gain, _codec_ctrl, key, _1))
- .set(e300::DEFAULT_FE_GAIN);
- }
- _tree->create<std::string>(rf_fe_path / "connection").set("IQ");
- _tree->create<bool>(rf_fe_path / "enabled").set(true);
- _tree->create<bool>(rf_fe_path / "use_lo_offset").set(false);
- _tree->create<double>(rf_fe_path / "bandwidth" / "value")
- .coerce(boost::bind(&ad9361_ctrl::set_bw_filter, _codec_ctrl, key, _1))
- .set(e300::DEFAULT_FE_BW);
- _tree->create<meta_range_t>(rf_fe_path / "bandwidth" / "range")
- .publish(boost::bind(&ad9361_ctrl::get_bw_filter_range, key));
- _tree->create<double>(rf_fe_path / "freq" / "value")
- .publish(boost::bind(&ad9361_ctrl::get_freq, _codec_ctrl, key))
- .coerce(boost::bind(&ad9361_ctrl::tune, _codec_ctrl, key, _1))
- .subscribe(boost::bind(&e300_impl::_update_fe_lo_freq, this, key, _1))
- .set(e300::DEFAULT_FE_FREQ);
- _tree->create<meta_range_t>(rf_fe_path / "freq" / "range")
- .publish(boost::bind(&ad9361_ctrl::get_rf_freq_range));
-
- //only in local mode
- if(_xport_path == AXI) {
- //add all frontend filters
- std::vector<std::string> filter_names = _codec_ctrl->get_filter_names(key);
- for(size_t i = 0;i < filter_names.size(); i++)
- {
- _tree->create<filter_info_base::sptr>(rf_fe_path / "filters" / filter_names[i] / "value" )
- .publish(boost::bind(&ad9361_ctrl::get_filter, _codec_ctrl, key, filter_names[i]))
- .subscribe(boost::bind(&ad9361_ctrl::set_filter, _codec_ctrl, key, filter_names[i], _1));
- }
+ // Network mode currently doesn't support the filter API, so
+ // prevent it from using it:
+ if(_xport_path != AXI) {
+ _tree->remove(rf_fe_path / "filters");
}
- //setup RX related stuff
- if (key[0] == 'R') {
+ // Antenna Setup
+ if (dir == RX_DIRECTION) {
static const std::vector<std::string> ants = boost::assign::list_of("TX/RX")("RX2");
_tree->create<std::vector<std::string> >(rf_fe_path / "antenna" / "options").set(ants);
_tree->create<std::string>(rf_fe_path / "antenna" / "value")
.subscribe(boost::bind(&e300_impl::_update_antenna_sel, this, dspno, _1))
.set("RX2");
- _tree->create<sensor_value_t>(rf_fe_path / "sensors" / "rssi")
- .publish(boost::bind(&ad9361_ctrl::get_rssi, _codec_ctrl, key));
}
- if (key[0] == 'T') {
+ if (dir == TX_DIRECTION) {
static const std::vector<std::string> ants(1, "TX/RX");
_tree->create<std::vector<std::string> >(rf_fe_path / "antenna" / "options").set(ants);
_tree->create<std::string>(rf_fe_path / "antenna" / "value").set("TX/RX");
diff --git a/host/lib/usrp/e300/e300_impl.hpp b/host/lib/usrp/e300/e300_impl.hpp
index 3ed133489..d61b95387 100644
--- a/host/lib/usrp/e300/e300_impl.hpp
+++ b/host/lib/usrp/e300/e300_impl.hpp
@@ -40,6 +40,7 @@
#include "rx_dsp_core_3000.hpp"
#include "tx_dsp_core_3000.hpp"
#include "ad9361_ctrl.hpp"
+#include "ad936x_manager.hpp"
#include "gpio_core_200.hpp"
#include "e300_global_regs.hpp"
@@ -288,6 +289,7 @@ private: // members
radio_perifs_t _radio_perifs[2];
double _tick_rate;
ad9361_ctrl::sptr _codec_ctrl;
+ ad936x_manager::sptr _codec_mgr;
fe_control_settings_t _settings;
global_regs::sptr _global_regs;
e300_sensor_manager::sptr _sensor_manager;
diff --git a/host/lib/usrp/e300/e300_io_impl.cpp b/host/lib/usrp/e300/e300_io_impl.cpp
index dadfb71e9..29d250c8f 100644
--- a/host/lib/usrp/e300/e300_io_impl.cpp
+++ b/host/lib/usrp/e300/e300_io_impl.cpp
@@ -91,21 +91,13 @@ void e300_impl::_update_tick_rate(const double rate)
}
}
-#define CHECK_BANDWIDTH(dir) \
- if (rate > _codec_ctrl->get_bw_filter_range(dir).stop()) { \
- UHD_MSG(warning) \
- << "Selected " << dir << " bandwidth (" << (rate/1e6) << " MHz) exceeds\n" \
- << "analog frontend filter bandwidth (" << (_codec_ctrl->get_bw_filter_range(dir).stop()/1e6) << " MHz)." \
- << std::endl; \
- }
-
void e300_impl::_update_rx_samp_rate(const size_t dspno, const double rate)
{
boost::shared_ptr<sph::recv_packet_streamer> my_streamer =
boost::dynamic_pointer_cast<sph::recv_packet_streamer>(_radio_perifs[dspno].rx_streamer.lock());
if (my_streamer)
my_streamer->set_samp_rate(rate);
- CHECK_BANDWIDTH("Rx");
+ _codec_mgr->check_bandwidth(rate, "Rx");
}
void e300_impl::_update_tx_samp_rate(const size_t dspno, const double rate)
@@ -114,7 +106,7 @@ void e300_impl::_update_tx_samp_rate(const size_t dspno, const double rate)
boost::dynamic_pointer_cast<sph::send_packet_streamer>(_radio_perifs[dspno].tx_streamer.lock());
if (my_streamer)
my_streamer->set_samp_rate(rate);
- CHECK_BANDWIDTH("Tx");
+ _codec_mgr->check_bandwidth(rate, "Tx");
}
/***********************************************************************