osmocom-analog/src/libsdr/sdr_config.c

261 lines
8.2 KiB
C
Raw Normal View History

/* Config for SDR
*
* (C) 2017 by Andreas Eversberg <jolly@eversberg.eu>
* All Rights Reserved
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
enum paging_signal;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include "../libsample/sample.h"
#include "../liboptions/options.h"
#include "sdr.h"
#include "sdr_config.h"
static int got_init = 0;
extern int use_sdr;
sdr_config_t *sdr_config = NULL;
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;
}
void sdr_config_print_help(void)
{
printf("\nSDR options:\n");
/* - - */
#ifdef HAVE_UHD
printf(" --sdr-uhd\n");
printf(" Force UHD driver\n");
#endif
#ifdef HAVE_SOAPY
printf(" --sdr-soapy\n");
printf(" Force SoapySDR driver\n");
#endif
printf(" --sdr-channel <channel #>\n");
printf(" Give channel number for multi channel SDR device (default = %d)\n", sdr_config->channel);
printf(" --sdr-device-args <args>\n");
printf(" --sdr-stream-args <args>\n");
printf(" --sdr-tune-args <args>\n");
printf(" Optional SDR device arguments, separated by comma\n");
printf(" e.g. --sdr-device-args <key>=<value>[,<key>=<value>[,...]]\n");
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");
printf(" SDR device's RX antenna name, use 'list' to get a list\n");
printf(" --sdr-tx-antenna <name>\n");
printf(" SDR device's TX antenna name, use 'list' to get a list\n");
printf(" --sdr-clock-source <name>\n");
printf(" SDR device's clock sourc name, use 'list' to get a list\n");
printf(" --sdr-rx-gain <gain>\n");
printf(" SDR device's RX gain in dB (default = %.1f)\n", sdr_config->rx_gain);
printf(" --sdr-tx-gain <gain>\n");
printf(" SDR device's TX gain in dB (default = %.1f)\n", sdr_config->tx_gain);
printf(" --write-iq-rx-wave <file>\n");
printf(" Write received IQ data to given wave file.\n");
printf(" --write-iq-tx-wave <file>\n");
printf(" Write transmitted IQ data to given wave file.\n");
printf(" --read-iq-rx-wave <file>\n");
printf(" Replace received IQ data by given wave file.\n");
printf(" --read-iq-tx-wave <file>\n");
printf(" Replace transmitted IQ data by given wave file.\n");
printf(" --sdr-swap-links\n");
printf(" Swap RX and TX frequencies for loopback tests over the air.\n");
#ifdef HAVE_UHD
printf(" --sdr-uhd-tx-timestamps\n");
printf(" Use TX timestamps on UHD device. (May not work with some devices!)\n");
#endif
}
void sdr_config_print_hotkeys(void)
{
2017-10-03 08:23:04 +00:00
printf("Press 'q' key to toggle display of RX I/Q vector.\n");
printf("Press 's' key to toggle display of RX spectrum.\n");
2017-11-26 07:53:09 +00:00
printf("Press shift + 'B' key to remove DC level.\n");
}
#define OPT_SDR_UHD 1500
#define OPT_SDR_SOAPY 1501
#define OPT_SDR_CHANNEL 1502
#define OPT_SDR_DEVICE_ARGS 1503
#define OPT_SDR_STREAM_ARGS 1504
#define OPT_SDR_TUNE_ARGS 1505
#define OPT_SDR_RX_ANTENNA 1506
#define OPT_SDR_TX_ANTENNA 1507
#define OPT_SDR_CLOCK_SOURCE 1508
#define OPT_SDR_RX_GAIN 1509
#define OPT_SDR_TX_GAIN 1510
#define OPT_SDR_SAMPLERATE 1511
#define OPT_SDR_LO_OFFSET 1512
#define OPT_SDR_BANDWIDTH 1513
#define OPT_WRITE_IQ_RX_WAVE 1514
#define OPT_WRITE_IQ_TX_WAVE 1515
#define OPT_READ_IQ_RX_WAVE 1516
#define OPT_READ_IQ_TX_WAVE 1517
#define OPT_SDR_SWAP_LINKS 1518
#define OPT_SDR_UHD_TX_TS 1519
void sdr_config_add_options(void)
{
option_add(OPT_SDR_UHD, "sdr-uhd", 0);
option_add(OPT_SDR_SOAPY, "sdr-soapy", 0);
option_add(OPT_SDR_CHANNEL, "sdr-channel", 1);
option_add(OPT_SDR_DEVICE_ARGS, "sdr-device-args", 1);
option_add(OPT_SDR_STREAM_ARGS, "sdr-stream-args", 1);
option_add(OPT_SDR_TUNE_ARGS, "sdr-tune-args", 1);
option_add(OPT_SDR_SAMPLERATE, "sdr-samplerate", 1);
option_add(OPT_SDR_LO_OFFSET, "sdr-lo-offset", 1);
option_add(OPT_SDR_BANDWIDTH, "sdr-bandwidth", 1);
option_add(OPT_SDR_RX_ANTENNA, "sdr-rx-antenna", 1);
option_add(OPT_SDR_TX_ANTENNA, "sdr-tx-antenna", 1);
option_add(OPT_SDR_CLOCK_SOURCE, "sdr-clock-source", 1);
option_add(OPT_SDR_RX_GAIN, "sdr-rx-gain", 1);
option_add(OPT_SDR_TX_GAIN, "sdr-tx-gain", 1);
option_add(OPT_WRITE_IQ_RX_WAVE, "write-iq-rx-wave", 1);
option_add(OPT_WRITE_IQ_TX_WAVE, "write-iq-tx-wave", 1);
option_add(OPT_READ_IQ_RX_WAVE, "read-iq-rx-wave", 1);
option_add(OPT_READ_IQ_TX_WAVE, "read-iq-tx-wave", 1);
option_add(OPT_SDR_SWAP_LINKS, "sdr-swap-links", 0);
option_add(OPT_SDR_UHD_TX_TS, "sdr-uhd-tx-timestamps", 0);
}
int sdr_config_handle_options(int short_option, int argi, char **argv)
{
switch (short_option) {
case OPT_SDR_UHD:
#ifdef HAVE_UHD
sdr_config->uhd = 1;
use_sdr = 1;
#else
fprintf(stderr, "UHD SDR support not compiled in!\n");
return -EINVAL;
#endif
break;
case OPT_SDR_SOAPY:
#ifdef HAVE_SOAPY
sdr_config->soapy = 1;
use_sdr = 1;
#else
fprintf(stderr, "SoapySDR support not compiled in!\n");
return -EINVAL;
#endif
break;
case OPT_SDR_CHANNEL:
sdr_config->channel = atoi(argv[argi]);
break;
case OPT_SDR_DEVICE_ARGS:
sdr_config->device_args = strdup(argv[argi]);
break;
case OPT_SDR_STREAM_ARGS:
sdr_config->stream_args = strdup(argv[argi]);
break;
case OPT_SDR_TUNE_ARGS:
sdr_config->tune_args = strdup(argv[argi]);
break;
case OPT_SDR_SAMPLERATE:
sdr_config->samplerate = atoi(argv[argi]);
break;
case OPT_SDR_LO_OFFSET:
sdr_config->lo_offset = atof(argv[argi]);
break;
case OPT_SDR_BANDWIDTH:
sdr_config->bandwidth = atof(argv[argi]);
break;
case OPT_SDR_RX_ANTENNA:
sdr_config->rx_antenna = strdup(argv[argi]);
break;
case OPT_SDR_TX_ANTENNA:
sdr_config->tx_antenna = strdup(argv[argi]);
break;
case OPT_SDR_CLOCK_SOURCE:
sdr_config->clock_source = strdup(argv[argi]);
break;
case OPT_SDR_RX_GAIN:
sdr_config->rx_gain = atof(argv[argi]);
break;
case OPT_SDR_TX_GAIN:
sdr_config->tx_gain = atof(argv[argi]);
break;
case OPT_WRITE_IQ_RX_WAVE:
sdr_config->write_iq_rx_wave = strdup(argv[argi]);
break;
case OPT_WRITE_IQ_TX_WAVE:
sdr_config->write_iq_tx_wave = strdup(argv[argi]);
break;
case OPT_READ_IQ_RX_WAVE:
sdr_config->read_iq_rx_wave = strdup(argv[argi]);
break;
case OPT_READ_IQ_TX_WAVE:
sdr_config->read_iq_tx_wave = strdup(argv[argi]);
break;
case OPT_SDR_SWAP_LINKS:
sdr_config->swap_links = 1;
break;
case OPT_SDR_UHD_TX_TS:
sdr_config->uhd_tx_timestamps = 1;
break;
default:
return -EINVAL;
}
return 1;
}
int sdr_configure(int samplerate)
{
if (!got_init) {
fprintf(stderr, "sdr_config_init was not called, please fix!\n");
abort();
}
/* no sdr selected -> return 0 */
if (!sdr_config->uhd && !sdr_config->soapy)
return 0;
if ((sdr_config->uhd == 1 && sdr_config->soapy == 1)) {
fprintf(stderr, "You must choose which one you want: --sdr-uhd or --sdr-soapy\n");
exit(0);
}
if (sdr_config->samplerate == 0)
sdr_config->samplerate = samplerate;
if (sdr_config->bandwidth == 0.0)
sdr_config->bandwidth = (double)sdr_config->samplerate;
/* sdr selected -> return 1 */
return 1;
}