# USRP tuning time

**URL:** <https://www.ruby-forum.com/t/usrp-tuning-time/242946>\
**Category:** GNU Radio\
**Created:** [August 9, 2015, 7:05pm UTC](https://www.ruby-forum.com/t/usrp-tuning-time/242946 "2015-08-09T19:05:51Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rafa\_F](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/958977/32.png) [@Rafa\_F](https://www.ruby-forum.com/u/Rafa_F)\
**Post date:** [August 9, 2015, 7:05pm UTC](https://www.ruby-forum.com/t/usrp-tuning-time/242946/1 "2015-08-09T19:05:51Z")

</div>

Dear all,

After quite some searching, I wasn’t able to find information about how  
long it takes to retune a USRP (say, change the centre frequency). Do  
you guys know anything about that? Specifically, I’m using a USRP X300  
with a UBX160 daughterboard. Does anyone know how long it takes in this  
specific setup to retune the daughterboard to a different centre  
frequency?

Kind regards and many thanks,  
Mat

---

<div class="post-metadata">

**Author:** ![okcomputer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/b38774/32.png) [@okcomputer](https://www.ruby-forum.com/u/okcomputer)\
**Post date:** [August 9, 2015, 8:03pm UTC](https://www.ruby-forum.com/t/usrp-tuning-time/242946/2 "2015-08-09T20:03:52Z")

</div>

Hi Mat,

the answer is a bit more complicated, I’m afraid:

so first of all, we need to distinguish latency from time it takes to  
tune.  
Latency happens if you want the device to tune as soon as possible, and  
will be mainly dominated by the latency of your general purpose OS  
running on your general purpose computer. It wildly varies, but good  
estimates on a properly configured PC might be around 5ms; your actual  
time might be different.

Now, you can /hide/ that latency by using timed commands if you know in  
advance when you want your tuning process to start. Then all there’s  
left is the “invalid” signal during the time the device actually tuned.

USRPs have a two-stage tuning: You get the configurable synthesizer that  
generates the LO for mixing down (and up), and you have the digital  
frequency shifter [1].  
The digital tuning happens /almost/ instantly. Basically, the moment the  
right register is set, the CORDIC uses a different phase increment [2];  
that can happen at every clock cycle of the master clock (ie. 200MHz by  
default on X300)[2].

Then, there’s the analog part. That’s where things get tricky, because  
a) we now have to take the time into account it takes to tell the LO  
synthesizer what we want to do, and b) the time it takes for the  
synthesizer to get stable, and c) there might be DC offset filters that  
might distort your signal.

_a) communication time_

This depends on the synthesizers used. The UBX uses MAX2871  
synthesizers. These are SPI chips; from the top of my head I don’t know  
at which rates the bus is clocked, but let’s assume it’s “sufficiently  
fast” (\>\>1Mb/s). So let’s subsume that with 20?s max.  
Now a speciality for the UBX: if the LO synthesizer you want to tune is  
turned off, it must be started first. Typically, you’d only have that at  
initialization, but since the UBX spans so much spectrum, different  
clock lines have been introduced, and hence, a separate synthesizer for  
frequencies below and above 500MHz each. So when crossing that boundary,  
assume at least 20ms additional startup time.

_b) analog/real-world hardware stuff_

Things get tricky here, and I can’t actually give you a definite answer.  
Tuning speed depends on too many factors, some of which aren’t even  
controllable. Looking through datasheets and at the loop filter  
components, I’d say a locking time of up to 100?s might be realistic.  
However, that’s a bit up to you as user; the less accuracy you need, the  
shorter you can wait for the LO to successfully lock. After all,  
“locked” is just the notion that PLL oscillations have dropped below an  
arbitrary level.

\_c) DC offset filtering  
\_  
RX only:  
To eliminate the DC offset that the ADC might measure, there’s a DC  
offset filter. It’s an IIR whose sole accumulator gets reset at every  
tune. Depending on how far the real DC offset is from 0, the IIR’s step  
response might or might not be visible for up to 40ms, if I remember  
correctly. You can disable the DC offset removal, however, with the  
multi\_usrp::set\_rx\_dc\_offset(false); however, DC offset removal is then  
up to you; this might or might not be a problem for your application.

Best regards,  
Marcus

[1]  
[http://files.ettus.com/manual/page\_general.html#general\_tuning\_process](http://files.ettus.com/manual/page_general.html#general_tuning_process)  
[2a]

> <https://github.com/EttusResearch/fpga/blob/master/usrp3/lib/dsp/duc_chain.v#L41>

[2b]

> <https://github.com/EttusResearch/fpga/blob/master/usrp3/lib/dsp/duc_chain.v#L82>

[2c]

> <https://github.com/EttusResearch/fpga/blob/master/usrp3/lib/dsp/duc_chain.v#L193>

[2d]

> <https://github.com/EttusResearch/fpga/blob/master/usrp3/lib/dsp/cordic_z24.v>

---

<div class="post-metadata">

**Author:** ![okcomputer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/b38774/32.png) [@okcomputer](https://www.ruby-forum.com/u/okcomputer)\
**Post date:** [August 10, 2015, 2:00pm UTC](https://www.ruby-forum.com/t/usrp-tuning-time/242946/3 "2015-08-10T14:00:24Z")

</div>

hey man,

many many thanks for the detailed reply! Based on it, I decided to  
achieve frequency hopping not by changing the centre frequency of the  
USRP, but by multiplying my signal with a sine of a certain frequency  
offset and then transmit that signal over the USRP with a fixed USRP.  
Unfortunately, a new problem has arisen. you can see my flowgraph  
attached

I want my signal to be transmitted on 5.804GHz. to this end, the centre  
frequency is set to 5.799GHz, and the signal that I wish to transmit is  
multiplied with a sine wave of 5MHz. (I’m storing everything as a file  
before transmitting, as things are otherwise too slow). The problem now  
is that when I transmit the signal over the USRP, it is not transmitted  
on 5804 MHz but on approx. 5802 MHz. Furthermore, this error appears to  
become bigger with bigger frequency offsets: When I want the signal to  
be transmitted with 20MHz offset to the centre frequency of the usrp  
(thus using a sine wave of 20MHz), the difference between the intended  
signal frequency and the true signal frequency is almost 10 MHz!

Am I doing anything wrong here??

kind regards and thanks so much,  
Mat

---

<div class="post-metadata">

**Author:** ![okcomputer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/b38774/32.png) [@okcomputer](https://www.ruby-forum.com/u/okcomputer)\
**Post date:** [August 10, 2015, 3:05pm UTC](https://www.ruby-forum.com/t/usrp-tuning-time/242946/4 "2015-08-10T15:05:36Z")

</div>

well here’s the thing: I need to transmit a burst every 7ms (in each  
burst transmit 37bytes at 1 MBit/s). From what  
you’ve written about tuning times, i got somewhat pessimistic as to  
whether this is enough time to retune. Or would you say that this should  
be enough?

---

<div class="post-metadata">

**Author:** ![okcomputer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/b38774/32.png) [@okcomputer](https://www.ruby-forum.com/u/okcomputer)\
**Post date:** [August 10, 2015, 3:25pm UTC](https://www.ruby-forum.com/t/usrp-tuning-time/242946/5 "2015-08-10T15:25:40Z")

</div>

I’d just try. Clearly, physically retuning is bad in this case, but if  
you haven’t tried with the stream tag approach, you should.

Other than that, I think a relatively small patch to the USRP sink would  
add a tx\_tune tag, doing the same as the message of the same name,  
namely allowing you to specify exactly how you want to tune  
(DSP/analog).

Best regards,  
Marcus

---

<div class="post-metadata">

**Author:** ![okcomputer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/b38774/32.png) [@okcomputer](https://www.ruby-forum.com/u/okcomputer)\
**Post date:** [August 10, 2015, 3:36pm UTC](https://www.ruby-forum.com/t/usrp-tuning-time/242946/6 "2015-08-10T15:36:47Z")

</div>

Hell. I haven’t tried this, but:  
If you’re building GNU Radio from source, you can use this:

> **[GitHub - marcusmueller/gnuradio at uhd\_add\_tx\_tune\_tag\_handling](https://github.com/marcusmueller/gnuradio/tree/uhd_add_tx_tune_tag_handling)**
>
> uhd\_add\_tx\_tune\_tag\_handling

ie. in your gnu radio directory do something like (assuming you’re on  
the master branch)

git pull [GitHub - marcusmueller/gnuradio: GNU Radio](https://github.com/marcusmueller/gnuradio.git)  
uhd\_add\_tx\_tune\_tag\_handling

Best regards,  
Marcus

PS: You’re a regular poster now. Get rid of ruby-forum and directly sign  
up for the mailing list!  
Ruby-Forum doesn’t properly reply to the mail you content-wisely reply  
reliably.

---

<div class="post-metadata">

**Author:** ![okcomputer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/b38774/32.png) [@okcomputer](https://www.ruby-forum.com/u/okcomputer)\
**Post date:** [August 10, 2015, 3:00pm UTC](https://www.ruby-forum.com/t/usrp-tuning-time/242946/7 "2015-08-10T15:00:33Z")

</div>

Hi Mat,

> I decided to achieve frequency hopping not by changing the centre  
> frequency of the USRP, but by multiplying my signal with a sine of a  
> certain frequency offset and then transmit that signal over the USRP  
> with a fixed USRP.  
> That’s cool, but it’s exactly what the FPGA of the USRP would have done  
> for you if you just used DSP tuning; but without having to use the full  
> sampling rate that covers the whole analog band. I do agree, it’s often  
> easier to implement things this way, because everything stays within  
> control of your software.

The errors you describe sound like your USRP is actually running at a  
different rate than what you’ve set. And in fact, the 150MHz you set are  
not a rate that is possible with any master clock rate. You’ll need to  
use an integer factor of your master clock rate, which by default is  
200MHz (but can also be configured to be 120MHz or 184.3MHz). So  
possible rates are 200MS/s / 1, 200MS/s / 2, 200MS/s / 3 and so on. The  
console output of your script should actually tell you that the rate is  
unsupported and a different rate was used.

I’d say that it might really be a good choice to let the FPGA do this;  
it’s nothing you must task your CPU with if your USRP can do it! In  
fact, it would not be overly hard to add the DSP-only tuning via stream  
tags to the USRP sink, but since this might solve your problem  
sufficiently well, why don’t you try adding stream tags? For example,  
replace your sinus source with a vector source with a constant list as  
value (e.g. [1.0] \* 1000\* 3000) and a tags parameter, like the  
following:

[ gr.tag\_utils.python\_to\_tag( (n_1000, pmt.intern(“tx\_freq”),  
pmt.from\_double(2.5e9 + n_1000), pmt.intern(“src”)) ) for n in  
xrange(3000) ]

that should instruct the USRP sink to tune every 1000 samples. That way,  
you don’t have to interpolate to the full physical DAC rate, but just  
enough to allow your frequency mod to work (which probably is much much  
less).

Best regards,  
Marcus
