aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/b200/b200_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/b200/b200_impl.cpp')
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp69
1 files changed, 54 insertions, 15 deletions
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index 1f1fda92f..3ff502858 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -31,6 +31,7 @@
#include <boost/thread/thread.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/functional/hash.hpp>
+#include <boost/make_shared.hpp>
#include <cstdio>
#include <ctime>
#include <cmath>
@@ -45,6 +46,33 @@ static const boost::posix_time::milliseconds REENUMERATION_TIMEOUT_MS(3000);
static const size_t FE1 = 1;
static const size_t FE2 = 0;
+class b200_ad9361_client_t : public ad9361_params {
+public:
+ ~b200_ad9361_client_t() {}
+ double get_band_edge(frequency_band_t band) {
+ switch (band) {
+ case AD9361_RX_BAND0: return 2.2e9;
+ case AD9361_RX_BAND1: return 4.0e9;
+ case AD9361_TX_BAND0: return 2.5e9;
+ default: return 0;
+ }
+ }
+ clocking_mode_t get_clocking_mode() {
+ return AD9361_XTAL_N_CLK_PATH;
+ }
+ digital_interface_mode_t get_digital_interface_mode() {
+ return AD9361_DDR_FDD_LVCMOS;
+ }
+ digital_interface_delays_t get_digital_interface_timing() {
+ digital_interface_delays_t delays;
+ delays.rx_clk_delay = 0;
+ delays.rx_data_delay = 0xF;
+ delays.tx_clk_delay = 0;
+ delays.tx_data_delay = 0xF;
+ return delays;
+ }
+};
+
/***********************************************************************
* Discovery
**********************************************************************/
@@ -161,7 +189,7 @@ static device::sptr b200_make(const device_addr_t &device_addr)
UHD_STATIC_BLOCK(register_b200_device)
{
- device::register_device(&b200_find, &b200_make);
+ device::register_device(&b200_find, &b200_make, device::USRP);
}
/***********************************************************************
@@ -170,6 +198,7 @@ UHD_STATIC_BLOCK(register_b200_device)
b200_impl::b200_impl(const device_addr_t &device_addr)
{
_tree = property_tree::make();
+ _type = device::USRP;
const fs_path mb_path = "/mboards/0";
//try to match the given device address with something on the USB bus
@@ -352,10 +381,17 @@ b200_impl::b200_impl(const device_addr_t &device_addr)
_demux = recv_packet_demuxer_3000::make(_data_transport);
////////////////////////////////////////////////////////////////////
+ // create time and clock control objects
+ ////////////////////////////////////////////////////////////////////
+ _spi_iface = b200_local_spi_core::make(_local_ctrl);
+ _adf4001_iface = boost::make_shared<b200_ref_pll_ctrl>(_spi_iface);
+
+ ////////////////////////////////////////////////////////////////////
// Init codec - turns on clocks
////////////////////////////////////////////////////////////////////
UHD_MSG(status) << "Initialize CODEC control..." << std::endl;
- _codec_ctrl = ad9361_ctrl::make(_iface);
+ ad9361_params::sptr client_settings = boost::make_shared<b200_ad9361_client_t>();
+ _codec_ctrl = ad9361_ctrl::make_spi(client_settings, _spi_iface, AD9361_SLAVENO);
this->reset_codec_dcm();
////////////////////////////////////////////////////////////////////
@@ -418,13 +454,6 @@ b200_impl::b200_impl(const device_addr_t &device_addr)
}
_codec_ctrl->data_port_loopback(false);
- ////////////////////////////////////////////////////////////////////
- // create time and clock control objects
- ////////////////////////////////////////////////////////////////////
- _spi_iface = spi_core_3000::make(_local_ctrl, TOREG(SR_CORE_SPI), RB32_CORE_SPI);
- _spi_iface->set_divider(B200_BUS_CLOCK_RATE/ADF4001_SPI_RATE);
- _adf4001_iface = boost::shared_ptr<adf4001_ctrl>(new adf4001_ctrl(_spi_iface, ADF4001_SLAVENO));
-
//register time now and pps onto available radio cores
_tree->create<time_spec_t>(mb_path / "time" / "now")
.publish(boost::bind(&time_core_3000::get_time_now, _radio_perifs[0].time64));
@@ -478,6 +507,16 @@ b200_impl::b200_impl(const device_addr_t &device_addr)
_tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(rx_spec);
_tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(tx_spec);
+ //init to internal clock and time source
+ _tree->access<std::string>(mb_path / "clock_source/value").set("internal");
+ _tree->access<std::string>(mb_path / "time_source/value").set("none");
+
+ // Set default rates (can't be done in setup_radio() because tick rate is not yet set)
+ for (size_t i = 0; i < _radio_perifs.size(); i++) {
+ _tree->access<double>(mb_path / "rx_dsps" / str(boost::format("%u") % i)/ "rate/value").set(B200_DEFAULT_RATE);
+ _tree->access<double>(mb_path / "tx_dsps" / str(boost::format("%u") % i) / "rate/value").set(B200_DEFAULT_RATE);
+ }
+
//GPS installed: use external ref, time, and init time spec
if (_gps and _gps->gps_detected())
{
@@ -542,7 +581,7 @@ void b200_impl::setup_radio(const size_t dspno)
_tree->create<double>(rx_dsp_path / "rate" / "value")
.coerce(boost::bind(&rx_dsp_core_3000::set_host_rate, perif.ddc, _1))
.subscribe(boost::bind(&b200_impl::update_rx_samp_rate, this, dspno, _1))
- .set(1e6);
+ .set(0.0); // Can only set this after tick rate is initialized.
_tree->create<double>(rx_dsp_path / "freq" / "value")
.coerce(boost::bind(&rx_dsp_core_3000::set_freq, perif.ddc, _1))
.set(0.0);
@@ -566,7 +605,7 @@ void b200_impl::setup_radio(const size_t dspno)
_tree->create<double>(tx_dsp_path / "rate" / "value")
.coerce(boost::bind(&tx_dsp_core_3000::set_host_rate, perif.duc, _1))
.subscribe(boost::bind(&b200_impl::update_tx_samp_rate, this, dspno, _1))
- .set(1e6);
+ .set(0.0); // Can only set this after tick rate is initialized.
_tree->create<double>(tx_dsp_path / "freq" / "value")
.coerce(boost::bind(&tx_dsp_core_3000::set_freq, perif.duc, _1))
.set(0.0);
@@ -599,7 +638,7 @@ void b200_impl::setup_radio(const size_t dspno)
_tree->create<double>(rf_fe_path / "gains" / name / "value")
.coerce(boost::bind(&ad9361_ctrl::set_gain, _codec_ctrl, key, _1))
- .set(0.0);
+ .set(x == "rx" ? B200_DEFAULT_RX_GAIN : B200_DEFAULT_TX_GAIN);
}
_tree->create<std::string>(rf_fe_path / "connection").set("IQ");
_tree->create<bool>(rf_fe_path / "enabled").set(true);
@@ -610,9 +649,9 @@ void b200_impl::setup_radio(const size_t dspno)
_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")
- .set(0.0)
.coerce(boost::bind(&ad9361_ctrl::tune, _codec_ctrl, key, _1))
- .subscribe(boost::bind(&b200_impl::update_bandsel, this, key, _1));
+ .subscribe(boost::bind(&b200_impl::update_bandsel, this, key, _1))
+ .set(B200_DEFAULT_FREQ);
_tree->create<meta_range_t>(rf_fe_path / "freq" / "range")
.publish(boost::bind(&ad9361_ctrl::get_rf_freq_range));
@@ -694,7 +733,7 @@ void b200_impl::enforce_tick_rate_limits(size_t chan_count, double tick_rate, co
}
else
{
- const double max_tick_rate = ((chan_count <= 1) ? AD9361_1_CHAN_CLOCK_RATE_MAX : AD9361_2_CHAN_CLOCK_RATE_MAX);
+ const double max_tick_rate = ad9361_device_t::AD9361_MAX_CLOCK_RATE / ((chan_count <= 1) ? 1 : 2);
if (tick_rate - max_tick_rate >= 1.0)
{
throw uhd::value_error(boost::str(