Discussion:
Patch: Improve R820T tuner precision
Oliver Jowett
2014-08-23 22:46:07 UTC
Permalink
​Hi

I've made some changes to the R820T tuner code to improve the tuning
precision.
The old code lost some precision to rounding errors etc, causing an
unpredictable frequency-dependent tuning error over and above the limits of
the hardware itself.

The changes are in a github pull request here:
https://github.com/steve-m/librtlsdr/pull/10
(but the rtl-sdr page suggests I mention it here too, so here I am)

I've attached some graphs showing the results of these changes. These are
showing what happens to the apparent frequency of a nominally fixed
external signal (the GSM FCCH tone measured by kalibrate) when the tuner
frequency is changed. In an ideal world you'd expect that the apparent
frequency offset would change in lockstep with the tuner frequency;
anything different is tuner imprecision or oscillator drift.

At 954MHz these changes improve the tuning precision from approx +/-750Hz
to +/-200Hz.

Oliver
keenerd
2014-08-24 00:00:01 UTC
Permalink
I cleaned up the patch a little and applied it to my tree. I can't
vouch for the precision, but it builds, runs and doesn't seem to set
any small animals on fire.

The revised commit is at
https://github.com/keenerd/rtl-sdr/commit/f2328161ea
And a windows build is at
http://igg.kmkeen.com/builds/rtl-sdr-mingw32-v0.5.3.r32.gf232816.zip

I am a bit curious about the sigma-delta-mod math. We've got three
different sdm calculations now. The one in osmocom's repo, this new
one from O. Jowett and M. Bavaro's version
(http://michelebavaro.blogspot.com/2014/05/gnss-carrier-phase-rtlsdr-and.html).

-Kyle
http://kmkeen.com
Post by Oliver Jowett
Hi
I've made some changes to the R820T tuner code to improve the tuning
precision.
The old code lost some precision to rounding errors etc, causing an
unpredictable frequency-dependent tuning error over and above the limits of
the hardware itself.
https://github.com/steve-m/librtlsdr/pull/10
(but the rtl-sdr page suggests I mention it here too, so here I am)
I've attached some graphs showing the results of these changes. These are
showing what happens to the apparent frequency of a nominally fixed
external signal (the GSM FCCH tone measured by kalibrate) when the tuner
frequency is changed. In an ideal world you'd expect that the apparent
frequency offset would change in lockstep with the tuner frequency;
anything different is tuner imprecision or oscillator drift.
At 954MHz these changes improve the tuning precision from approx +/-750Hz
to +/-200Hz.
Oliver
Oliver Jowett
2014-08-24 00:22:06 UTC
Permalink
On 24 August 2014 01:00, keenerd <***@gmail.com> wrote:
I am a bit curious about the sigma-delta-mod math. We've got three
Post by keenerd
different sdm calculations now. The one in osmocom's repo, this new
one from O. Jowett and M. Bavaro's version
(
http://michelebavaro.blogspot.com/2014/05/gnss-carrier-phase-rtlsdr-and.html
).
Michele's looks equivalent to mine, I think; we seem to have independently
come up with the same thing:

vco_div = (pll_ref + 65536 * vco_freq) / (2 * pll_ref);
sdm = (uint32_t) (vco_div % 65536);

vs

mysdm = (((vco_freq<<16)+pll_ref)/(2*pll_ref)) & 0xFFFF;

The main differences versus the original osmocom code are

1) the old code works in kHz and runs into rounding issues since the
smallest frequency step is actually 400Hz-ish
2) the manual long division code looks dodgy (as Michele also noted)

This bit of the osmocom code seems to have been inherited wholesale from
the original "realtek driver" back in the mists of history - see e.g.
https://github.com/n1gp/gr-baz/blob/master/lib/rtl2832-tuner_r820t.cc - I
don't know if it's had much (any?) review.

FWIW I am just working empirically here - I don't have details of the
underlying hardware, I'm just assuming it's set up so that the VCO divisor
is effectively N + M/65536 since that seems plausible.

If the IF of the RTL2832U can be tweaked as Michele suggests (I have not
looked there at all) then you could improve the precision further.

Oliver
Oliver Jowett
2014-08-24 01:04:02 UTC
Permalink
On 24 August 2014 01:22, Oliver Jowett <***@gmail.com> wrote:
If the IF of the RTL2832U can be tweaked as Michele suggests (I have not
Post by Oliver Jowett
looked there at all) then you could improve the precision further.
Oliver Jowett
2014-08-24 09:25:51 UTC
Permalink
Post by keenerd
I am a bit curious about the sigma-delta-mod math. We've got three
Post by keenerd
different sdm calculations now. The one in osmocom's repo, this new
one from O. Jowett and M. Bavaro's version
(
http://michelebavaro.blogspot.com/2014/05/gnss-carrier-phase-rtlsdr-and.html
).
Michele's looks equivalent to mine, I think; we seem to have independently
vco_div = (pll_ref + 65536 * vco_freq) / (2 * pll_ref);
sdm = (uint32_t) (vco_div % 65536);
vs
mysdm = (((vco_freq<<16)+pll_ref)/(2*pll_ref)) & 0xFFFF;
This part is equivalent but there's a corresponding change in calculating
the integer part of the divisor that's needed. This affects a small range
of VCO frequencies just below integer multiples of 2*pll_ref.

e.g. with pll_ref = 28.8MHz, vco_freq = 4*pll_ref-1 = 115.199999MHz, my
code yields nint=2, sdm=0 (effective VCO frequency of 115.2MHz) but
Michele's yields nint=1,sdm=0 (effective 57.6MHz)

Try tuning to 802.829990MHz (with PPM correction=0) +/- a few Hz to see
this effect (note the values below are the tuner's LO frequency, so they
include the IF offset):

[R82XX] requested 806399890Hz; selected mix_div=4 vco_freq=3225599560
nint=55 sdm=65535; actual_vco=3225599121; tuning error=-109Hz
[R82XX] requested 806399891Hz; selected mix_div=4 vco_freq=3225599564
nint=56 sdm=0; actual_vco=3225600000; tuning error=+109Hz

Oliver

Loading...