diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2017-07-11 20:26:40 +0200 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2017-07-15 12:45:19 +0200 |
commit | fda224c27f84b17ac6b0427534adcbe48be96635 (patch) | |
tree | 063e41d1bbe41b958b5f237de4f1a33456692782 | |
parent | 538b4a42ec0925cbd764ab8733bc1639d4221107 (diff) |
Fixing and improving SDR support (SoapySDR and UHD)
- Soapy SDR now works.
- Channels can be selected.
- Antennas can be listed and selected.
- Device args, tune args, stream args can be specified.
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | src/common/debug.c | 1 | ||||
-rw-r--r-- | src/common/debug.h | 1 | ||||
-rw-r--r-- | src/common/main_common.c | 71 | ||||
-rw-r--r-- | src/common/sdr.c | 19 | ||||
-rw-r--r-- | src/common/sdr.h | 2 | ||||
-rw-r--r-- | src/common/soapy.c | 265 | ||||
-rw-r--r-- | src/common/soapy.h | 2 | ||||
-rw-r--r-- | src/common/uhd.c | 146 | ||||
-rw-r--r-- | src/common/uhd.h | 2 |
10 files changed, 397 insertions, 116 deletions
diff --git a/configure.ac b/configure.ac index 53309a5..10c1d15 100644 --- a/configure.ac +++ b/configure.ac @@ -37,8 +37,8 @@ AS_IF([test "x$with_soapy" != xno], [PKG_CHECK_MODULES(SOAPY, SoapySDR >= 0.6.0, AM_CONDITIONAL(HAVE_UHD, test "x$with_uhd" == "xyes" ) AM_CONDITIONAL(HAVE_SOAPY, test "x$with_soapy" == "xyes" ) AM_CONDITIONAL(HAVE_SDR, test "x$with_sdr" == "xyes" ) -AS_IF([test "x$with_uhd" == "xyes"],[AC_MSG_NOTICE( Compiling with UHD SDR support )], []) -AS_IF([test "x$with_soapy" == "xyes"],[AC_MSG_NOTICE( Compiling with SoapySDR support )], []) +AS_IF([test "x$with_uhd" == "xyes"],[AC_MSG_NOTICE( Compiling with UHD SDR support )], [AC_MSG_NOTICE( UHD SDR not support )]) +AS_IF([test "x$with_soapy" == "xyes"],[AC_MSG_NOTICE( Compiling with SoapySDR support )], [AC_MSG_NOTICE( SoapySDR not support )]) AC_OUTPUT( src/common/Makefile diff --git a/src/common/debug.c b/src/common/debug.c index bea7bb0..b3df3cb 100644 --- a/src/common/debug.c +++ b/src/common/debug.c @@ -58,6 +58,7 @@ struct debug_cat { { "sms", "\033[1;37m" }, { "sdr", "\033[1;31m" }, { "uhd", "\033[1;35m" }, + { "soapy", "\033[1;35m" }, { NULL, NULL } }; diff --git a/src/common/debug.h b/src/common/debug.h index b5b3e2e..b412df2 100644 --- a/src/common/debug.h +++ b/src/common/debug.h @@ -21,6 +21,7 @@ #define DSMS 14 #define DSDR 15 #define DUHD 16 +#define DSOAPY 17 #define PDEBUG(cat, level, fmt, arg...) _printdebug(__FILE__, __FUNCTION__, __LINE__, cat, level, -1, fmt, ## arg) #define PDEBUG_CHAN(cat, level, fmt, arg...) _printdebug(__FILE__, __FUNCTION__, __LINE__, cat, level, CHAN, fmt, ## arg) diff --git a/src/common/main_common.c b/src/common/main_common.c index 20d384f..8955a25 100644 --- a/src/common/main_common.c +++ b/src/common/main_common.c @@ -59,23 +59,24 @@ int send_patterns = 1; int release_on_disconnect = 1; int loopback = 0; int rt_prio = 0; -const char *write_rx_wave = NULL; const char *write_tx_wave = NULL; -const char *read_rx_wave = NULL; +const char *write_rx_wave = NULL; const char *read_tx_wave = NULL; +const char *read_rx_wave = NULL; int use_sdr = 0; int sdr_channel = 0; -static const char *sdr_args = ""; +static const char *sdr_device_args = "", *sdr_stream_args = "", *sdr_tune_args = ""; static double sdr_bandwidth = 0.0; #ifdef HAVE_SDR static int sdr_uhd = 0; static int sdr_soapy = 0; #endif -double sdr_rx_gain = 0, sdr_tx_gain = 0; -const char *write_iq_rx_wave = NULL; +double sdr_tx_gain = 0, sdr_rx_gain = 0; +const char *sdr_tx_antenna = "", *sdr_rx_antenna = ""; const char *write_iq_tx_wave = NULL; -const char *read_iq_rx_wave = NULL; +const char *write_iq_rx_wave = NULL; const char *read_iq_tx_wave = NULL; +const char *read_iq_rx_wave = NULL; void print_help_common(const char *arg0, const char *ext_usage) { printf("Usage: %s -k <kanal/channel> %s[options] [station-id]\n", arg0, ext_usage); @@ -150,11 +151,17 @@ void print_help_common(const char *arg0, const char *ext_usage) #endif printf(" --sdr-channel <channel #>\n"); printf(" Give channel number for multi channel SDR device (default = %d)\n", sdr_channel); - printf(" --sdr-args <args>\n"); + printf(" --sdr-device-args <args>\n"); + printf(" --sdr-stream-args <args>\n"); + printf(" --sdr-tune-args <args>\n"); printf(" Optional SDR device arguments, seperated by comma\n"); - printf(" e.g. --sdr-args <key>=<value>[,<key>=<value>[,...]]\n"); + printf(" e.g. --sdr-device-args <key>=<value>[,<key>=<value>[,...]]\n"); 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-rx-gain <gain>\n"); printf(" SDR device's RX gain in dB (default = %.1f)\n", sdr_rx_gain); printf(" --sdr-tx-gain <gain>\n"); @@ -195,14 +202,18 @@ void print_hotkeys_common(void) #define OPT_SDR_UHD 1100 #define OPT_SDR_SOAPY 1101 #define OPT_SDR_CHANNEL 1102 -#define OPT_SDR_ARGS 1103 -#define OPT_SDR_RX_GAIN 1104 -#define OPT_SDR_TX_GAIN 1105 -#define OPT_SDR_BANDWIDTH 1106 -#define OPT_WRITE_IQ_RX_WAVE 1107 -#define OPT_WRITE_IQ_TX_WAVE 1108 -#define OPT_READ_IQ_RX_WAVE 1109 -#define OPT_READ_IQ_TX_WAVE 1110 +#define OPT_SDR_DEVICE_ARGS 1103 +#define OPT_SDR_STREAM_ARGS 1104 +#define OPT_SDR_TUNE_ARGS 1105 +#define OPT_SDR_RX_ANTENNA 1106 +#define OPT_SDR_TX_ANTENNA 1107 +#define OPT_SDR_RX_GAIN 1108 +#define OPT_SDR_TX_GAIN 1109 +#define OPT_SDR_BANDWIDTH 1110 +#define OPT_WRITE_IQ_RX_WAVE 1111 +#define OPT_WRITE_IQ_TX_WAVE 1112 +#define OPT_READ_IQ_RX_WAVE 1113 +#define OPT_READ_IQ_TX_WAVE 1114 static struct option long_options_common[] = { {"help", 0, 0, 'h'}, @@ -230,8 +241,12 @@ static struct option long_options_common[] = { {"sdr-uhd", 0, 0, OPT_SDR_UHD}, {"sdr-soapy", 0, 0, OPT_SDR_SOAPY}, {"sdr-channel", 1, 0, OPT_SDR_CHANNEL}, - {"sdr-args", 1, 0, OPT_SDR_ARGS}, + {"sdr-device-args", 1, 0, OPT_SDR_DEVICE_ARGS}, + {"sdr-stream-args", 1, 0, OPT_SDR_STREAM_ARGS}, + {"sdr-tune-args", 1, 0, OPT_SDR_TUNE_ARGS}, {"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}, {"sdr-rx-gain", 1, 0, OPT_SDR_RX_GAIN}, {"sdr-tx-gain", 1, 0, OPT_SDR_TX_GAIN}, {"write-iq-rx-wave", 1, 0, OPT_WRITE_IQ_RX_WAVE}, @@ -413,14 +428,30 @@ void opt_switch_common(int c, char *arg0, int *skip_args) sdr_channel = atoi(optarg); *skip_args += 2; break; - case OPT_SDR_ARGS: - sdr_args = strdup(optarg); + case OPT_SDR_DEVICE_ARGS: + sdr_device_args = strdup(optarg); + *skip_args += 2; + break; + case OPT_SDR_STREAM_ARGS: + sdr_stream_args = strdup(optarg); + *skip_args += 2; + break; + case OPT_SDR_TUNE_ARGS: + sdr_tune_args = strdup(optarg); *skip_args += 2; break; case OPT_SDR_BANDWIDTH: sdr_bandwidth = atof(optarg); *skip_args += 2; break; + case OPT_SDR_RX_ANTENNA: + sdr_rx_antenna = strdup(optarg); + *skip_args += 2; + break; + case OPT_SDR_TX_ANTENNA: + sdr_tx_antenna = strdup(optarg); + *skip_args += 2; + break; case OPT_SDR_RX_GAIN: sdr_rx_gain = atof(optarg); *skip_args += 2; @@ -523,7 +554,7 @@ void main_common(int *quit, int latency, int interval, void (*myhandler)(void), if (sdr_bandwidth == 0.0) sdr_bandwidth = samplerate; - rc = sdr_init(sdr_uhd, sdr_soapy, sdr_channel, sdr_args, sdr_rx_gain, sdr_tx_gain, sdr_bandwidth, write_iq_rx_wave, write_iq_tx_wave, read_iq_rx_wave, read_iq_tx_wave); + rc = sdr_init(sdr_uhd, sdr_soapy, sdr_channel, sdr_device_args, sdr_stream_args, sdr_tune_args, sdr_tx_antenna, sdr_rx_antenna, sdr_tx_gain, sdr_rx_gain, sdr_bandwidth, write_iq_tx_wave, write_iq_rx_wave, read_iq_tx_wave, read_iq_rx_wave); if (rc < 0) return; #endif diff --git a/src/common/sdr.c b/src/common/sdr.c index e24c8bd..049e6af 100644 --- a/src/common/sdr.c +++ b/src/common/sdr.c @@ -57,24 +57,29 @@ typedef struct sdr { static int sdr_use_uhd, sdr_use_soapy; static int sdr_channel; -static const char *sdr_device_args; +static const char *sdr_device_args, *sdr_stream_args, *sdr_tune_args; +static const char *sdr_rx_antenna, *sdr_tx_antenna; static double sdr_rx_gain, sdr_tx_gain; const char *sdr_write_iq_rx_wave, *sdr_write_iq_tx_wave, *sdr_read_iq_rx_wave, *sdr_read_iq_tx_wave; static double sdr_bandwidth; -int sdr_init(int sdr_uhd, int sdr_soapy, int channel, const char *device_args, double rx_gain, double tx_gain, double bandwidth, const char *write_iq_rx_wave, const char *write_iq_tx_wave, const char *read_iq_rx_wave, const char *read_iq_tx_wave) +int sdr_init(int sdr_uhd, int sdr_soapy, int channel, const char *device_args, const char *stream_args, const char *tune_args, const char *tx_antenna, const char *rx_antenna, double tx_gain, double rx_gain, double bandwidth, const char *write_iq_tx_wave, const char *write_iq_rx_wave, const char *read_iq_tx_wave, const char *read_iq_rx_wave) { sdr_use_uhd = sdr_uhd; sdr_use_soapy = sdr_soapy; sdr_channel = channel; sdr_device_args = strdup(device_args); - sdr_rx_gain = rx_gain; + sdr_stream_args = strdup(stream_args); + sdr_tune_args = strdup(tune_args); + sdr_tx_antenna = strdup(tx_antenna); + sdr_rx_antenna = strdup(rx_antenna); sdr_tx_gain = tx_gain; + sdr_rx_gain = rx_gain; sdr_bandwidth = bandwidth; - sdr_write_iq_rx_wave = write_iq_rx_wave; sdr_write_iq_tx_wave = write_iq_tx_wave; - sdr_read_iq_rx_wave = read_iq_rx_wave; + sdr_write_iq_rx_wave = write_iq_rx_wave; sdr_read_iq_tx_wave = read_iq_tx_wave; + sdr_read_iq_rx_wave = read_iq_rx_wave; return 0; } @@ -242,7 +247,7 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq #ifdef HAVE_UHD if (sdr_use_uhd) { - rc = uhd_open(sdr_channel, sdr_device_args, tx_center_frequency, rx_center_frequency, sdr->samplerate, sdr_rx_gain, sdr_tx_gain, sdr_bandwidth); + rc = uhd_open(sdr_channel, sdr_device_args, sdr_stream_args, sdr_tune_args, sdr_tx_antenna, sdr_rx_antenna, tx_center_frequency, rx_center_frequency, sdr->samplerate, sdr_tx_gain, sdr_rx_gain, sdr_bandwidth); if (rc) goto error; } @@ -250,7 +255,7 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq #ifdef HAVE_SOAPY if (sdr_use_soapy) { - rc = soapy_open(sdr_channel, sdr_device_args, tx_center_frequency, rx_center_frequency, sdr->samplerate, sdr_rx_gain, sdr_tx_gain, sdr_bandwidth); + rc = soapy_open(sdr_channel, sdr_device_args, sdr_stream_args, sdr_tune_args, sdr_tx_antenna, sdr_rx_antenna, tx_center_frequency, rx_center_frequency, sdr->samplerate, sdr_tx_gain, sdr_rx_gain, sdr_bandwidth); if (rc) goto error; } diff --git a/src/common/sdr.h b/src/common/sdr.h index 5e2aaf4..69c8d19 100644 --- a/src/common/sdr.h +++ b/src/common/sdr.h @@ -1,5 +1,5 @@ -int sdr_init(int sdr_uhd, int sdr_soapy, int channel, const char *device_args, double rx_gain, double tx_gain, double bandwidth, const char *write_iq_rx_wave, const char *write_iq_tx_wave, const char *read_iq_rx_wave, const char *read_iq_tx_wave); +int sdr_init(int sdr_uhd, int sdr_soapy, int channel, const char *device_args, const char *stream_args, const char *tune_args, const char *tx_antenna, const char *rx_antenna, double tx_gain, double rx_gain, double bandwidth, const char *write_iq_tx_wave, const char *write_iq_rx_wave, const char *read_iq_tx_wave, const char *read_iq_rx_wave); int sdr_start(void *inst); void *sdr_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int channels, double paging_frequency, int samplerate, double bandwidth, double sample_deviation); void sdr_close(void *inst); diff --git a/src/common/soapy.c b/src/common/soapy.c index d1b37c0..72a3c4d 100644 --- a/src/common/soapy.c +++ b/src/common/soapy.c @@ -35,101 +35,171 @@ static double samplerate; static uint64_t rx_count = 0; static uint64_t tx_count = 0; -int soapy_open(size_t channel, const char *device_args, double tx_frequency, double rx_frequency, double rate, double rx_gain, double tx_gain, double bandwidth) +static int parse_args(SoapySDRKwargs *args, const char *_args_string) { - double got_frequency, got_rate, got_gain, got_bandwidth; - char *arg_string = strdup(device_args), *key, *val; - SoapySDRKwargs args; - - samplerate = rate; + char *args_string = strdup(_args_string), *key, *val; - /* create SoapySDR device */ - PDEBUG(DUHD, DEBUG_INFO, "Creating SoapySDR with args \"%s\"...\n", arg_string); - memset(&args, 0, sizeof(args)); - while (arg_string && *arg_string) { - key = arg_string; + memset(args, 0, sizeof(*args)); + while (args_string && *args_string) { + key = args_string; val = strchr(key, '='); if (!val) { - PDEBUG(DUHD, DEBUG_ERROR, "Error parsing SDR args: No '=' after key\n"); + PDEBUG(DSOAPY, DEBUG_ERROR, "Error parsing SDR args: No '=' after key\n"); soapy_close(); return -EIO; } *val++ = '\0'; - arg_string = strchr(val, ','); - if (arg_string) - *arg_string++ = '\0'; - SoapySDRKwargs_set(&args, key, val); + args_string = strchr(val, ','); + if (args_string) + *args_string++ = '\0'; + PDEBUG(DSOAPY, DEBUG_DEBUG, "SDR device args: key='%s' value='%s'\n", key, val); + SoapySDRKwargs_set(args, key, val); } - sdr = SoapySDRDevice_make(&args); + + 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) +{ + double got_frequency, got_rate, got_gain, got_bandwidth; + const char *got_antenna; + size_t num_channels; + SoapySDRKwargs device_args; + SoapySDRKwargs stream_args; + SoapySDRKwargs tune_args; + int rc; + + samplerate = rate; + + /* parsing ARGS */ + PDEBUG(DSOAPY, DEBUG_INFO, "Using device args \"%s\"\n", _device_args); + rc = parse_args(&device_args, _device_args); + if (rc < 0) + return rc; + PDEBUG(DSOAPY, DEBUG_INFO, "Using stream args \"%s\"\n", _stream_args); + rc = parse_args(&stream_args, _stream_args); + if (rc < 0) + return rc; + PDEBUG(DSOAPY, DEBUG_INFO, "Using tune args \"%s\"\n", _tune_args); + rc = parse_args(&tune_args, _tune_args); + if (rc < 0) + return rc; + + /* create SoapySDR device */ + sdr = SoapySDRDevice_make(&device_args); if (!sdr) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to create SoapySDR\n"); + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to create SoapySDR\n"); soapy_close(); return -EIO; } if (tx_frequency) { + /* get number of channels and check if requested channel is in range */ + num_channels = SoapySDRDevice_getNumChannels(sdr, SOAPY_SDR_TX); + PDEBUG(DSOAPY, DEBUG_DEBUG, "We have %d TX channel, selecting channel #%d\n", (int)num_channels, (int)channel); + if (channel >= num_channels) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Requested channel #%d (capable of TX) does not exist. Please select channel %d..%d!\n", (int)channel, 0, (int)num_channels - 1); + soapy_close(); + return -EIO; + } + + /* antenna */ + if (tx_antenna && tx_antenna[0]) { + if (!strcasecmp(tx_antenna, "list")) { + char **antennas; + size_t antennas_length; + int i; + antennas = SoapySDRDevice_listAntennas(sdr, SOAPY_SDR_TX, channel, &antennas_length); + if (!antennas) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to request list of TX antennas!\n"); + soapy_close(); + return -EIO; + } + for (i = 0; i < (int)antennas_length; i++) + PDEBUG(DSOAPY, DEBUG_NOTICE, "TX Antenna: '%s'\n", antennas[i]); + got_antenna = SoapySDRDevice_getAntenna(sdr, SOAPY_SDR_TX, channel); + PDEBUG(DSOAPY, DEBUG_NOTICE, "Default TX Antenna: '%s'\n", got_antenna); + soapy_close(); + return 1; + } + + if (SoapySDRDevice_setAntenna(sdr, SOAPY_SDR_TX, channel, tx_antenna) != 0) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to set TX antenna to '%s'\n", tx_antenna); + soapy_close(); + return -EIO; + } + got_antenna = SoapySDRDevice_getAntenna(sdr, SOAPY_SDR_TX, channel); + if (!!strcasecmp(tx_antenna, got_antenna)) { + PDEBUG(DSOAPY, DEBUG_NOTICE, "Given TX antenna '%s' was accepted, but driver claims to use '%s'\n", tx_antenna, got_antenna); + soapy_close(); + return -EINVAL; + } + } + /* set rate */ if (SoapySDRDevice_setSampleRate(sdr, SOAPY_SDR_TX, channel, rate) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX rate to %.0f Hz\n", rate); + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to set TX rate to %.0f Hz\n", rate); soapy_close(); return -EIO; } /* see what rate actually is */ got_rate = SoapySDRDevice_getSampleRate(sdr, SOAPY_SDR_TX, channel); - if (fabs(got_rate - rate) > 0.001) { - PDEBUG(DUHD, DEBUG_ERROR, "Given TX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate); + if (fabs(got_rate - rate) > 0.01) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Given TX rate %.3f Hz is not supported, try %.3f Hz\n", rate, got_rate); soapy_close(); return -EINVAL; } - /* set gain */ - if (SoapySDRDevice_setGain(sdr, SOAPY_SDR_TX, channel, tx_gain) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX gain to %.0f\n", tx_gain); - soapy_close(); - return -EIO; - } - - /* see what gain actually is */ - got_gain = SoapySDRDevice_getGain(sdr, SOAPY_SDR_TX, channel); - if (fabs(got_gain - tx_gain) > 0.001) { - PDEBUG(DUHD, DEBUG_NOTICE, "Given TX gain %.0f is not supported, we use %0.f\n", tx_gain, got_gain); - tx_gain = got_gain; + if (tx_gain) { + /* set gain */ + if (SoapySDRDevice_setGain(sdr, SOAPY_SDR_TX, channel, tx_gain) != 0) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to set TX gain to %.0f\n", tx_gain); + soapy_close(); + return -EIO; + } + + /* see what gain actually is */ + got_gain = SoapySDRDevice_getGain(sdr, SOAPY_SDR_TX, channel); + if (fabs(got_gain - tx_gain) > 0.001) { + PDEBUG(DSOAPY, DEBUG_NOTICE, "Given TX gain %.3f is not supported, we use %.3f\n", tx_gain, got_gain); + tx_gain = got_gain; + } } /* set frequency */ - if (SoapySDRDevice_setFrequency(sdr, SOAPY_SDR_TX, channel, tx_frequency, NULL) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX frequency to %.0f Hz\n", tx_frequency); + if (SoapySDRDevice_setFrequency(sdr, SOAPY_SDR_TX, channel, tx_frequency, &tune_args) != 0) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to set TX frequency to %.0f Hz\n", tx_frequency); soapy_close(); return -EIO; } /* see what frequency actually is */ got_frequency = SoapySDRDevice_getFrequency(sdr, SOAPY_SDR_TX, channel); - if (fabs(got_frequency - tx_frequency) > 0.001) { - PDEBUG(DUHD, DEBUG_ERROR, "Given TX frequency %.0f Hz is not supported, try %0.f Hz\n", tx_frequency, got_frequency); + if (fabs(got_frequency - tx_frequency) > 100.0) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Given TX frequency %.0f Hz is not supported, try %.0f Hz\n", tx_frequency, got_frequency); soapy_close(); return -EINVAL; } /* set bandwidth */ if (SoapySDRDevice_setBandwidth(sdr, SOAPY_SDR_TX, channel, bandwidth) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX bandwidth to %.0f Hz\n", bandwidth); + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to set TX bandwidth to %.0f Hz\n", bandwidth); soapy_close(); return -EIO; } /* see what bandwidth actually is */ got_bandwidth = SoapySDRDevice_getBandwidth(sdr, SOAPY_SDR_TX, channel); - if (fabs(got_bandwidth - bandwidth) >= 0.001) { - PDEBUG(DUHD, DEBUG_ERROR, "Given TX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth); + if (fabs(got_bandwidth - bandwidth) > 100.0) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Given TX bandwidth %.0f Hz is not supported, try %.0f Hz\n", bandwidth, got_bandwidth); soapy_close(); return -EINVAL; } /* set up streamer */ - if (SoapySDRDevice_setupStream(sdr, &txStream, SOAPY_SDR_TX, SOAPY_SDR_CF32, &channel, 1, NULL) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX streamer args\n"); + if (SoapySDRDevice_setupStream(sdr, &txStream, SOAPY_SDR_TX, SOAPY_SDR_CF32, &channel, 1, &stream_args) != 0) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to set TX streamer args\n"); soapy_close(); return -EIO; } @@ -137,75 +207,119 @@ int soapy_open(size_t channel, const char *device_args, double tx_frequency, dou /* get buffer sizes */ tx_samps_per_buff = SoapySDRDevice_getStreamMTU(sdr, txStream); if (tx_samps_per_buff == 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX streamer sample buffer\n"); + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to get TX streamer sample buffer\n"); soapy_close(); return -EIO; } } if (rx_frequency) { + /* get number of channels and check if requested channel is in range */ + num_channels = SoapySDRDevice_getNumChannels(sdr, SOAPY_SDR_RX); + PDEBUG(DSOAPY, DEBUG_DEBUG, "We have %d RX channel, selecting channel #%d\n", (int)num_channels, (int)channel); + if (channel >= num_channels) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Requested channel #%d (capable of RX) does not exist. Please select channel %d..%d!\n", (int)channel, 0, (int)num_channels - 1); + soapy_close(); + return -EIO; + } + + /* antenna */ + if (rx_antenna && rx_antenna[0]) { + if (!strcasecmp(rx_antenna, "list")) { + char **antennas; + size_t antennas_length; + int i; + antennas = SoapySDRDevice_listAntennas(sdr, SOAPY_SDR_RX, channel, &antennas_length); + if (!antennas) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to request list of RX antennas!\n"); + soapy_close(); + return -EIO; + } + for (i = 0; i < (int)antennas_length; i++) + PDEBUG(DSOAPY, DEBUG_NOTICE, "RX Antenna: '%s'\n", antennas[i]); + got_antenna = SoapySDRDevice_getAntenna(sdr, SOAPY_SDR_RX, channel); + PDEBUG(DSOAPY, DEBUG_NOTICE, "Default RX Antenna: '%s'\n", got_antenna); + soapy_close(); + return 1; + } + + if (SoapySDRDevice_setAntenna(sdr, SOAPY_SDR_RX, channel, rx_antenna) != 0) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to set RX antenna to '%s'\n", rx_antenna); + soapy_close(); + return -EIO; + } + got_antenna = SoapySDRDevice_getAntenna(sdr, SOAPY_SDR_RX, channel); + if (!!strcasecmp(rx_antenna, got_antenna)) { + PDEBUG(DSOAPY, DEBUG_NOTICE, "Given RX antenna '%s' was accepted, but driver claims to use '%s'\n", rx_antenna, got_antenna); + soapy_close(); + return -EINVAL; + } + } + /* set rate */ if (SoapySDRDevice_setSampleRate(sdr, SOAPY_SDR_RX, channel, rate) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX rate to %.0f Hz\n", rate); + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to set RX rate to %.0f Hz\n", rate); soapy_close(); return -EIO; } /* see what rate actually is */ got_rate = SoapySDRDevice_getSampleRate(sdr, SOAPY_SDR_RX, channel); - if (fabs(got_rate - rate) > 0.001) { - PDEBUG(DUHD, DEBUG_ERROR, "Given RX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate); + if (fabs(got_rate - rate) > 0.01) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Given RX rate %.3f Hz is not supported, try %.3f Hz\n", rate, got_rate); soapy_close(); return -EINVAL; } - /* set gain */ - if (SoapySDRDevice_setGain(sdr, SOAPY_SDR_RX, channel, rx_gain) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX gain to %.0f\n", rx_gain); - soapy_close(); - return -EIO; - } - - /* see what gain actually is */ - got_gain = SoapySDRDevice_getGain(sdr, SOAPY_SDR_RX, channel); - if (fabs(got_gain - rx_gain) > 0.001) { - PDEBUG(DUHD, DEBUG_NOTICE, "Given RX gain %.3f is not supported, we use %.3f\n", rx_gain, got_gain); - rx_gain = got_gain; + if (rx_gain) { + /* set gain */ + if (SoapySDRDevice_setGain(sdr, SOAPY_SDR_RX, channel, rx_gain) != 0) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to set RX gain to %.0f\n", rx_gain); + soapy_close(); + return -EIO; + } + + /* see what gain actually is */ + got_gain = SoapySDRDevice_getGain(sdr, SOAPY_SDR_RX, channel); + if (fabs(got_gain - rx_gain) > 0.001) { + PDEBUG(DSOAPY, DEBUG_NOTICE, "Given RX gain %.3f is not supported, we use %.3f\n", rx_gain, got_gain); + rx_gain = got_gain; + } } /* set frequency */ - if (SoapySDRDevice_setFrequency(sdr, SOAPY_SDR_RX, channel, rx_frequency, NULL) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX frequency to %.0f Hz\n", rx_frequency); + if (SoapySDRDevice_setFrequency(sdr, SOAPY_SDR_RX, channel, rx_frequency, &tune_args) != 0) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to set RX frequency to %.0f Hz\n", rx_frequency); soapy_close(); return -EIO; } /* see what frequency actually is */ got_frequency = SoapySDRDevice_getFrequency(sdr, SOAPY_SDR_RX, channel); - if (fabs(got_frequency - rx_frequency) > 0.001) { - PDEBUG(DUHD, DEBUG_ERROR, "Given RX frequency %.0f Hz is not supported, try %0.f Hz\n", rx_frequency, got_frequency); + if (fabs(got_frequency - rx_frequency) > 100.0) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Given RX frequency %.0f Hz is not supported, try %.0f Hz\n", rx_frequency, got_frequency); soapy_close(); return -EINVAL; } /* set bandwidth */ if (SoapySDRDevice_setBandwidth(sdr, SOAPY_SDR_RX, channel, bandwidth) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX bandwidth to %.0f Hz\n", bandwidth); + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to set RX bandwidth to %.0f Hz\n", bandwidth); soapy_close(); return -EIO; } /* see what bandwidth actually is */ got_bandwidth = SoapySDRDevice_getBandwidth(sdr, SOAPY_SDR_RX, channel); - if (fabs(got_bandwidth - bandwidth) > 0.001) { - PDEBUG(DUHD, DEBUG_ERROR, "Given RX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth); + if (fabs(got_bandwidth - bandwidth) > 100.0) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Given RX bandwidth %.0f Hz is not supported, try %.0f Hz\n", bandwidth, got_bandwidth); soapy_close(); return -EINVAL; } /* set up streamer */ - if (SoapySDRDevice_setupStream(sdr, &rxStream, SOAPY_SDR_RX, SOAPY_SDR_CF32, &channel, 1, NULL) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX streamer args\n"); + if (SoapySDRDevice_setupStream(sdr, &rxStream, SOAPY_SDR_RX, SOAPY_SDR_CF32, &channel, 1, &stream_args) != 0) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to set RX streamer args\n"); soapy_close(); return -EIO; } @@ -213,7 +327,7 @@ int soapy_open(size_t channel, const char *device_args, double tx_frequency, dou /* get buffer sizes */ rx_samps_per_buff = SoapySDRDevice_getStreamMTU(sdr, rxStream); if (rx_samps_per_buff == 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX streamer sample buffer\n"); + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to get RX streamer sample buffer\n"); soapy_close(); return -EIO; } @@ -227,7 +341,13 @@ int soapy_start(void) { /* enable rx stream */ if (SoapySDRDevice_activateStream(sdr, rxStream, 0, 0, 0) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to issue RX stream command\n"); + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to issue RX stream command\n"); + return -EIO; + } + + /* enable tx stream */ + if (SoapySDRDevice_activateStream(sdr, txStream, 0, 0, 0) != 0) { + PDEBUG(DSOAPY, DEBUG_ERROR, "Failed to issue TX stream command\n"); return -EIO; } return 0; @@ -235,8 +355,9 @@ int soapy_start(void) void soapy_close(void) { - PDEBUG(DUHD, DEBUG_DEBUG, "Clean up UHD\n"); + PDEBUG(DSOAPY, DEBUG_DEBUG, "Clean up SoapySDR\n"); if (txStream) { + SoapySDRDevice_deactivateStream(sdr, txStream, 0, 0); SoapySDRDevice_closeStream(sdr, txStream); txStream = NULL; } @@ -290,7 +411,7 @@ int soapy_receive(float *buff, int max) while (1) { if (max < rx_samps_per_buff) { /* no more space this time */ - PDEBUG(DUHD, DEBUG_ERROR, "SDR RX overflow!\n"); + PDEBUG(DSOAPY, DEBUG_ERROR, "SDR RX overflow!\n"); break; } /* read RX stream */ @@ -329,7 +450,7 @@ int soapy_get_tosend(int latspl) tosend = latspl - (tx_count - rx_count); /* in case of underrun: */ if (tosend < 0) { - PDEBUG(DUHD, DEBUG_ERROR, "SDR TX underrun!\n"); + PDEBUG(DSOAPY, DEBUG_ERROR, "SDR TX underrun!\n"); tosend = 0; } diff --git a/src/common/soapy.h b/src/common/soapy.h index 525899f..702890b 100644 --- a/src/common/soapy.h +++ b/src/common/soapy.h @@ -1,5 +1,5 @@ -int soapy_open(size_t channel, const char *device_args, double tx_frequency, double rx_frequency, double rate, double rx_gain, double tx_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 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/common/uhd.c b/src/common/uhd.c index 6d79b26..b22f722 100644 --- a/src/common/uhd.c +++ b/src/common/uhd.c @@ -45,17 +45,22 @@ static time_t tx_time_secs = 0; static double tx_time_fract_sec = 0.0; static int rx_gap = 0; /* if we missed samples, we fill our rx data with zeroes */ -int uhd_open(size_t channel, const char *device_args, double tx_frequency, double rx_frequency, double rate, double rx_gain, double tx_gain, double bandwidth) +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) { uhd_error error; double got_frequency, got_rate, got_gain, got_bandwidth; + char got_antenna[64]; samplerate = rate; check_rate = 1; + PDEBUG(DUHD, DEBUG_INFO, "Using device args \"%s\"\n", _device_args); + PDEBUG(DUHD, DEBUG_INFO, "Using stream args \"%s\"\n", _stream_args); + PDEBUG(DUHD, DEBUG_INFO, "Using tune args \"%s\"\n", _tune_args); + /* create USRP */ - PDEBUG(DUHD, DEBUG_INFO, "Creating USRP with args \"%s\"...\n", device_args); - error = uhd_usrp_make(&usrp, device_args); + PDEBUG(DUHD, DEBUG_INFO, "Creating USRP with args \"%s\"...\n", _device_args); + error = uhd_usrp_make(&usrp, _device_args); if (error) { PDEBUG(DUHD, DEBUG_ERROR, "Failed to create USRP\n"); uhd_close(); @@ -63,6 +68,64 @@ int uhd_open(size_t channel, const char *device_args, double tx_frequency, doubl } if (tx_frequency) { + /* antenna */ + if (tx_antenna && tx_antenna[0]) { + if (!strcasecmp(tx_antenna, "list")) { + uhd_string_vector_handle antennas; + size_t antennas_length; + int i; + error = uhd_string_vector_make(&antennas); + if (error) { + tx_vector_error: + PDEBUG(DUHD, DEBUG_ERROR, "Failed to hande UHD vector, please fix!\n"); + uhd_close(); + return -EIO; + } + error = uhd_usrp_get_tx_antennas(usrp, channel, &antennas); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to request list of TX antennas!\n"); + uhd_close(); + return -EIO; + } + error = uhd_string_vector_size(antennas, &antennas_length); + if (error) + goto tx_vector_error; + for (i = 0; i < (int)antennas_length; i++) { + error = uhd_string_vector_at(antennas, i, got_antenna, sizeof(got_antenna)); + if (error) + goto tx_vector_error; + PDEBUG(DUHD, DEBUG_NOTICE, "TX Antenna: '%s'\n", got_antenna); + } + uhd_string_vector_free(&antennas); + error = uhd_usrp_get_tx_antenna(usrp, channel, got_antenna, sizeof(got_antenna)); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX antenna\n"); + uhd_close(); + return -EINVAL; + } + PDEBUG(DUHD, DEBUG_NOTICE, "Default TX Antenna: '%s'\n", got_antenna); + uhd_close(); + return 1; + } + error = uhd_usrp_set_tx_antenna(usrp, tx_antenna, channel); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX antenna to '%s'\n", tx_antenna); + uhd_close(); + return -EIO; + } + error = uhd_usrp_get_tx_antenna(usrp, channel, got_antenna, sizeof(got_antenna)); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX antenna\n"); + uhd_close(); + return -EINVAL; + } + if (!!strcasecmp(tx_antenna, got_antenna)) { + PDEBUG(DUHD, DEBUG_NOTICE, "Given TX antenna '%s' was accepted, but driver claims to use '%s'\n", tx_antenna, got_antenna); + uhd_close(); + return -EINVAL; + } + } + /* create streamers */ error = uhd_tx_streamer_make(&tx_streamer); if (error) { @@ -87,7 +150,7 @@ int uhd_open(size_t channel, const char *device_args, double tx_frequency, doubl return -EIO; } if (fabs(got_rate - rate) > 0.001) { - PDEBUG(DUHD, DEBUG_ERROR, "Given TX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate); + PDEBUG(DUHD, DEBUG_ERROR, "Given TX rate %.0f Hz is not supported, try %.0f Hz\n", rate, got_rate); uhd_close(); return -EINVAL; } @@ -108,7 +171,7 @@ int uhd_open(size_t channel, const char *device_args, double tx_frequency, doubl return -EIO; } if (fabs(got_gain - tx_gain) > 0.001) { - PDEBUG(DUHD, DEBUG_NOTICE, "Given TX gain %.0f is not supported, we use %0.f\n", tx_gain, got_gain); + PDEBUG(DUHD, DEBUG_NOTICE, "Given TX gain %.0f is not supported, we use %.0f\n", tx_gain, got_gain); tx_gain = got_gain; } @@ -117,6 +180,7 @@ int uhd_open(size_t channel, const char *device_args, double tx_frequency, doubl tune_request.target_freq = tx_frequency; 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); if (error) { PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX frequeny to %.0f Hz\n", tx_frequency); @@ -132,7 +196,7 @@ int uhd_open(size_t channel, const char *device_args, double tx_frequency, doubl return -EIO; } if (fabs(got_frequency - tx_frequency) > 0.001) { - PDEBUG(DUHD, DEBUG_ERROR, "Given TX frequency %.0f Hz is not supported, try %0.f Hz\n", tx_frequency, got_frequency); + PDEBUG(DUHD, DEBUG_ERROR, "Given TX frequency %.0f Hz is not supported, try %.0f Hz\n", tx_frequency, got_frequency); uhd_close(); return -EINVAL; } @@ -152,7 +216,7 @@ int uhd_open(size_t channel, const char *device_args, double tx_frequency, doubl return -EIO; } if (fabs(got_bandwidth - bandwidth) > 0.001) { - PDEBUG(DUHD, DEBUG_ERROR, "Given TX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth); + PDEBUG(DUHD, DEBUG_ERROR, "Given TX bandwidth %.0f Hz is not supported, try %.0f Hz\n", bandwidth, got_bandwidth); uhd_close(); return -EINVAL; } @@ -161,7 +225,7 @@ int uhd_open(size_t channel, const char *device_args, double tx_frequency, doubl memset(&stream_args, 0, sizeof(stream_args)); stream_args.cpu_format = "fc32"; stream_args.otw_format = "sc16"; - stream_args.args = ""; + stream_args.args = strdup(_stream_args); stream_args.channel_list = &channel; stream_args.n_channels = 1; error = uhd_usrp_get_tx_stream(usrp, &stream_args, tx_streamer); @@ -181,6 +245,63 @@ int uhd_open(size_t channel, const char *device_args, double tx_frequency, doubl } if (rx_frequency) { + /* antenna */ + if (rx_antenna && rx_antenna[0]) { + if (!strcasecmp(rx_antenna, "list")) { + uhd_string_vector_handle antennas; + size_t antennas_length; + int i; + error = uhd_string_vector_make(&antennas); + if (error) { + rx_vector_error: + PDEBUG(DUHD, DEBUG_ERROR, "Failed to hande UHD vector, please fix!\n"); + uhd_close(); + return -EIO; + } + error = uhd_usrp_get_rx_antennas(usrp, channel, &antennas); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to request list of RX antennas!\n"); + uhd_close(); + return -EIO; + } + error = uhd_string_vector_size(antennas, &antennas_length); + if (error) + goto rx_vector_error; + for (i = 0; i < (int)antennas_length; i++) { + error = uhd_string_vector_at(antennas, i, got_antenna, sizeof(got_antenna)); + if (error) + goto rx_vector_error; + PDEBUG(DUHD, DEBUG_NOTICE, "RX Antenna: '%s'\n", got_antenna); + } + uhd_string_vector_free(&antennas); + error = uhd_usrp_get_rx_antenna(usrp, channel, got_antenna, sizeof(got_antenna)); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX antenna\n"); + uhd_close(); + return -EINVAL; + } + PDEBUG(DUHD, DEBUG_NOTICE, "Default RX Antenna: '%s'\n", got_antenna); + uhd_close(); + return 1; + } + error = uhd_usrp_set_rx_antenna(usrp, rx_antenna, channel); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX antenna to '%s'\n", rx_antenna); + uhd_close(); + return -EIO; + } + error = uhd_usrp_get_rx_antenna(usrp, channel, got_antenna, sizeof(got_antenna)); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX antenna\n"); + uhd_close(); + return -EINVAL; + } + if (!!strcasecmp(rx_antenna, got_antenna)) { + PDEBUG(DUHD, DEBUG_NOTICE, "Given RX antenna '%s' was accepted, but driver claims to use '%s'\n", rx_antenna, got_antenna); + uhd_close(); + return -EINVAL; + } + } /* create streamers */ error = uhd_rx_streamer_make(&rx_streamer); if (error) { @@ -213,7 +334,7 @@ int uhd_open(size_t channel, const char *device_args, double tx_frequency, doubl return -EIO; } if (fabs(got_rate - rate) > 0.001) { - PDEBUG(DUHD, DEBUG_ERROR, "Given RX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate); + PDEBUG(DUHD, DEBUG_ERROR, "Given RX rate %.0f Hz is not supported, try %.0f Hz\n", rate, got_rate); uhd_close(); return -EINVAL; } @@ -243,6 +364,7 @@ int uhd_open(size_t channel, const char *device_args, double tx_frequency, doubl tune_request.target_freq = rx_frequency; 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); if (error) { PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX frequeny to %.0f Hz\n", rx_frequency); @@ -258,7 +380,7 @@ int uhd_open(size_t channel, const char *device_args, double tx_frequency, doubl return -EIO; } if (fabs(got_frequency - rx_frequency) > 0.001) { - PDEBUG(DUHD, DEBUG_ERROR, "Given RX frequency %.0f Hz is not supported, try %0.f Hz\n", rx_frequency, got_frequency); + PDEBUG(DUHD, DEBUG_ERROR, "Given RX frequency %.0f Hz is not supported, try %.0f Hz\n", rx_frequency, got_frequency); uhd_close(); return -EINVAL; } @@ -278,7 +400,7 @@ int uhd_open(size_t channel, const char *device_args, double tx_frequency, doubl return -EIO; } if (fabs(got_bandwidth - bandwidth) > 0.001) { - PDEBUG(DUHD, DEBUG_ERROR, "Given RX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth); + PDEBUG(DUHD, DEBUG_ERROR, "Given RX bandwidth %.0f Hz is not supported, try %.0f Hz\n", bandwidth, got_bandwidth); uhd_close(); return -EINVAL; } @@ -287,7 +409,7 @@ int uhd_open(size_t channel, const char *device_args, double tx_frequency, doubl memset(&stream_args, 0, sizeof(stream_args)); stream_args.cpu_format = "fc32"; stream_args.otw_format = "sc16"; - stream_args.args = ""; + stream_args.args = strdup(_stream_args); stream_args.channel_list = &channel; stream_args.n_channels = 1; error = uhd_usrp_get_rx_stream(usrp, &stream_args, rx_streamer); diff --git a/src/common/uhd.h b/src/common/uhd.h index 55f1bb8..95891ae 100644 --- a/src/common/uhd.h +++ b/src/common/uhd.h @@ -1,5 +1,5 @@ -int uhd_open(size_t channel, const char *device_args, double tx_frequency, double rx_frequency, double rate, double rx_gain, double tx_gain, double bandwidth); +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 uhd_start(void); void uhd_close(void); int uhd_send(float *buff, int num); |