SDR: Add option to set local oscillator (LO) offset
By default it is set to -1 MHz.
This commit is contained in:
parent
c49ee3b2a8
commit
9f901384de
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue