aboutsummaryrefslogtreecommitdiffstats
path: root/host/docs/sync.dox
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2014-03-23 15:11:26 +0100
committerMartin Braun <martin.braun@ettus.com>2014-04-09 17:25:09 +0200
commita74919c2a89a6b1ae40b526c4ceadf1108bfd186 (patch)
tree79cb43c5d7ed3caa1fe8b695001267f0cc8286bf /host/docs/sync.dox
parent47bf17b50a305228cfd07ff6fbaff3ac4a30e811 (diff)
downloaduhd-a74919c2a89a6b1ae40b526c4ceadf1108bfd186.tar.gz
uhd-a74919c2a89a6b1ae40b526c4ceadf1108bfd186.tar.bz2
uhd-a74919c2a89a6b1ae40b526c4ceadf1108bfd186.zip
docs: Moved manual to Doxygen
Diffstat (limited to 'host/docs/sync.dox')
-rw-r--r--host/docs/sync.dox197
1 files changed, 197 insertions, 0 deletions
diff --git a/host/docs/sync.dox b/host/docs/sync.dox
new file mode 100644
index 000000000..f41d3a78c
--- /dev/null
+++ b/host/docs/sync.dox
@@ -0,0 +1,197 @@
+/*! \page page_sync Synchronization Application Notes
+
+\tableofcontents
+
+The following application notes explain how to synchronize multiple USRP
+devices with the goal of transmitting or receiving time-aligned samples
+for MIMO or other applications requiring multiple USRP devices operating
+synchronously.
+
+<b>Note:</b> The following synchronization notes do not apply to USRP1,
+which does not support the advanced features available in newer
+products.
+
+\section sync_commonref Common Reference Signals
+
+USRP devices take two reference signals in order to synchronize clocks
+and time:
+
+- A 10MHz reference to provide a single frequency reference for both
+ devices.
+- A pulse-per-second (PPS) to synchronize the sample time across
+ devices.
+- A MIMO cable transmits an encoded time message from one device to
+ another.
+
+\subsection sync_commonref_pps PPS and 10 MHz reference signals
+
+Connect the front panel SMA connectors to the reference sources.
+Typically, these signals are provided by an external GPSDO. However,
+some USRP models can provide these signals from an optional internal
+GPSDO.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+usrp->set_clock_source("external");
+usrp->set_time_source("external");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+<b>Note:</b> Sometimes the delay on the PPS signal will cause it to arrive
+inside the timing margin the FPGA sampling clock, causing PPS edges to
+be separated by less or more than 100 million cycles of the FPGA clock.
+If this is the case, you can change the edge reference of the PPS signal
+with this parameter:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+usrp->set_time_source("_external_");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+<b>Note2:</b> For users generating their own signals for the external SMA
+connectors, the PPS should be clocked from the 10MHz reference. See the
+application notes for your device for specific signal requirements.
+
+\subsection sync_commonref_mimo MIMO cable reference signals
+
+Use the MIMO expansion cable to share reference sources (USRP2 and
+N-Series). The MIMO cable can be used synchronize one device to another
+device. Users of the MIMO cable may use Method 1 (explained below) to
+synchronize multiple pairs of devices.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+ usrp->set_clock_source("mimo");
+ usrp->set_time_source("mimo");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+\section sync_time Synchronizing the Device Time
+
+The purpose of the PPS signal is to synchronously latch a time into the
+device. You can use the `set_time_next_pps(...)` function to either
+initialize the sample time to 0 or an absolute time, such as GPS time or
+UTC time. For the purposes of synchronizing devices, it doesn't matter
+what time you initialize to when using `set_time_next_pps(...)`.
+
+\subsection sync_time_reg Method 1 - poll the USRP time registers
+
+One way to initialize the PPS edge is to poll the "last PPS" time from
+the USRP device. When the last PPS time increments, the user can
+determine that a PPS has occurred:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+ const uhd::time_spec_t last_pps_time = usrp->get_time_last_pps();
+ while (last_pps_time == usrp->get_time_last_pps()){
+ //sleep 100 milliseconds (give or take)
+ }
+ usrp->set_time_next_pps(uhd::time_spec_t(0.0));
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+\subsection sync_time_gpsdo Method 2 - query the GPSDO for seconds
+
+Most GPSDOs can be configured to output a NMEA string over the serial
+port once every PPS. The user can wait for this string to determine the
+PPS edge, and the user can also parse this string to determine GPS time:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+ //call user's function to wait for NMEA message...
+ usrp->set_time_next_pps(uhd::time_spec_t(0.0));
+
+ -- OR --
+
+ //call user's function to wait for NMEA message...
+ //call user's function to parse the NMEA message...
+ usrp->set_time_next_pps(uhd::time_spec_t(gps_time+1));
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+\subsection sync_time_internalgps Method 3 - internal GPSDO
+
+USRP devices with internal GPSDOs properly configured will automatically
+configure themselves to set the VITA time to current UTC time. See \ref page_gpsdo
+for more details.
+
+\subsection sync_time_mimocable Method 4 - MIMO cable
+
+A USRP device can synchronize its time to another USRP device via the
+MIMO cable. Unlike the other methods, this does not use a real "pulse
+per second". Rather, the USRP device sends an encoded time message over
+the MIMO cable. The slave device will automatically synchronize to the
+time on the master device. See \ref usrp2_mimocable for more detail.
+
+\section sync_phase Synchronizing Channel Phase
+
+\subsection sync_phase_cordics Align CORDICs in the DSP
+
+In order to achieve phase alignment between USRP devices, the CORDICS in
+both devices must be aligned with respect to each other. This is easily
+achieved by issuing stream commands with a time spec property, which
+instructs the streaming to begin at a specified time. Since the devices
+are already synchronized via the 10 MHz and PPS inputs, the streaming
+will start at exactly the same time on both devices. The CORDICs are
+reset at each start-of-burst command, so users should ensure that every
+start-of-burst also has a time spec set.
+
+For receive, a burst is started when the user issues a stream command.
+This stream command should have a time spec set:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+ uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
+ stream_cmd.num_samps = samps_to_recv;
+ stream_cmd.stream_now = false;
+ stream_cmd.time_spec = time_to_recv;
+ usrp->issue_stream_cmd(stream_cmd);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For transmit, a burst is started when the user calls send(). The
+metadata should have a time spec set: :
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+ uhd::tx_metadata_t md;
+ md.start_of_burst = true;
+ md.end_of_burst = false;
+ md.has_time_spec = true;
+ md.time_spec = time_to_send;
+
+ //send a single packet
+ 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)
+
+Using timed commands, multiple frontends can be tuned at a specific
+time. This timed-tuning ensures that the phase offsets between VCO/PLL
+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
+- This phase offset will drift over time due to thermal and other characteristics
+- Periodic calibration will be necessary for phase-coherent applications
+
+Code snippet example, tuning with timed commands: :
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+ //we will tune the frontends in 100ms from now
+ uhd::time_spec_t cmd_time = usrp->get_time_now() + uhd::time_spec_t(0.1);
+
+ //sets command time on all devices
+ //the next commands are all timed
+ usrp->set_command_time(cmd_time);
+
+ //tune channel 0 and channel 1
+ usrp->set_rx_freq(1.03e9, 0); // Channel 0
+ usrp->set_rx_freq(1.03e9, 1); // Channel 1
+
+ //end timed commands
+ usrp->clear_command_time();
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+\subsection sync_phase_lootherfe Align LOs in the front-end (others)
+
+After tuning the RF front-ends, each local oscillator may have a random
+phase offset due to the dividers in the VCO/PLL chains. This offset will
+remain constant after the device has been initialized, and will remain
+constant until the device is closed or re-tuned. This phase offset is
+typically removed by the user in MIMO applications, using a training
+sequence to estimate the offset. It will be necessary to re-align the
+LOs after each tune command.
+
+*/
+// vim:ft=doxygen: