From 4c2e07593fc9e8c3a1ad842eb0dd93a3c8c329c1 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 29 May 2011 18:43:23 -0400 Subject: uhd: work on sync docs --- host/docs/CMakeLists.txt | 1 + host/docs/index.rst | 1 + host/docs/sync.rst | 118 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 host/docs/sync.rst diff --git a/host/docs/CMakeLists.txt b/host/docs/CMakeLists.txt index 1a2738647..5926e062e 100644 --- a/host/docs/CMakeLists.txt +++ b/host/docs/CMakeLists.txt @@ -26,6 +26,7 @@ SET(manual_sources dboards.rst general.rst images.rst + sync.rst transport.rst usrp1.rst usrp2.rst diff --git a/host/docs/index.rst b/host/docs/index.rst index 467d5f385..40fe64599 100644 --- a/host/docs/index.rst +++ b/host/docs/index.rst @@ -27,6 +27,7 @@ Application Notes * `USRP-E1XX Series Application Notes <./usrp_e1xx.html>`_ * `Daughterboard Application Notes <./dboards.html>`_ * `Transport Application Notes <./transport.html>`_ +* `Synchronization Application Notes <./sync.html>`_ ^^^^^^^^^^^^^^^^^^^^^ API Documentation diff --git a/host/docs/sync.rst b/host/docs/sync.rst new file mode 100644 index 000000000..a33fa134d --- /dev/null +++ b/host/docs/sync.rst @@ -0,0 +1,118 @@ +======================================================================== +UHD - Synchronization Application Notes +======================================================================== + +.. contents:: Table of Contents + +The following application notes explain how to synchronize multiple USRPs +with the goal of transmitting or receiving time-aligned samples. + +**Note:** The following synchronization notes do not apply to USRP1 +which does not support the advanced features available in newer products. + +------------------------------------------------------------------------ +Common reference signals +------------------------------------------------------------------------ +USRPs take two reference signals in order to synchronize clocks and time. + +* A 10MHz reference to synchronize the clocks across devices. +* A pulse-per-second to synchronize the time across devices. + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Provide reference signals +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Most USRPs have front panel SMA connectors to source these signals externally. +Alternatively, some USRP models support an optional internal GPSDO. +Typically, these signals are provided from a GPSDO. +For user's generating their own signals, +the pulse-per-second should be clocked off of the 10MHz reference. +See the application notes for your device for specific signal requirements. + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Set the clock configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The user should set the "external" clock configuration when configuring the USRP device object. +:: + + usrp->set_clock_config(uhd::clock_config_t::external()); + +------------------------------------------------------------------------ +Synchronizing the device time +------------------------------------------------------------------------ +The purpose of the PPS signal is to synchronously latch a time into the device. +The device time may be absolute (GPS, UTC) or relative. +The user should decide what is most useful to the application. +To synchronously set the device time, +the user should determine the PPS edge, +and then make the API call set_time_next_pps(...). +The user can determine the PPS edge in a variety of ways... + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Method 1 - poll the USRP time registers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +One way to catch 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. + +:: + + 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)); + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Method 2 - query the GPSDO for seconds +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Most GPSDO 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. + +:: + + //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)); + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Method 3 - query the gps_time sensor +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +This is a variant of method 2 for USRPs with internal GPSDOs. +The user can query the gps_time sensor to wait for the NMEA string. + +:: + + //wait for NMEA string from internal GPSDO + usrp->get_mboard_sensor("gps_time"); + usrp->set_time_next_pps(uhd::time_spec_t(0.0)); + + -- OR -- + + //wait for the NMEA string and set GPS time + const time_t gps_time = usrp->get_mboard_sensor("gps_time").to_int(); + usrp->set_time_next_pps(uhd::time_spec_t(gps_time+1)); + +------------------------------------------------------------------------ +Synchronizing multiple channels +------------------------------------------------------------------------ + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Synchronizing the cordics +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The frequency translation between baseband and IF can introduce a phase ambiguity between channels. +This is due to the property that the cordic in the DSP chain can have a random phase offset. +Fortunately, the cordic is reset on each start-of-burst. +Therefore, the method to phase-align the cordics is to coordinate streaming at a particular time. + +For receive, a burst is started when the user issues a stream command. This stream command should have a time spec set. +For transmit, a burst is started when the user calls send. The metadata should have a time spec and start of burst set. + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Synchronizing the RF LOs +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + -- cgit v1.2.3 From 22bfca2687d28b9eb9534fe2513b984b36664838 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 31 May 2011 02:46:26 -0400 Subject: uhd: notes on LO calibration, and tweaks --- host/docs/sync.rst | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/host/docs/sync.rst b/host/docs/sync.rst index a33fa134d..15f3b10cf 100644 --- a/host/docs/sync.rst +++ b/host/docs/sync.rst @@ -21,11 +21,11 @@ USRPs take two reference signals in order to synchronize clocks and time. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Provide reference signals ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Most USRPs have front panel SMA connectors to source these signals externally. -Alternatively, some USRP models support an optional internal GPSDO. -Typically, these signals are provided from a GPSDO. +Most USRPs have front panel SMA connectors to source these reference signals. +Typically, these signals are provided by an external GPSDO. +Some USRP models can provide these signals from an optional internal GPSDO. For user's generating their own signals, -the pulse-per-second should be clocked off of the 10MHz reference. +the pulse-per-second should be clocked from the 10MHz reference. See the application notes for your device for specific signal requirements. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -98,21 +98,41 @@ The user can query the gps_time sensor to wait for the NMEA string. usrp->set_time_next_pps(uhd::time_spec_t(gps_time+1)); ------------------------------------------------------------------------ -Synchronizing multiple channels +Synchronizing channel phase ------------------------------------------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Synchronizing the cordics +Align CORDICs in the DSP ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The frequency translation between baseband and IF can introduce a phase ambiguity between channels. This is due to the property that the cordic in the DSP chain can have a random phase offset. -Fortunately, the cordic is reset on each start-of-burst. +Fortunately, the CORDIC is reset on each start-of-burst. Therefore, the method to phase-align the cordics is to coordinate streaming at a particular time. -For receive, a burst is started when the user issues a stream command. This stream command should have a time spec set. -For transmit, a burst is started when the user calls send. The metadata should have a time spec and start of burst set. +* For receive, a burst is started when the user issues a stream command. This stream command should have a time spec set. +* For transmit, a burst is started when the user calls send. The metadata should have a time spec and start of burst set. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Synchronizing the RF LOs +Align LOs in the front-end ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - +After tuning the RF front-ends, +each local oscillator will have a random phase offset. +Some daughterboards have mechanisms to phase-align the oscillators, +however, these mechanisms are not currently implemented. +In any case, LO phase-alignment will not forgo the need for calibration. + +**RX Calibration** + +1) Tune the setup. +2) Receive known signals. +3) Capture calibration data. +4) Do not re-tune. +5) Receive live data. + +**TX Calibration** + +1) Tune the setup. +2) Transmit known signals. +3) Capture calibration data. +4) Do not re-tune. +5) Transmit live data. -- cgit v1.2.3 From 289a24e54f3a3bc6aef096dfca58113ae573eaae Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 31 May 2011 11:24:18 -0400 Subject: usrp2: added app notes on multi channel RX --- host/docs/usrp2.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/host/docs/usrp2.rst b/host/docs/usrp2.rst index 2eb3ee796..904005ce0 100644 --- a/host/docs/usrp2.rst +++ b/host/docs/usrp2.rst @@ -393,3 +393,20 @@ they can be queried through the API. * mimo_locked - clock reference locked over the MIMO cable * ref_locked - clock reference locked (internal/external) * gps_time - GPS seconds (available when GPSDO installed) + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Multiple RX channels +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +There are two complete DDC chains in the FPGA. +In the single channel case, only one chain is ever used. +To receive from both channels, +the user must set the RX subdevice specification. +This hardware has only one daughterboard slot, +which has been aptly named slot "0". + +In the following example, a TVRX2 is installed. +Channel 0 is sourced from subdevice RX1, +channel 1 is sourced from subdevice RX2: +:: + + usrp->set_rx_subdev_spec("0:RX1 0:RX2"); -- cgit v1.2.3 From c41328816b96fdf01119de4960069ebbc201da8d Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 31 May 2011 12:54:10 -0400 Subject: uhd: added app notes to docs on tuning --- host/docs/general.rst | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/host/docs/general.rst b/host/docs/general.rst index 73b820c84..ff85fb0f9 100644 --- a/host/docs/general.rst +++ b/host/docs/general.rst @@ -5,7 +5,63 @@ UHD - General Application Notes .. contents:: Table of Contents ------------------------------------------------------------------------ -Misc notes +Tuning notes +------------------------------------------------------------------------ + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Two-stage tuning process +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +A USRP device has two stages of tuning: + +* RF front-end: translates bewteen RF and IF +* DSP: translates between IF and baseband + +In a typical use-case, the user specifies an overall center frequency for the signal chain. +The RF front-end will be tuned as close as possible to the center frequency, +and the DSP will account for the error in tuning between target frequency and actual frequency. +The user may also explicitly control both stages of tuning through the tune_request_t object. + +Pseudo-code for tuning the receive chain: +:: + + //tuning to a desired center frequency + usrp->set_rx_freq(my_frequency_in_hz); + + --OR-- + + //advanced tuning with tune_request_t + uhd::tune_request_t tune_req; + tune_req.target_freq = my_frequency_in_hz; + //fill in tune request fields... + usrp->set_rx_freq(tune_req); + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +RF front-end settling time +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +After tuning, the RF front-end will need time to settle into a usable state. +Typically, this means that the local oscillators must be given time to lock before streaming begins. +Lock time is not consistent; it varies depending upon the device and requested settings. +After tuning and before streaming, the user should +wait for the "lo_locked" sensor to become true, +or sleep for a conservative amount of time (perhaps a second). + +Pseudo-code for dealing with settling time after tuning on receive: +:: + + usrp->set_rx_freq(...); + sleep(1); + usrp->issue_stream_command(...); + + --OR-- + + usrp->set_rx_freq(...); + while (not usrp->get_rx_sensor("lo_locked").to_bool()){ + //sleep for a short time in milliseconds + } + usrp->issue_stream_command(...); + +------------------------------------------------------------------------ +Threading notes ------------------------------------------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,6 +102,10 @@ Add the following line to */etc/security/limits.conf*: Replace with a group to which your user belongs. Settings will not take effect until the user has logged in and out. +------------------------------------------------------------------------ +Misc notes +------------------------------------------------------------------------ + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Support for dynamically loadable modules ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- cgit v1.2.3 From e081fe1f098c09a2661e954bec3e511dfc28c897 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Wed, 1 Jun 2011 09:09:24 -0700 Subject: updated sync doc for clarity & examples --- host/docs/sync.rst | 106 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 64 insertions(+), 42 deletions(-) diff --git a/host/docs/sync.rst b/host/docs/sync.rst index 15f3b10cf..7e9ea11f4 100644 --- a/host/docs/sync.rst +++ b/host/docs/sync.rst @@ -5,18 +5,19 @@ UHD - Synchronization Application Notes .. contents:: Table of Contents The following application notes explain how to synchronize multiple USRPs -with the goal of transmitting or receiving time-aligned samples. +with the goal of transmitting or receiving time-aligned samples for MIMO +or other applications requiring multiple USRPs operating synchronously. -**Note:** The following synchronization notes do not apply to USRP1 +**Note:** The following synchronization notes do not apply to USRP1, which does not support the advanced features available in newer products. ------------------------------------------------------------------------ Common reference signals ------------------------------------------------------------------------ -USRPs take two reference signals in order to synchronize clocks and time. +USRPs take two reference signals in order to synchronize clocks and time: -* A 10MHz reference to synchronize the clocks across devices. -* A pulse-per-second to synchronize the time across devices. +* A 10MHz reference to provide a single frequency reference for both devices, and +* A pulse-per-second (1PPS) to synchronize the sample time across devices. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Provide reference signals @@ -24,14 +25,16 @@ Provide reference signals Most USRPs have front panel SMA connectors to source these reference signals. Typically, these signals are provided by an external GPSDO. Some USRP models can provide these signals from an optional internal GPSDO. -For user's generating their own signals, +For users generating their own signals, the pulse-per-second should be clocked from the 10MHz reference. See the application notes for your device for specific signal requirements. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Set the clock configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The user should set the "external" clock configuration when configuring the USRP device object. +In order to synchronize to an external clock, configure the USRP device +using the "external" clock configuration: + :: usrp->set_clock_config(uhd::clock_config_t::external()); @@ -40,18 +43,24 @@ The user should set the "external" clock configuration when configuring the USRP Synchronizing the device time ------------------------------------------------------------------------ The purpose of the PPS signal is to synchronously latch a time into the device. -The device time may be absolute (GPS, UTC) or relative. -The user should decide what is most useful to the application. -To synchronously set the device time, -the user should determine the PPS edge, -and then make the API call set_time_next_pps(...). -The user can determine the PPS edge in a variety of ways... +You can use the set_time_next_pps(...) function to either initialize the sample time to 0, +or to 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(...). + +Some GPSDOs synchronize their PPS with the rising edge of the 10MHz clock, +and some synchronize with the falling edge of the clock. +You should find out which edge your GPSDO uses, +and then pass that in as an argument to set_time_next_pps(...). + +Here are two examples of how to set the PPS time to synchronize USRPs +to a clock source. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Method 1 - poll the USRP time registers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -One way to catch 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. +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: :: @@ -66,7 +75,7 @@ Method 2 - query the GPSDO for seconds ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Most GPSDO 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. +and the user can also parse this string to determine GPS time: :: @@ -104,35 +113,48 @@ Synchronizing channel phase ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Align CORDICs in the DSP ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The frequency translation between baseband and IF can introduce a phase ambiguity between channels. -This is due to the property that the cordic in the DSP chain can have a random phase offset. -Fortunately, the CORDIC is reset on each start-of-burst. -Therefore, the method to phase-align the cordics is to coordinate streaming at a particular time. +In order to achieve phase alignment between USRPs, 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 10MHz 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. + +:: + + uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); + stream_cmd.num_samps = spb; + stream_cmd.stream_now = false; + stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future); + usrp->issue_stream_cmd(stream_cmd); + +For transmit, a burst is started when the user calls send(). The metadata should have a time spec and start of burst set. + +:: + + uhd::tx_metadata_t md; + md.start_of_burst = true; + md.end_of_burst = false; + md.has_time_spec = true; + md.time_spec = uhd::time_spec_t(time_to_send); -* For receive, a burst is started when the user issues a stream command. This stream command should have a time spec set. -* For transmit, a burst is started when the user calls send. The metadata should have a time spec and start of burst set. + //send a single packet + size_t num_tx_samps = usrp->get_device()->send( + buffs, samps_to_send, md, + uhd::io_type_t::COMPLEX_FLOAT32, + uhd::device::SEND_MODE_ONE_PACKET, timeout + ); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Align LOs in the front-end ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ After tuning the RF front-ends, -each local oscillator will have a random phase offset. -Some daughterboards have mechanisms to phase-align the oscillators, -however, these mechanisms are not currently implemented. -In any case, LO phase-alignment will not forgo the need for calibration. - -**RX Calibration** - -1) Tune the setup. -2) Receive known signals. -3) Capture calibration data. -4) Do not re-tune. -5) Receive live data. - -**TX Calibration** - -1) Tune the setup. -2) Transmit known signals. -3) Capture calibration data. -4) Do not re-tune. -5) Transmit live data. +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. -- cgit v1.2.3