Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IQ amplitude phase correction #3

Open
wants to merge 64 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
284fd4d
driver: tejeez's no-mod direct sampling
keenerd Jan 25, 2014
7d70b00
utils: tejeez's no-mod direct sampling
keenerd Jan 25, 2014
389de6d
utils: rebase ppm in eeprom prototype
keenerd Jan 25, 2014
e8d1d26
modprobe rules
keenerd Jan 29, 2014
3dfa4ad
rtl_fm: esbensen's discriminant
keenerd Jan 30, 2014
3f2632d
r82xx: set_dithering()
keenerd Aug 2, 2014
a7caaac
r82xx: tejeez's if/bw filters
keenerd Aug 2, 2014
4198f7d
r82xx: register caching
keenerd Aug 3, 2014
a0b6131
r82xx: register batching
keenerd Aug 3, 2014
d59b178
lib: cache i2c repeater
keenerd Aug 3, 2014
29d2c84
r82xx: pll tweaks beyond my ken
keenerd Aug 3, 2014
0bba67a
r82xx: error on pll failure
keenerd Aug 4, 2014
c5d7ebe
rtl_test: r820t tuning range
keenerd Aug 4, 2014
fba7708
r82xx: build warning
keenerd Aug 5, 2014
588b673
rtl_fm: half working AGC
keenerd Aug 6, 2014
6d5cd16
rtl_fm: wav header
keenerd Aug 7, 2014
42d8f12
rtl_fm: mostly working AGC
keenerd Aug 11, 2014
9ed9ffa
lib: retry i2c on failure
keenerd Aug 11, 2014
3cb8bd6
rtl_fm: proportional squelch
keenerd Aug 12, 2014
08889ee
rtl_fm, power: stay open through broken pipes
keenerd Aug 14, 2014
00a74f0
rtl_sdr: units on -n
keenerd Aug 15, 2014
e98ab40
rtl_fm: half finished stream padding
keenerd Aug 16, 2014
3223086
rtl_power: fixed size bins, refactoring
keenerd Aug 20, 2014
40bf3cb
rtl_power: adjustable sample rate
keenerd Aug 22, 2014
6d9bb99
rtl_power: multiple frequency ranges
keenerd Aug 23, 2014
225f401
rtl_power: linear output
keenerd Aug 23, 2014
f232816
r82xx: improved tuner precision
mutability Aug 23, 2014
f9ce8bd
rtl_power: bugfix for odd bin numbers
keenerd Aug 25, 2014
ecae3d5
rtl_power: fix bugs with bin counting
keenerd Aug 26, 2014
ebb5f2a
rtl_fm: bugfix from M. Curtis
keenerd Aug 26, 2014
e23b92c
rtl_fm: in-place demodulators
keenerd Aug 26, 2014
34ab4ac
rtl_fm: no-copy architecture
keenerd Aug 26, 2014
6d57803
r82xx: remove incorrect error from reg caching
mutability Aug 26, 2014
f3b45e1
rtl_power: doc corrections
keenerd Aug 27, 2014
06af0f9
r82xx: direct sampling fixes from tejeez
keenerd Aug 27, 2014
15bb16b
rtl_fm: fix lockup on squelch
keenerd Aug 28, 2014
5e13808
rtl_power: more bug fixes
keenerd Aug 28, 2014
a710e4e
rtl_test: generic tuner range test
mutability Aug 28, 2014
1cf9215
r82xx: enforce PLL register limits.
mutability Aug 29, 2014
c918fda
rtl_fm: link librt
keenerd Aug 31, 2014
92a684c
rtl_test: refactor tuner_benchmark
keenerd Aug 31, 2014
05bee34
rtl_fm: handle no availible buffers
keenerd Aug 31, 2014
6bcea88
rtl_fm: arbitrary translation prototype
keenerd Sep 1, 2014
90706d4
rtl_fm: remove unused resamplers
keenerd Sep 1, 2014
df2a9c0
rtl_fm: software agc
keenerd Sep 1, 2014
88244c0
rtl_fm: sw-agc quantization correction
keenerd Sep 1, 2014
581b6b6
rtl_fm: pad out single channel underruns
keenerd Sep 2, 2014
c813134
rtl_fm: stream padding
keenerd Sep 3, 2014
53d212d
rtl_fm: half finished dual-channel mode
keenerd Sep 4, 2014
0037e5f
rtl_fm: arbitrary translation
keenerd Sep 8, 2014
8ad17c2
rtl_fm: three-quarters of dual channel
keenerd Sep 8, 2014
1b1c03d
rtl_power: fix NaN on 32 bit platforms (T. Kaminski)
keenerd Oct 17, 2014
012ca95
rtl_test: Support PPM error measurement on Windows.
kasper93 Nov 1, 2014
61e2b66
rtl_fm: Support output padding on Windows.
kasper93 Nov 1, 2014
d426cfd
convenience: No junk when device info isn't properly extracted.
kasper93 Nov 1, 2014
a2d23c5
rtl_fm: Avoid possible null pointer dereference.
kasper93 Nov 1, 2014
6aa5f17
Variable cleanup and corrections.
kasper93 Nov 1, 2014
5ba8898
build: Fix compilation on VS2013, Cygwin and MinGW.
kasper93 Oct 30, 2014
bc872cb
build: libusb pkgconfig for NixOS
keenerd Nov 13, 2014
f1e8e4d
rtl_power: improved hopping math
keenerd Dec 1, 2014
3c01571
rtl_power: fix peak hold
keenerd Dec 1, 2014
c6e6be5
rtl_power: epoch time
keenerd Dec 1, 2014
86f9503
rtl_fm: add swagc-aggressive
Mar 29, 2015
0d825fe
rtl_power: trough hold
keenerd Jan 1, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
rtl_test: generic tuner range test
This scans 0 - 3GHz looking for frequencies that can be tuned to without
error, and refines the band edges further once a tuneable band is found. It
should work with any tuner that correctly reports tuning errors. It takes
about 1.5 minutes to complete on a R820T.
mutability authored and keenerd committed Sep 2, 2014
commit a710e4eed2a1662fa758b3d538e7643760330d52
213 changes: 143 additions & 70 deletions src/rtl_test.c
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@ void usage(void)
"Usage:\n"
"\t[-s samplerate (default: 2048000 Hz)]\n"
"\t[-d device_index (default: 0)]\n"
"\t[-t enable E4000 or R820T tuner range benchmark]\n"
"\t[-t enable tuner range benchmark]\n"
#ifndef _WIN32
"\t[-p[seconds] enable PPM error measurement (default: 10 seconds)]\n"
#endif
@@ -221,79 +221,161 @@ static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
#endif
}

void e4k_benchmark(void)
{
uint32_t freq, gap_start = 0, gap_end = 0;
uint32_t range_start = 0, range_end = 0;
/* smallest band or band gap that tuner_benchmark() will notice */
static uint32_t max_step(uint32_t freq) {
if (freq < 1e6)
return 1e4;
if (freq > 1e8)
return 1e6;
return freq / 1e2;
}

fprintf(stderr, "Benchmarking E4000 PLL...\n");
/* precision with which tuner_benchmark() will measure the edges of bands */
static uint32_t min_step(uint32_t freq) {
return 100;
}

/* find tuner range start */
for (freq = MHZ(70); freq > MHZ(1); freq -= MHZ(1)) {
if (rtlsdr_set_center_freq(dev, freq) < 0) {
range_start = freq;
break;
}
}
static void report_band_start(uint32_t start) {
fprintf(stderr, "Found a new band starting at %u Hz\n", start);
}

/* find tuner range end */
for (freq = MHZ(2000); freq < MHZ(2300UL); freq += MHZ(1)) {
if (rtlsdr_set_center_freq(dev, freq) < 0) {
range_end = freq;
break;
}
}
static void report_band(uint32_t low, uint32_t high) {
fprintf(stderr, "Tuning band: %u - %u Hz\n", low, high);
}

/* find start of L-band gap */
for (freq = MHZ(1000); freq < MHZ(1300); freq += MHZ(1)) {
if (rtlsdr_set_center_freq(dev, freq) < 0) {
gap_start = freq;
break;
}
void tuner_benchmark(void)
{
uint32_t current = max_step(0);
uint32_t band_start = 0;
uint32_t low_bound = 0, high_bound = 0;
char buf[20];
enum { FIND_START, REFINE_START, FIND_END, REFINE_END } state;

fprintf(stderr, "Testing tuner range. This may take a couple of minutes..\n");

/* Scan for tuneable frequencies coarsely. When we find something,
* do a binary search to narrow down the exact edge of the band.
*
* This can potentially miss bands/gaps smaller than max_step(freq)
* but it is a lot faster than exhaustively scanning everything.
*/

/* handle bands starting at 0Hz */
if (rtlsdr_set_center_freq(dev, 0) < 0)
state = FIND_START;
else {
band_start = 0;
report_band_start(band_start);
state = FIND_END;
}

/* find end of L-band gap */
for (freq = MHZ(1300); freq > MHZ(1000); freq -= MHZ(1)) {
if (rtlsdr_set_center_freq(dev, freq) < 0) {
gap_end = freq;
while (current < 3e9 && !do_exit) {
switch (state) {
case FIND_START:
/* scanning for the start of a new band */
if (rtlsdr_set_center_freq(dev, current) < 0) {
/* still looking for a band */
low_bound = current;
current += max_step(current);
} else {
/* new band, starting somewhere at or before current */
/* low_bound < start <= current */
high_bound = current;
state = REFINE_START;
}
break;
}
}

fprintf(stderr, "E4K range: %i to %i MHz\n",
range_start/MHZ(1) + 1, range_end/MHZ(1) - 1);

fprintf(stderr, "E4K L-band gap: %i to %i MHz\n",
gap_start/MHZ(1), gap_end/MHZ(1));
}

void r820t_benchmark(void)
{
uint32_t freq;
uint32_t range_start = 0, range_end = 0;

fprintf(stderr, "Benchmarking R820T PLL...\n");
case REFINE_START:
/* refining the start of a band */
/* low_bound < bandstart <= high_bound */
if (rtlsdr_set_center_freq(dev, current) == 0) {
/* current is inside the band */
/* low_bound < bandstart <= current */
if (current - low_bound <= min_step(current)) {
/* start found at low_bound */
band_start = current;
report_band_start(band_start);
low_bound = current;
current = band_start + max_step(band_start);
state = FIND_END;
} else {
/* binary search */
high_bound = current;
current = (current + low_bound) / 2;
}
} else {
/* current is outside the band */
/* current < bandstart <= high_bound */
if (high_bound - current <= min_step(current)) {
/* start found at high_bound */
low_bound = band_start = high_bound;
report_band_start(band_start);
current = band_start + max_step(band_start);
state = FIND_END;
} else {
/* binary search */
low_bound = current;
current = (current + high_bound) / 2;
}
}
break;

/* find tuner range start */
for (freq = MHZ(30); freq > MHZ(1); freq -= MHZ(1)) {
if (rtlsdr_set_center_freq(dev, freq)) {
break;}
range_start = freq;
}
case FIND_END:
/* scanning for the end of the current band */
if (rtlsdr_set_center_freq(dev, current) == 0) {
/* still looking for the end of the band */
low_bound = current;
current += max_step(current);
} else {
/* end found, coarsely */
/* low_bound <= bandend < current, refine it */
high_bound = current;
state = REFINE_END;
}
break;

/* find tuner range end */
for (freq = MHZ(1750); freq < MHZ(1950UL); freq += MHZ(1)) {
if (rtlsdr_set_center_freq(dev, freq)) {
break;}
range_end = freq;
case REFINE_END:
/* refining the end of a band */
/* low_bound <= bandend < high_bound */
if (rtlsdr_set_center_freq(dev, current) < 0) {
/* current is outside the band */
/* low_bound <= bandend < current */
if (current - low_bound <= min_step(current)) {
/* band ends at low_bound */
report_band(band_start, low_bound);
low_bound = current;
current = low_bound + max_step(low_bound);
state = FIND_START;
} else {
/* binary search */
high_bound = current;
current = (current + low_bound) / 2;
}
} else {
/* current is inside the band */
/* current <= bandend < high_bound */
if (high_bound - current <= min_step(current)) {
/* band ends at high_bound */
report_band(band_start, current);
low_bound = high_bound;
current = low_bound + max_step(low_bound);
state = FIND_START;
} else {
/* binary search */
low_bound = current;
current = (current + high_bound) / 2;
}
}
break;
}
}

fprintf(stderr, "R820T range: %i to %i MHz\n",
range_start/MHZ(1), range_end/MHZ(1));
if (state == FIND_END)
report_band(band_start, current);
else if (state == REFINE_END)
report_band(band_start, low_bound);
}



int main(int argc, char **argv)
{
#ifndef _WIN32
@@ -387,16 +469,7 @@ int main(int argc, char **argv)
verbose_set_sample_rate(dev, samp_rate);

if (test_mode == TUNER_BENCHMARK) {
switch (rtlsdr_get_tuner_type(dev)) {
case RTLSDR_TUNER_E4000:
e4k_benchmark();
break;
case RTLSDR_TUNER_R820T:
r820t_benchmark();
break;
default:
fprintf(stderr, "No testable tuner found, aborting.\n");
}
tuner_benchmark();
goto exit;
}