Compare commits

...

2 Commits

Author SHA1 Message Date
Oliver Jowett e2494c2159 Quick hacks to get it working with rtlsdr-on-soapy 2019-01-10 22:50:59 +00:00
Oliver Jowett 8001832de2 WIP soapysdr support 2019-01-10 22:26:54 +00:00
5 changed files with 267 additions and 1 deletions

View File

@ -35,6 +35,10 @@ ifeq ($(BLADERF), yes)
LIBS_SDR += $(shell pkg-config --libs libbladeRF)
endif
SDR_OBJ += sdr_soapy.o
CFLAGS += $(shell pkg-config --cflags SoapySDR)
LIBS_SDR += $(shell pkg-config --libs SoapySDR)
all: dump1090 view1090
%.o: %.c *.h

View File

@ -274,7 +274,7 @@ typedef enum {
//======================== structure declarations =========================
typedef enum {
SDR_NONE, SDR_IFILE, SDR_RTLSDR, SDR_BLADERF
SDR_NONE, SDR_IFILE, SDR_RTLSDR, SDR_BLADERF, SDR_SOAPY
} sdr_type_t;
// Structure representing one magnitude buffer

3
sdr.c
View File

@ -28,6 +28,8 @@
# include "sdr_bladerf.h"
#endif
#include "sdr_soapy.h"
typedef struct {
const char *name;
sdr_type_t sdr_type;
@ -85,6 +87,7 @@ static sdr_handler sdr_handlers[] = {
{ "bladerf", SDR_BLADERF, bladeRFInitConfig, bladeRFShowHelp, bladeRFHandleOption, bladeRFOpen, bladeRFRun, bladeRFClose },
#endif
{ "soapy", SDR_SOAPY, soapyInitConfig, soapyShowHelp, soapyHandleOption, soapyOpen, soapyRun, soapyClose },
{ "ifile", SDR_IFILE, ifileInitConfig, ifileShowHelp, ifileHandleOption, ifileOpen, ifileRun, ifileClose },
{ "none", SDR_NONE, noInitConfig, noShowHelp, noHandleOption, noOpen, noRun, noClose },

228
sdr_soapy.c Normal file
View File

@ -0,0 +1,228 @@
// Part of dump1090, a Mode S message decoder for RTLSDR devices.
//
// sdr_soapy.c: SoapySDR support
//
// Copyright (c) 2014-2017 Oliver Jowett <oliver@mutability.co.uk>
// Copyright (c) 2017 FlightAware LLC
//
// This file is free software: you may copy, redistribute and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 2 of the License, or (at your
// option) any later version.
//
// This file 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/>.
#include "dump1090.h"
#include "sdr_soapy.h"
#include <SoapySDR/Device.h>
#include <SoapySDR/Formats.h>
static struct {
SoapySDRDevice *dev;
SoapySDRStream *stream;
iq_convert_fn converter;
struct converter_state *converter_state;
} SOAPY;
//
// =============================== SoapySDR handling ==========================
//
void soapyInitConfig()
{
SOAPY.dev = NULL;
SOAPY.stream = NULL;
SOAPY.converter = NULL;
SOAPY.converter_state = NULL;
}
void soapyShowHelp()
{
printf(" SoapySDR-specific options (use with --device-type soapy)\n");
printf("\n");
printf("--device <string> select/configure device\n");
printf("\n");
}
bool soapyHandleOption(int argc, char **argv, int *jptr)
{
MODES_NOTUSED(argc);
MODES_NOTUSED(argv);
MODES_NOTUSED(jptr);
return false;
}
bool soapyOpen(void)
{
size_t length;
SoapySDRKwargs *results = SoapySDRDevice_enumerate(NULL, &length);
for (size_t i = 0; i < length; i++)
{
printf("Found device #%d: ", (int)i);
for (size_t j = 0; j < results[i].size; j++)
{
printf("%s=%s, ", results[i].keys[j], results[i].vals[j]);
}
printf("\n");
}
SoapySDRKwargsList_clear(results, length);
SOAPY.dev = SoapySDRDevice_makeStrArgs(Modes.dev_name);
if (!SOAPY.dev) {
fprintf(stderr, "soapy: failed to create device: %s\n", SoapySDRDevice_lastError());
return false;
}
SoapySDRKwargs result = SoapySDRDevice_getHardwareInfo(SOAPY.dev);
for (size_t i = 0; i < result.size; ++i) {
printf("%s=%s\n", result.keys[i], result.vals[i]);
}
SoapySDRKwargs_clear(&result);
if (SoapySDRDevice_setSampleRate(SOAPY.dev, SOAPY_SDR_RX, 0, Modes.sample_rate) != 0) {
fprintf(stderr, "soapy: setSampleRate failed: %s\n", SoapySDRDevice_lastError());
goto error;
}
if (SoapySDRDevice_setFrequency(SOAPY.dev, SOAPY_SDR_RX, 0, Modes.freq, NULL) != 0) {
fprintf(stderr, "soapy: setFrequency failed: %s\n", SoapySDRDevice_lastError());
goto error;
}
if (SoapySDRDevice_setGain(SOAPY.dev, SOAPY_SDR_RX, 0, Modes.gain / 10.0) != 0) {
fprintf(stderr, "soapy: setGain failed: %s\n", SoapySDRDevice_lastError());
goto error;
}
if (SoapySDRDevice_setBandwidth(SOAPY.dev, SOAPY_SDR_RX, 0, 3.0e6) != 0) {
fprintf(stderr, "soapy: setBandwidth failed: %s\n", SoapySDRDevice_lastError());
goto error;
}
if (SoapySDRDevice_setAntenna(SOAPY.dev, SOAPY_SDR_RX, 0, "LNAW") != 0) {
fprintf(stderr, "soapy: setAntenna failed: %s\n", SoapySDRDevice_lastError());
goto error;
}
fprintf(stderr, "soapy: frequency is %.1f MHz\n",
SoapySDRDevice_getFrequency(SOAPY.dev, SOAPY_SDR_RX, 0) / 1e6);
fprintf(stderr, "soapy: sample rate is %.1f MHz\n",
SoapySDRDevice_getSampleRate(SOAPY.dev, SOAPY_SDR_RX, 0) / 1e6);
fprintf(stderr, "soapy: bandwidth is %.1f MHz\n",
SoapySDRDevice_getBandwidth(SOAPY.dev, SOAPY_SDR_RX, 0) / 1e6);
fprintf(stderr, "soapy: gain mode is %d\n",
SoapySDRDevice_getGainMode(SOAPY.dev, SOAPY_SDR_RX, 0));
fprintf(stderr, "soapy: gain is %.1f dB\n",
SoapySDRDevice_getGain(SOAPY.dev, SOAPY_SDR_RX, 0));
fprintf(stderr, "soapy: antenna is %s\n",
SoapySDRDevice_getAntenna(SOAPY.dev, SOAPY_SDR_RX, 0));
size_t channels[1] = { 0 };
if (SoapySDRDevice_setupStream(SOAPY.dev, &SOAPY.stream, SOAPY_SDR_RX, SOAPY_SDR_CS16, channels, 1, NULL) != 0) {
fprintf(stderr, "soapy: setupStream failed: %s\n", SoapySDRDevice_lastError());
goto error;
}
SOAPY.converter = init_converter(INPUT_SC16,
Modes.sample_rate,
Modes.dc_filter,
&SOAPY.converter_state);
if (!SOAPY.converter) {
fprintf(stderr, "soapy: can't initialize sample converter\n");
goto error;
}
return true;
error:
if (SOAPY.dev != NULL) {
SoapySDRDevice_unmake(SOAPY.dev);
SOAPY.dev = NULL;
}
return false;
}
void soapyRun()
{
if (!SOAPY.dev) {
return;
}
if (SoapySDRDevice_activateStream(SOAPY.dev, SOAPY.stream, 0, 0, 0) != 0) {
fprintf(stderr, "soapy: activateStream failed: %s\n", SoapySDRDevice_lastError());
return;
}
void *buffers[1];
const int buffer_elements = 131072;
buffers[0] = malloc(buffer_elements * 4);
while (!Modes.exit) {
int flags;
long long timeNs;
int sample_count = SoapySDRDevice_readStream(SOAPY.dev, SOAPY.stream, buffers, buffer_elements, &flags, &timeNs, 5000000);
if (sample_count <= 0) {
fprintf(stderr, "soapy: readStream failed: %s\n", SoapySDRDevice_lastError());
return;
}
pthread_mutex_lock(&Modes.data_mutex);
unsigned next_free_buffer = (Modes.first_free_buffer + 1) % MODES_MAG_BUFFERS;
if (next_free_buffer == Modes.first_filled_buffer) {
// drop it
fprintf(stderr, "fifo full\n");
pthread_mutex_unlock(&Modes.data_mutex);
continue;
}
struct mag_buf *outbuf = &Modes.mag_buffers[Modes.first_free_buffer];
struct mag_buf *lastbuf = &Modes.mag_buffers[(Modes.first_free_buffer + MODES_MAG_BUFFERS - 1) % MODES_MAG_BUFFERS];
pthread_mutex_unlock(&Modes.data_mutex);
// Copy trailing data from last block
memcpy(outbuf->data, lastbuf->data + lastbuf->length, Modes.trailing_samples * sizeof(uint16_t));
SOAPY.converter(buffers[0], &outbuf->data[Modes.trailing_samples], sample_count,
SOAPY.converter_state, &outbuf->mean_level, &outbuf->mean_power);
outbuf->dropped = 0;
outbuf->length = sample_count;
pthread_mutex_lock(&Modes.data_mutex);
Modes.mag_buffers[next_free_buffer].dropped = 0;
Modes.mag_buffers[next_free_buffer].length = 0;
Modes.first_free_buffer = next_free_buffer;
pthread_cond_signal(&Modes.data_cond);
pthread_mutex_unlock(&Modes.data_mutex);
}
}
void soapyClose()
{
fprintf(stderr, "close stream\n");
if (SOAPY.stream) {
SoapySDRDevice_closeStream(SOAPY.dev, SOAPY.stream);
SOAPY.stream = NULL;
}
fprintf(stderr, "close device\n");
if (SOAPY.dev) {
SoapySDRDevice_unmake(SOAPY.dev);
SOAPY.dev = NULL;
}
if (SOAPY.converter) {
cleanup_converter(SOAPY.converter_state);
SOAPY.converter = NULL;
SOAPY.converter_state = NULL;
}
fprintf(stderr, "all done\n");
}

31
sdr_soapy.h Normal file
View File

@ -0,0 +1,31 @@
// Part of dump1090, a Mode S message decoder for RTLSDR devices.
//
// sdr_soapy.h: SoapySDR dongle support (header)
//
// Copyright (c) 2016-2017 Oliver Jowett <oliver@mutability.co.uk>
// Copyright (c) 2017 FlightAware LLC
//
// This file is free software: you may copy, redistribute and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 2 of the License, or (at your
// option) any later version.
//
// This file 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/>.
#ifndef SDR_SOAPY_H
#define SDR_SOAPY_H
void soapyInitConfig();
void soapyShowHelp();
bool soapyOpen();
void soapyRun();
void soapyClose();
bool soapyHandleOption(int argc, char **argv, int *jptr);
#endif