aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2015-04-14 14:05:19 -0500
committerMartin Braun <martin.braun@ettus.com>2015-04-14 14:05:19 -0500
commit2f760ac0f883e1de9adca48449498deab72a9359 (patch)
treeffe52eeabe9f265dd0471b20d670091091f8dcc8
parent2f48c9bb979c8777cc8a3d3a0de03e9cf2958b14 (diff)
parent19716045c60f00296f24e115580da154e5ddef8d (diff)
downloaduhd-2f760ac0f883e1de9adca48449498deab72a9359.tar.gz
uhd-2f760ac0f883e1de9adca48449498deab72a9359.tar.bz2
uhd-2f760ac0f883e1de9adca48449498deab72a9359.zip
Merge branch 'maint'
Conflicts: host/lib/usrp/b200/b200_io_impl.cpp host/lib/usrp/common/ad9361_driver/ad9361_device.cpp host/lib/usrp/common/ad9361_driver/ad9361_device.h
-rw-r--r--host/docs/octoclock.dox34
-rw-r--r--host/docs/sync.dox6
-rw-r--r--host/lib/usrp/b200/b200_io_impl.cpp11
-rw-r--r--host/lib/usrp/common/ad9361_ctrl.cpp8
-rw-r--r--host/lib/usrp/common/ad9361_driver/ad9361_device.cpp3
-rw-r--r--host/lib/usrp/common/ad9361_driver/ad9361_device.h2
-rw-r--r--host/lib/usrp/e300/e300_io_impl.cpp10
7 files changed, 46 insertions, 28 deletions
diff --git a/host/docs/octoclock.dox b/host/docs/octoclock.dox
index 9c1ca7b47..45a12e93a 100644
--- a/host/docs/octoclock.dox
+++ b/host/docs/octoclock.dox
@@ -29,14 +29,15 @@ schematics</a>. Once you verify that the programmer is properly connected, run t
cd <install path>/share/uhd/images
avrdude -p atmega128 -c <programmer name> -P usb -U efuse:w:0xFF:m -U hfuse:w:0x80:m -U lfuse:w:0xFF:m -U flash:w:octoclock_bootloader.hex:i
-**Note:** On Linux, **sudo** must be used with the **avrdude** command.
+\b Note:
+On Linux, `sudo avrdude ...` might be necessary to gain access to the programmer.
Once the bootloader has been burned, power-cycle your OctoClock device and refer to the below instructions on burning the OctoClock's
primary firmware.
\subsection application Primary Octoclock firmware
-To load firmware onto the OctoClock, you must use the *octoclock_firmware_burner* utility, specifying the IP
+To load firmware onto the OctoClock, you must use the `octoclock_firmware_burner` utility, specifying the IP
address of the OctoClock device, as follows:
octoclock_firmware_burner --addr=192.168.10.3
@@ -45,12 +46,13 @@ address of the OctoClock device, as follows:
\subsection host_interface Setting up the host interface
-The OctoClock communicates with the host machine at the UDP layer over Gigabit Ethernet. The default device
-of the OctoClock is **192.168.10.3**. You will need to configure the host machine's Ethernet interface with
-a static IP address to enable communication. An address of **192.168.10.1** and a subnet mask of
-**255.255.255.0** is recommended.
+The OctoClock communicates with the host machine at the UDP layer over Ethernet. The default device
+of the OctoClock is `192.168.10.3`. You will need to configure the host machine's Ethernet interface with
+a static IP address to enable communication. An address of `192.168.10.1` and a subnet mask of
+`255.255.255.0` is recommended.
-**Note:** When using UHD software, if an IP address for the OctoClock is not specified, the software will
+\b Note:
+When using UHD software, if an IP address for the OctoClock is not specified, the software will
use UDP broadcast packets to locate the OctoClock. On some systems, the firewall will block UDP broadcast
packets. It is recommended that you change your firewall settings.
@@ -110,17 +112,17 @@ The same applies for an external signal.
The following sensors are available on both the OctoClock and Octoclock-G; these can be queried through the
<a href="classuhd_1_1octoclock.html">API</a>.
-- **ext_ref_detected:** whether or not the device detects an external reference
-- **gps_detected:** whether or not the device detects an internal GPSDO
-- **using_ref:** which reference the device is using (internal or external)
-- **switch_pos:** the position of the front switch (internal or external)
+- `ext_ref_detected:` whether or not the device detects an external reference
+- `gps_detected:` whether or not the device detects an internal GPSDO
+- `using_ref:` which reference the device is using (internal or external)
+- `switch_pos:` the position of the front switch (internal or external)
On the OctoClock-G, the following sensors are added:
-- **gps_gpgga:** the latest GPGGA string sent by the GPSDO
-- **gps_gprmc:** the latest GPRMC string sent by the GPSDO
-- **gps_time:** the time reported by the GPSDO
-- **gps_locked:** whether or not the GPSDO is locked (true/false)
-- **gps_servo:** the latest debug trace information sent by the GPSDO
+- `gps_gpgga:` the latest GPGGA string sent by the GPSDO
+- `gps_gprmc:` the latest GPRMC string sent by the GPSDO
+- `gps_time:` the time reported by the GPSDO
+- `gps_locked:` whether or not the GPSDO is locked (true/false)
+- `gps_servo:` the latest debug trace information sent by the GPSDO
*/
diff --git a/host/docs/sync.dox b/host/docs/sync.dox
index 8c16eb046..aaae88702 100644
--- a/host/docs/sync.dox
+++ b/host/docs/sync.dox
@@ -152,7 +152,7 @@ metadata should have a time spec set: :
size_t num_tx_samps = tx_streamer->send(buffs, samps_to_send, md);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-\subsection sync_phase_lo Align LOs in the front-end (SBX, WBX, CBX)
+\subsection sync_phase_lo Align LOs in the front-end (SBX, WBX, UBX)
Using timed commands, multiple frontends can be tuned at a specific
time. This timed-tuning ensures that the phase offsets between VCO/PLL
@@ -161,7 +161,9 @@ chains will remain constant after each re-tune. See notes below:
- There is a random phase offset between any two frontends
- This phase offset is different for different LO frequencies
- This phase offset remains constant after retuning
- - Due to a divider, WBX phase offset will be randomly +/- 180 deg after re-tune
+ - Due to a divider, WBX phase offset will be randomly +/- 180 deg after re-tune on all USRPs.
+ - Due to a divider, UBX phase offset will be randomly +/- 180 deg after re-tune on N200/N210.
+ On X300/X310, phase sync with UBX fully works.
- This phase offset will drift over time due to thermal and other characteristics
- Periodic calibration will be necessary for phase-coherent applications
diff --git a/host/lib/usrp/b200/b200_io_impl.cpp b/host/lib/usrp/b200/b200_io_impl.cpp
index e423285ce..d6df726af 100644
--- a/host/lib/usrp/b200/b200_io_impl.cpp
+++ b/host/lib/usrp/b200/b200_io_impl.cpp
@@ -175,7 +175,6 @@ void b200_impl::update_tick_rate(const double new_tick_rate)
}
}
-
double b200_impl::coerce_rx_samp_rate(rx_dsp_core_3000::sptr ddc, size_t dspno, const double rx_rate)
{
// Have to set tick rate first, or the ddc will change the requested rate based on default tick rate
@@ -186,6 +185,14 @@ double b200_impl::coerce_rx_samp_rate(rx_dsp_core_3000::sptr ddc, size_t dspno,
return ddc->set_host_rate(rx_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 b200_impl::update_rx_samp_rate(const size_t dspno, const double rate)
{
boost::shared_ptr<sph::recv_packet_streamer> my_streamer =
@@ -194,6 +201,7 @@ void b200_impl::update_rx_samp_rate(const size_t dspno, const double rate)
my_streamer->set_samp_rate(rate);
const double adj = _radio_perifs[dspno].ddc->get_scaling_adjustment();
my_streamer->set_scale_factor(adj);
+ CHECK_BANDWIDTH("Rx");
}
double b200_impl::coerce_tx_samp_rate(tx_dsp_core_3000::sptr duc, size_t dspno, const double tx_rate)
@@ -214,6 +222,7 @@ void b200_impl::update_tx_samp_rate(const size_t dspno, const double rate)
my_streamer->set_samp_rate(rate);
const double adj = _radio_perifs[dspno].duc->get_scaling_adjustment();
my_streamer->set_scale_factor(adj);
+ CHECK_BANDWIDTH("Tx");
}
/***********************************************************************
diff --git a/host/lib/usrp/common/ad9361_ctrl.cpp b/host/lib/usrp/common/ad9361_ctrl.cpp
index 9c17a582d..f3ab36247 100644
--- a/host/lib/usrp/common/ad9361_ctrl.cpp
+++ b/host/lib/usrp/common/ad9361_ctrl.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2012-2014 Ettus Research LLC
+// Copyright 2012-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
@@ -133,12 +133,6 @@ public:
{
boost::lock_guard<boost::mutex> lock(_mutex);
- //warning for known trouble rates
- if (rate > ad9361_device_t::AD9361_RECOMMENDED_MAX_CLOCK_RATE) UHD_MSG(warning) << boost::format(
- "The requested clock rate %f MHz may cause slow configuration.\n"
- "The driver recommends a master clock rate less than %f MHz.\n"
- ) % (rate/1e6) % (ad9361_device_t::AD9361_RECOMMENDED_MAX_CLOCK_RATE/1e6) << std::endl;
-
//clip to known bounds
const meta_range_t clock_rate_range = ad9361_ctrl::get_clock_rate_range();
const double clipped_rate = clock_rate_range.clip(rate);
diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp
index c3eb5fb9d..8737837b3 100644
--- a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp
+++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp
@@ -79,8 +79,9 @@ int get_num_taps(int max_num_taps) {
const double ad9361_device_t::AD9361_MAX_GAIN = 89.75;
const double ad9361_device_t::AD9361_MAX_CLOCK_RATE = 61.44e6;
-const double ad9361_device_t::AD9361_RECOMMENDED_MAX_CLOCK_RATE = 56e6;
const double ad9361_device_t::AD9361_CAL_VALID_WINDOW = 100e6;
+// Max bandwdith is due to filter rolloff in analog filter stage
+const double ad9361_device_t::AD9361_RECOMMENDED_MAX_BANDWIDTH = 56e6;
/* Program either the RX or TX FIR filter.
*
diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.h b/host/lib/usrp/common/ad9361_driver/ad9361_device.h
index a242f35e9..0c7a7e4f7 100644
--- a/host/lib/usrp/common/ad9361_driver/ad9361_device.h
+++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.h
@@ -132,8 +132,8 @@ public:
//Constants
static const double AD9361_MAX_GAIN;
static const double AD9361_MAX_CLOCK_RATE;
- static const double AD9361_RECOMMENDED_MAX_CLOCK_RATE;
static const double AD9361_CAL_VALID_WINDOW;
+ static const double AD9361_RECOMMENDED_MAX_BANDWIDTH;
private: //Methods
void _program_fir_filter(direction_t direction, int num_taps, boost::uint16_t *coeffs);
diff --git a/host/lib/usrp/e300/e300_io_impl.cpp b/host/lib/usrp/e300/e300_io_impl.cpp
index fa4915ed1..dadfb71e9 100644
--- a/host/lib/usrp/e300/e300_io_impl.cpp
+++ b/host/lib/usrp/e300/e300_io_impl.cpp
@@ -91,12 +91,21 @@ 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");
}
void e300_impl::_update_tx_samp_rate(const size_t dspno, const double rate)
@@ -105,6 +114,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");
}
/***********************************************************************