mirror of https://github.com/drowe67/librtlsdr.git
direct sampling mode switching depending on center_frequency
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 <h_ayguen@web.de>master
parent
34bbae3f11
commit
43c4028b00
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -997,6 +1000,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) {
|
||||
|
@ -1486,6 +1492,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;
|
||||
|
|
16
src/rtl_fm.c
16
src/rtl_fm.c
|
@ -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"
|
||||
|
@ -1166,6 +1168,8 @@ 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);
|
||||
|
@ -1173,7 +1177,7 @@ int main(int argc, char **argv)
|
|||
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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue