Skip to content
This repository has been archived by the owner on Jan 27, 2021. It is now read-only.

Commit

Permalink
direct sampling mode switching depending on center_frequency
Browse files Browse the repository at this point in the history
added API function rtlsdr_set_ds_mode(dev, enum rtlsdr_ds_mode, freq_threshold)
added CLI option '-D' to rtl_(fm|power|tcp) for mode and threshold frequency

Signed-off-by: hayati ayguen <[email protected]>
  • Loading branch information
hayguen committed Aug 31, 2016
1 parent e14cb99 commit ddb009c
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 4 deletions.
19 changes: 19 additions & 0 deletions include/rtl-sdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,25 @@ RTLSDR_API int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on);
*/
RTLSDR_API int rtlsdr_get_direct_sampling(rtlsdr_dev_t *dev);

enum rtlsdr_ds_mode {
RTLSDR_DS_IQ = 0, /* I/Q quadrature sampling of tuner output */
RTLSDR_DS_I, /* 1: direct sampling on I branch: usually not connected */
RTLSDR_DS_Q, /* 2: direct sampling on Q branch: HF on rtl-sdr v3 dongle */
RTLSDR_DS_I_BELOW, /* 3: direct sampling on I branch when frequency below 'DS threshold frequency' */
RTLSDR_DS_Q_BELOW /* 4: direct sampling on Q branch when frequency below 'DS threshold frequency' */
};

/*!
* Set direct sampling mode with threshold
*
* \param dev the device handle given by rtlsdr_open()
* \param mode static modes 0 .. 2 as in rtlsdr_set_direct_sampling(). other modes do automatic switching
* \param freq_threshold direct sampling is used below this frequency, else quadrature mode through tuner
* set 0 for using default setting per tuner - not fully implemented yet!
* \return negative on error, 0 on success
*/
RTLSDR_API int rtlsdr_set_ds_mode(rtlsdr_dev_t *dev, enum rtlsdr_ds_mode mode, uint32_t freq_threshold);

/*!
* Enable or disable offset tuning for zero-IF tuners, which allows to avoid
* problems caused by the DC offset of the ADCs and 1/f noise.
Expand Down
59 changes: 59 additions & 0 deletions src/librtlsdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ struct rtlsdr_dev {
uint32_t offs_freq; /* Hz */
int corr; /* ppm */
int gain; /* tenth dB */
enum rtlsdr_ds_mode direct_sampling_mode;
uint32_t direct_sampling_threshold; /* Hz */
struct e4k_state e4k_s;
struct r82xx_config r82xx_c;
struct r82xx_priv r82xx_p;
Expand All @@ -131,6 +133,7 @@ struct rtlsdr_dev {

void rtlsdr_set_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int val);
static int rtlsdr_set_if_freq(rtlsdr_dev_t *dev, uint32_t freq);
static int rtlsdr_update_ds(rtlsdr_dev_t *dev, uint32_t freq);

/* generic tuner interface functions, shall be moved to the tuner implementations */
int e4000_init(void *dev) {
Expand Down Expand Up @@ -996,6 +999,9 @@ int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq)
if (!dev || !dev->tuner)
return -1;

if (dev->direct_sampling_mode > RTLSDR_DS_Q)
rtlsdr_update_ds(dev, freq);

if (dev->direct_sampling) {
r = rtlsdr_set_if_freq(dev, freq);
} else if (dev->tuner && dev->tuner->set_freq) {
Expand Down Expand Up @@ -1485,6 +1491,59 @@ int rtlsdr_get_direct_sampling(rtlsdr_dev_t *dev)
return dev->direct_sampling;
}

int rtlsdr_set_ds_mode(rtlsdr_dev_t *dev, enum rtlsdr_ds_mode mode, uint32_t freq_threshold)
{
if (!dev)
return -1;

uint32_t center_freq = rtlsdr_get_center_freq(dev);
if ( !center_freq )
return -2;

if (!freq_threshold) {
switch(dev->tuner_type) {
default:
case RTLSDR_TUNER_UNKNOWN: freq_threshold = 28800000; break; /* no idea!!! */
case RTLSDR_TUNER_E4000: freq_threshold = 50*1000000; break; /* E4K_FLO_MIN_MHZ */
case RTLSDR_TUNER_FC0012: freq_threshold = 28800000; break; /* no idea!!! */
case RTLSDR_TUNER_FC0013: freq_threshold = 28800000; break; /* no idea!!! */
case RTLSDR_TUNER_FC2580: freq_threshold = 28800000; break; /* no idea!!! */
case RTLSDR_TUNER_R820T: freq_threshold = 24000000; break; /* ~ */
case RTLSDR_TUNER_R828D: freq_threshold = 28800000; break; /* no idea!!! */
}
}

dev->direct_sampling_mode = mode;
dev->direct_sampling_threshold = freq_threshold;

if (mode <= RTLSDR_DS_Q)
rtlsdr_set_direct_sampling(dev, mode);

return rtlsdr_set_center_freq(dev, center_freq);
}

static int rtlsdr_update_ds(rtlsdr_dev_t *dev, uint32_t freq)
{
int curr_ds = rtlsdr_get_direct_sampling(dev);
if ( curr_ds < 0 )
return -1;

int new_ds = 0;
switch (dev->direct_sampling_mode) {
default:
case RTLSDR_DS_IQ: break;
case RTLSDR_DS_I: new_ds = 1; break;
case RTLSDR_DS_Q: new_ds = 2; break;
case RTLSDR_DS_I_BELOW: new_ds = (freq < dev->direct_sampling_threshold) ? 1 : 0; break;
case RTLSDR_DS_Q_BELOW: new_ds = (freq < dev->direct_sampling_threshold) ? 2 : 0; break;
}

if ( curr_ds != new_ds )
return rtlsdr_set_direct_sampling(dev, new_ds);

return 0;
}

int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on)
{
int r = 0;
Expand Down
16 changes: 15 additions & 1 deletion src/rtl_fm.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ void usage(void)
"\t[-s sample_rate (default: 24k)]\n"
"\t[-d device_index (default: 0)]\n"
"\t[-T enable bias-T on GPIO PIN 0 (works for rtl-sdr.com v3 dongles)]\n"
"\t[-D direct_sampling_mode (default: 0, 1 = I, 2 = Q, 3 = I below threshold, 4 = Q below threshold)]\n"
"\t[-D direct_sampling_threshold_frequency (default: 0 use tuner specific frequency threshold for 3 and 4)]\n"
"\t[-g tuner_gain (default: automatic)]\n"
"\t[-w tuner_bandwidth (default: automatic. enables offset tuning)]\n"
"\t[-l squelch_level (default: 0/off)]\n"
Expand Down Expand Up @@ -1166,14 +1168,16 @@ int main(int argc, char **argv)
int dev_given = 0;
int custom_ppm = 0;
int enable_biastee = 0;
enum rtlsdr_ds_mode ds_mode = RTLSDR_DS_IQ;
uint32_t ds_temp, ds_threshold = 0;
int timeConstant = 75; /* default: U.S. 75 uS */
int rtlagc = 0;
dongle_init(&dongle);
demod_init(&demod);
output_init(&output);
controller_init(&controller);

while ((opt = getopt(argc, argv, "d:f:g:s:b:l:L:o:t:r:p:E:q:F:A:M:c:h:w:Tv")) != -1) {
while ((opt = getopt(argc, argv, "d:f:g:s:b:l:L:o:t:r:p:E:q:F:A:M:c:h:w:D:Tv")) != -1) {
switch (opt) {
case 'd':
dongle.dev_index = verbose_device_search(optarg);
Expand Down Expand Up @@ -1289,6 +1293,13 @@ int main(int argc, char **argv)
case 'T':
enable_biastee = 1;
break;
case 'D':
ds_temp = (uint32_t)( atofs(optarg) + 0.5 );
if (ds_temp <= RTLSDR_DS_Q_BELOW)
ds_mode = (enum rtlsdr_ds_mode)ds_temp;
else
ds_threshold = ds_temp;
break;
case 'v':
++verbosity;
break;
Expand Down Expand Up @@ -1375,6 +1386,9 @@ int main(int argc, char **argv)

verbose_ppm_set(dongle.dev, dongle.ppm_error);

/* Set direct sampling with threshold */
rtlsdr_set_ds_mode(dongle.dev, ds_mode, ds_threshold);

verbose_set_bandwidth(dongle.dev, dongle.bandwidth);

if (verbosity && dongle.bandwidth)
Expand Down
19 changes: 17 additions & 2 deletions src/rtl_power.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ void usage(void)
"\t[-g tuner_gain (default: automatic)]\n"
"\t[-p ppm_error (default: 0)]\n"
"\t[-T enable bias-T on GPIO PIN 0 (works for rtl-sdr.com v3 dongles)]\n"
"\t[-D direct_sampling_mode (default: 0, 1 = I, 2 = Q, 3 = I below threshold, 4 = Q below threshold)]\n"
"\t[-D direct_sampling_threshold_frequency (default: 0 use tuner specific frequency threshold for 3 and 4)]\n"
"\tfilename (a '-' dumps samples to stdout)\n"
"\t (omitting the filename also uses stdout)\n"
"\n"
Expand Down Expand Up @@ -776,6 +778,8 @@ int main(int argc, char **argv)
int direct_sampling = 0;
int offset_tuning = 0;
int enable_biastee = 0;
enum rtlsdr_ds_mode ds_mode = RTLSDR_DS_IQ;
uint32_t ds_temp, ds_threshold = 0;
double crop = 0.0;
char *freq_optarg;
time_t next_tick;
Expand All @@ -786,7 +790,7 @@ int main(int argc, char **argv)
double (*window_fn)(int, int) = rectangle;
freq_optarg = "";

while ((opt = getopt(argc, argv, "f:i:s:t:d:g:p:e:w:c:F:1PDOTh")) != -1) {
while ((opt = getopt(argc, argv, "f:i:s:t:d:g:p:e:w:c:F:D:1POTh")) != -1) {
switch (opt) {
case 'f': // lower:upper:bin_size
freq_optarg = strdup(optarg);
Expand Down Expand Up @@ -845,7 +849,15 @@ int main(int argc, char **argv)
peak_hold = 1;
break;
case 'D':
direct_sampling = 1;
if(!optarg) {
direct_sampling = 1;
} else {
ds_temp = (uint32_t)( atofs(optarg) + 0.5 );
if (ds_temp <= RTLSDR_DS_Q_BELOW)
ds_mode = (enum rtlsdr_ds_mode)ds_temp;
else
ds_threshold = ds_temp;
}
break;
case 'O':
offset_tuning = 1;
Expand Down Expand Up @@ -919,6 +931,9 @@ int main(int argc, char **argv)
verbose_direct_sampling(dev, 1);
}

/* Set direct sampling with threshold */
rtlsdr_set_ds_mode(dev, ds_mode, ds_threshold);

if (offset_tuning) {
verbose_offset_tuning(dev);
}
Expand Down
16 changes: 15 additions & 1 deletion src/rtl_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ void usage(void)
"\t[-d device index (default: 0)]\n"
"\t[-P ppm_error (default: 0)]\n"
"\t[-T enable bias-T on GPIO PIN 0 (works for rtl-sdr.com v3 dongles)]\n"
"\t[-D direct_sampling_mode (default: 0, 1 = I, 2 = Q, 3 = I below threshold, 4 = Q below threshold)]\n"
"\t[-D direct_sampling_threshold_frequency (default: 0 use tuner specific frequency threshold for 3 and 4)]\n"
"\t[-v increase verbosity (default: 0)]\n");
exit(1);
}
Expand Down Expand Up @@ -470,6 +472,8 @@ int main(int argc, char **argv)
int wait_ir = 10000;
pthread_t thread_ir;
uint32_t frequency = 100000000, samp_rate = 2048000;
enum rtlsdr_ds_mode ds_mode = RTLSDR_DS_IQ;
uint32_t ds_temp, ds_threshold = 0;
struct sockaddr_in local, remote;
uint32_t buf_num = 0;
/* buf_len:
Expand Down Expand Up @@ -506,7 +510,7 @@ int main(int argc, char **argv)
struct sigaction sigact, sigign;
#endif

while ((opt = getopt(argc, argv, "a:p:I:W:f:g:s:b:l:n:d:P:w:vT")) != -1) {
while ((opt = getopt(argc, argv, "a:p:I:W:f:g:s:b:l:n:d:P:w:D:vT")) != -1) {
switch (opt) {
case 'd':
dev_index = verbose_device_search(optarg);
Expand Down Expand Up @@ -554,6 +558,13 @@ int main(int argc, char **argv)
case 'T':
enable_biastee = 1;
break;
case 'D':
ds_temp = (uint32_t)( atofs(optarg) + 0.5 );
if (ds_temp <= RTLSDR_DS_Q_BELOW)
ds_mode = (enum rtlsdr_ds_mode)ds_temp;
else
ds_threshold = ds_temp;
break;
default:
usage();
break;
Expand Down Expand Up @@ -601,6 +612,9 @@ int main(int argc, char **argv)
if (r < 0)
fprintf(stderr, "WARNING: Failed to set sample rate.\n");

/* Set direct sampling with threshold */
rtlsdr_set_ds_mode(dev, ds_mode, ds_threshold);

/* Set the frequency */
r = rtlsdr_set_center_freq(dev, frequency);
if (r < 0)
Expand Down

0 comments on commit ddb009c

Please sign in to comment.