aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2017-12-04 14:12:11 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2017-12-09 20:46:14 +0100
commit9f901384deda96a7dd021923841885ec1e4f2d67 (patch)
treea6bd7a6c611796369f0c1a7f9ddfd7bfe90da08a
parentc49ee3b2a8c545ce6582b414b55ed9f610bd4b94 (diff)
SDR: Add option to set local oscillator (LO) offset
By default it is set to -1 MHz.
-rw-r--r--docs/sdr.html10
-rw-r--r--src/libmobile/main_mobile.c4
-rw-r--r--src/libsdr/sdr.c6
-rw-r--r--src/libsdr/sdr_config.c26
-rw-r--r--src/libsdr/sdr_config.h3
-rw-r--r--src/libsdr/soapy.c9
-rw-r--r--src/libsdr/soapy.h2
-rw-r--r--src/libsdr/uhd.c22
-rw-r--r--src/libsdr/uhd.h2
-rw-r--r--src/tv/main.c4
10 files changed, 58 insertions, 30 deletions
diff --git a/docs/sdr.html b/docs/sdr.html
index 03bf8e1..687a10e 100644
--- a/docs/sdr.html
+++ b/docs/sdr.html
@@ -77,9 +77,7 @@ In case of B-Netz, I use the following parameters:
# bnetz --sdr-soapy \
--sdr-tx-gain 50 \
--sdr-rx-gain 30 \
- --sdr-bandwidth 5000000 \
--sdr-samplerate 5000000 \
- --sdr-tune-args "OFFSET=1000000" \
-s 100000 \
-k 17
@@ -89,10 +87,10 @@ In case of B-Netz, I use the following parameters:
In order to change from analog sound card to SDR, you need <b>--sdr-soapy</b> option.
In my setup I use antennas directly connected to the SDR.
Being about 1-10 meters away, I use the <b>gain</b> as defined above.
-The IF filter requires a minimum <b>bandwidth</b> of 5 MHz.
The <b>sample rate</b> must be 5 MHz minimum.
+The default <b>bandwidth</b> follows the sample rate, if not specified using <b>--sdr-bandwidth</b>.
Higher sample rate causes more CPU, RAM and USB load.
-The local oscillator frequency causes the transmitted signal to be noisy, so I shift it 1 MHz away, using an <b>offset</b>.
+The local oscillator frequency causes the transmitted signal to be noisy, so I shift it 1 MHz away, using the default <b>--sdr-lo-offset</b>.
The audio processing rate of 100 KHz (<b>-s 100000</b>) is used to generate two channels: <b>17</b> and 19.
Note that channel 19 is not given here, but will be used automatically.
With B-Netz, the transmitter switches from any voice channel to the paging channel (19) whenever the phone gets paged.
@@ -174,9 +172,7 @@ Because C-Netz uses only odd channel numbers for 10 KHz spacing, we use channel
# cnetz --sdr-soapy \
--sdr-rx-gain 50 \
--sdr-tx-gain 30 \
- --sdr-bandwidth 5000000 \
--sdr-samplerate 5000000 \
- --sdr-tune-args "OFFSET=1000000" \
-s 100000 \
-k 131 -k 135 \
-C 0,0
@@ -192,7 +188,7 @@ Give PAL 'FUBK' test image on TV channel 21.
# osmotv --sdr-soapy \
--sdr-tx-gain 60 \
- --sdr-tune-args "OFFSET=-3000000" \
+ --sdr-bandwidth 60000000 \
-r 13750000 \
-c 21 \
tx-fubk
diff --git a/src/libmobile/main_mobile.c b/src/libmobile/main_mobile.c
index 0654ae9..a66e038 100644
--- a/src/libmobile/main_mobile.c
+++ b/src/libmobile/main_mobile.c
@@ -43,6 +43,8 @@
#include "../libsdr/sdr_config.h"
#endif
+#define DEFAULT_LO_OFFSET -1000000.0
+
static int got_init = 0;
/* common mobile settings */
@@ -77,7 +79,7 @@ void main_mobile_init(void)
{
got_init = 1;
#ifdef HAVE_SDR
- sdr_config_init();
+ sdr_config_init(DEFAULT_LO_OFFSET);
#endif
}
diff --git a/src/libsdr/sdr.c b/src/libsdr/sdr.c
index 9a33697..1333a6a 100644
--- a/src/libsdr/sdr.c
+++ b/src/libsdr/sdr.c
@@ -368,9 +368,11 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
display_iq_init(samplerate);
display_spectrum_init(samplerate, rx_center_frequency);
+ PDEBUG(DSDR, DEBUG_INFO, "Using local oscillator offseet: %.0f Hz\n", sdr_config->lo_offset);
+
#ifdef HAVE_UHD
if (sdr_config->uhd) {
- rc = uhd_open(sdr_config->channel, sdr_config->device_args, sdr_config->stream_args, sdr_config->tune_args, sdr_config->tx_antenna, sdr_config->rx_antenna, tx_center_frequency, rx_center_frequency, sdr_config->samplerate, sdr_config->tx_gain, sdr_config->rx_gain, sdr_config->bandwidth, sdr_config->uhd_tx_timestamps);
+ rc = uhd_open(sdr_config->channel, sdr_config->device_args, sdr_config->stream_args, sdr_config->tune_args, sdr_config->tx_antenna, sdr_config->rx_antenna, tx_center_frequency, rx_center_frequency, sdr_config->lo_offset, sdr_config->samplerate, sdr_config->tx_gain, sdr_config->rx_gain, sdr_config->bandwidth, sdr_config->uhd_tx_timestamps);
if (rc)
goto error;
}
@@ -378,7 +380,7 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
#ifdef HAVE_SOAPY
if (sdr_config->soapy) {
- rc = soapy_open(sdr_config->channel, sdr_config->device_args, sdr_config->stream_args, sdr_config->tune_args, sdr_config->tx_antenna, sdr_config->rx_antenna, tx_center_frequency, rx_center_frequency, sdr_config->samplerate, sdr_config->tx_gain, sdr_config->rx_gain, sdr_config->bandwidth);
+ rc = soapy_open(sdr_config->channel, sdr_config->device_args, sdr_config->stream_args, sdr_config->tune_args, sdr_config->tx_antenna, sdr_config->rx_antenna, tx_center_frequency, rx_center_frequency, sdr_config->lo_offset, sdr_config->samplerate, sdr_config->tx_gain, sdr_config->rx_gain, sdr_config->bandwidth);
if (rc)
goto error;
}
diff --git a/src/libsdr/sdr_config.c b/src/libsdr/sdr_config.c
index 1c2297b..8fbb87c 100644
--- a/src/libsdr/sdr_config.c
+++ b/src/libsdr/sdr_config.c
@@ -32,13 +32,14 @@ static int got_init = 0;
extern int use_sdr;
sdr_config_t *sdr_config = NULL;
-void sdr_config_init(void)
+void sdr_config_init(double lo_offset)
{
sdr_config = calloc(1, sizeof(*sdr_config));
memset(sdr_config, 0, sizeof(*sdr_config));
sdr_config->device_args = "";
sdr_config->stream_args = "";
sdr_config->tune_args = "";
+ sdr_config->lo_offset = lo_offset;
got_init = 1;
}
@@ -65,6 +66,9 @@ void sdr_config_print_help(void)
printf(" --sdr-samplerate <samplerate>\n");
printf(" Sample rate to use with SDR. By default it equals the regular sample\n");
printf(" rate.\n");
+ printf(" --sdr-lo-offset <Hz>\n");
+ printf(" Give frequency offset in Hz to move the local oscillator away from the\n");
+ printf(" target frequency. (default = %.0f)\n", sdr_config->lo_offset);
printf(" --sdr-bandwidth <bandwidth>\n");
printf(" Give IF filter bandwidth to use. If not, sample rate is used.\n");
printf(" --sdr-rx-antenna <name>\n");
@@ -109,13 +113,14 @@ void sdr_config_print_hotkeys(void)
#define OPT_SDR_RX_GAIN 1508
#define OPT_SDR_TX_GAIN 1509
#define OPT_SDR_SAMPLERATE 1510
-#define OPT_SDR_BANDWIDTH 1511
-#define OPT_WRITE_IQ_RX_WAVE 1512
-#define OPT_WRITE_IQ_TX_WAVE 1513
-#define OPT_READ_IQ_RX_WAVE 1514
-#define OPT_READ_IQ_TX_WAVE 1515
-#define OPT_SDR_SWAP_LINKS 1516
-#define OPT_SDR_UHD_TX_TS 1517
+#define OPT_SDR_LO_OFFSET 1511
+#define OPT_SDR_BANDWIDTH 1512
+#define OPT_WRITE_IQ_RX_WAVE 1513
+#define OPT_WRITE_IQ_TX_WAVE 1514
+#define OPT_READ_IQ_RX_WAVE 1515
+#define OPT_READ_IQ_TX_WAVE 1516
+#define OPT_SDR_SWAP_LINKS 1517
+#define OPT_SDR_UHD_TX_TS 1518
struct option sdr_config_long_options[] = {
{"sdr-uhd", 0, 0, OPT_SDR_UHD},
@@ -125,6 +130,7 @@ struct option sdr_config_long_options[] = {
{"sdr-stream-args", 1, 0, OPT_SDR_STREAM_ARGS},
{"sdr-tune-args", 1, 0, OPT_SDR_TUNE_ARGS},
{"sdr-samplerate", 1, 0, OPT_SDR_SAMPLERATE},
+ {"sdr-lo-offset", 1, 0, OPT_SDR_LO_OFFSET},
{"sdr-bandwidth", 1, 0, OPT_SDR_BANDWIDTH},
{"sdr-rx-antenna", 1, 0, OPT_SDR_RX_ANTENNA},
{"sdr-tx-antenna", 1, 0, OPT_SDR_TX_ANTENNA},
@@ -184,6 +190,10 @@ int sdr_config_opt_switch(int c, int *skip_args)
sdr_config->samplerate = atoi(optarg);
*skip_args += 2;
break;
+ case OPT_SDR_LO_OFFSET:
+ sdr_config->lo_offset = atof(optarg);
+ *skip_args += 2;
+ break;
case OPT_SDR_BANDWIDTH:
sdr_config->bandwidth = atof(optarg);
*skip_args += 2;
diff --git a/src/libsdr/sdr_config.h b/src/libsdr/sdr_config.h
index b64424d..9bfba1f 100644
--- a/src/libsdr/sdr_config.h
+++ b/src/libsdr/sdr_config.h
@@ -7,6 +7,7 @@ typedef struct sdr_config {
*stream_args,
*tune_args;
int samplerate; /* ADC/DAC sample rate */
+ double lo_offset; /* LO frequency offset */
double bandwidth; /* IF bandwidth */
double tx_gain, /* gain */
rx_gain;
@@ -22,7 +23,7 @@ typedef struct sdr_config {
extern sdr_config_t *sdr_config;
-void sdr_config_init(void);
+void sdr_config_init(double lo_offset);
void sdr_config_print_help(void);
void sdr_config_print_hotkeys(void);
extern struct option sdr_config_long_options[];
diff --git a/src/libsdr/soapy.c b/src/libsdr/soapy.c
index 13797d1..ba330be 100644
--- a/src/libsdr/soapy.c
+++ b/src/libsdr/soapy.c
@@ -62,7 +62,7 @@ static int parse_args(SoapySDRKwargs *args, const char *_args_string)
return 0;
}
-int soapy_open(size_t channel, const char *_device_args, const char *_stream_args, const char *_tune_args, const char *tx_antenna, const char *rx_antenna, double tx_frequency, double rx_frequency, double rate, double tx_gain, double rx_gain, double bandwidth)
+int soapy_open(size_t channel, const char *_device_args, const char *_stream_args, const char *_tune_args, const char *tx_antenna, const char *rx_antenna, double tx_frequency, double rx_frequency, double lo_offset, double rate, double tx_gain, double rx_gain, double bandwidth)
{
double got_frequency, got_rate, got_gain, got_bandwidth;
const char *got_antenna;
@@ -88,6 +88,13 @@ int soapy_open(size_t channel, const char *_device_args, const char *_stream_arg
if (rc < 0)
return rc;
+ if (lo_offset) {
+ char val[32];
+ snprintf(val, sizeof(val), "%.0f", lo_offset);
+ val[sizeof(val) - 1] = '\0';
+ SoapySDRKwargs_set(&tune_args, "OFFSET", val);
+ }
+
/* create SoapySDR device */
sdr = SoapySDRDevice_make(&device_args);
if (!sdr) {
diff --git a/src/libsdr/soapy.h b/src/libsdr/soapy.h
index 702890b..755d0ca 100644
--- a/src/libsdr/soapy.h
+++ b/src/libsdr/soapy.h
@@ -1,5 +1,5 @@
-int soapy_open(size_t channel, const char *_device_args, const char *_stream_args, const char *_tune_args, const char *tx_antenna, const char *rx_antenna, double tx_frequency, double rx_frequency, double rate, double tx_gain, double rx_gain, double bandwidth);
+int soapy_open(size_t channel, const char *_device_args, const char *_stream_args, const char *_tune_args, const char *tx_antenna, const char *rx_antenna, double tx_frequency, double rx_frequency, double lo_offset, double rate, double tx_gain, double rx_gain, double bandwidth);
int soapy_start(void);
void soapy_close(void);
int soapy_send(float *buff, int num);
diff --git a/src/libsdr/uhd.c b/src/libsdr/uhd.c
index 3f29cd0..624146f 100644
--- a/src/libsdr/uhd.c
+++ b/src/libsdr/uhd.c
@@ -49,7 +49,7 @@ static time_t tx_time_secs = 0;
static double tx_time_fract_sec = 0.0;
static int tx_timestamps;
-int uhd_open(size_t channel, const char *_device_args, const char *_stream_args, const char *_tune_args, const char *tx_antenna, const char *rx_antenna, double tx_frequency, double rx_frequency, double rate, double tx_gain, double rx_gain, double bandwidth, int _tx_timestamps)
+int uhd_open(size_t channel, const char *_device_args, const char *_stream_args, const char *_tune_args, const char *tx_antenna, const char *rx_antenna, double tx_frequency, double rx_frequency, double lo_offset, double rate, double tx_gain, double rx_gain, double bandwidth, int _tx_timestamps)
{
uhd_error error;
double got_frequency, got_rate, got_gain, got_bandwidth;
@@ -153,7 +153,7 @@ int uhd_open(size_t channel, const char *_device_args, const char *_stream_args,
uhd_close();
return -EIO;
}
- if (fabs(got_rate - rate) > 0.001) {
+ if (fabs(got_rate - rate) > 1.0) {
PDEBUG(DUHD, DEBUG_ERROR, "Given TX rate %.0f Hz is not supported, try %.0f Hz\n", rate, got_rate);
uhd_close();
return -EINVAL;
@@ -182,7 +182,11 @@ int uhd_open(size_t channel, const char *_device_args, const char *_stream_args,
/* set frequency */
memset(&tune_request, 0, sizeof(tune_request));
tune_request.target_freq = tx_frequency;
- tune_request.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO;
+ if (lo_offset) {
+ tune_request.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_MANUAL;
+ tune_request.rf_freq = tx_frequency + lo_offset;
+ } else
+ tune_request.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO;
tune_request.dsp_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO;
tune_request.args = strdup(_tune_args);
error = uhd_usrp_set_tx_freq(usrp, &tune_request, channel, &tune_result);
@@ -219,7 +223,7 @@ int uhd_open(size_t channel, const char *_device_args, const char *_stream_args,
uhd_close();
return -EIO;
}
- if (fabs(got_bandwidth - bandwidth) > 0.001) {
+ if (fabs(got_bandwidth - bandwidth) > 100.0) {
PDEBUG(DUHD, DEBUG_ERROR, "Given TX bandwidth %.0f Hz is not supported, try %.0f Hz\n", bandwidth, got_bandwidth);
uhd_close();
return -EINVAL;
@@ -337,7 +341,7 @@ int uhd_open(size_t channel, const char *_device_args, const char *_stream_args,
uhd_close();
return -EIO;
}
- if (fabs(got_rate - rate) > 0.001) {
+ if (fabs(got_rate - rate) > 1.0) {
PDEBUG(DUHD, DEBUG_ERROR, "Given RX rate %.0f Hz is not supported, try %.0f Hz\n", rate, got_rate);
uhd_close();
return -EINVAL;
@@ -366,7 +370,11 @@ int uhd_open(size_t channel, const char *_device_args, const char *_stream_args,
/* set frequency */
memset(&tune_request, 0, sizeof(tune_request));
tune_request.target_freq = rx_frequency;
- tune_request.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO;
+ if (lo_offset) {
+ tune_request.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_MANUAL;
+ tune_request.rf_freq = rx_frequency + lo_offset;
+ } else
+ tune_request.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO;
tune_request.dsp_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO;
tune_request.args = strdup(_tune_args);
error = uhd_usrp_set_rx_freq(usrp, &tune_request, channel, &tune_result);
@@ -403,7 +411,7 @@ int uhd_open(size_t channel, const char *_device_args, const char *_stream_args,
uhd_close();
return -EIO;
}
- if (fabs(got_bandwidth - bandwidth) > 0.001) {
+ if (fabs(got_bandwidth - bandwidth) > 100.0) {
PDEBUG(DUHD, DEBUG_ERROR, "Given RX bandwidth %.0f Hz is not supported, try %.0f Hz\n", bandwidth, got_bandwidth);
uhd_close();
return -EINVAL;
diff --git a/src/libsdr/uhd.h b/src/libsdr/uhd.h
index 60eb94f..36ce1ba 100644
--- a/src/libsdr/uhd.h
+++ b/src/libsdr/uhd.h
@@ -1,5 +1,5 @@
-int uhd_open(size_t channel, const char *_device_args, const char *_stream_args, const char *_tune_args, const char *tx_antenna, const char *rx_antenna, double tx_frequency, double rx_frequency, double rate, double tx_gain, double rx_gain, double bandwidth, int _tx_timestamps);
+int uhd_open(size_t channel, const char *_device_args, const char *_stream_args, const char *_tune_args, const char *tx_antenna, const char *rx_antenna, double tx_frequency, double rx_frequency, double lo_offset, double rate, double tx_gain, double rx_gain, double bandwidth, int _tx_timestamps);
int uhd_start(void);
void uhd_close(void);
int uhd_send(float *buff, int num);
diff --git a/src/tv/main.c b/src/tv/main.c
index 3423ae3..1a1d0be 100644
--- a/src/tv/main.c
+++ b/src/tv/main.c
@@ -41,6 +41,8 @@ enum paging_signal;
#include "tv_modulate.h"
#include "channels.h"
+#define DEFAULT_LO_OFFSET -3000000.0
+
void *sender_head = NULL;
int use_sdr = 0;
int num_kanal = 1; /* only one channel used for debugging */
@@ -454,7 +456,7 @@ int main(int argc, char *argv[])
debuglevel = 0;
#ifdef HAVE_SDR
- sdr_config_init();
+ sdr_config_init(DEFAULT_LO_OFFSET);
#endif
skip_args = handle_options(argc, argv);