limesdr: basic implementation of LimeSDR support
The commit provides a basic implementation of support for LimeSDR USB receivers based on LMS7002 chip. The solution has several limitations: - passing parameters for tune LimeSDR receiver via command-line options is not implemented; - only hardcoded configuration is used (channel 0 of lower band LNA, LMS_FMT_I16 format, gain, bandwidth and timeout); - only one device is supported and it is not possible to select a desired one in case if several devices are connected to the host. Test: compare the output of the program for RTL and LimeSDR receivers. Environment: - RTL2832SDR dongle; - LMS7002M based USB LimeSDR board; - 800MHz-2200MHz omnidirectional antenna with SMA connector. Procedure: - connect RTL dongle to the host and start the program with the following parameters: $ ./dump1090 --device-type rtlsdr --interactive - wait until several planes will be detected; - stop the program, connect the LimeSDR board to the host and restart the program with the following parameters: $ ./dump1090 --device-type limesdr --interactive - ensure that the same planes are detected. Acceptance criteria: the same planes are detected using both receivers and track information matches with information from the FlightRadar24 application. Signed-off-by: Gluttton <gluttton@ukr.net>
This commit is contained in:
parent
d6b8065c3b
commit
53183c0b2a
8
Makefile
8
Makefile
|
|
@ -2,6 +2,7 @@ PROGNAME=dump1090
|
||||||
|
|
||||||
RTLSDR ?= yes
|
RTLSDR ?= yes
|
||||||
BLADERF ?= yes
|
BLADERF ?= yes
|
||||||
|
LIMESDR ?= yes
|
||||||
|
|
||||||
CPPFLAGS += -DMODES_DUMP1090_VERSION=\"$(DUMP1090_VERSION)\" -DMODES_DUMP1090_VARIANT=\"dump1090-fa\"
|
CPPFLAGS += -DMODES_DUMP1090_VERSION=\"$(DUMP1090_VERSION)\" -DMODES_DUMP1090_VARIANT=\"dump1090-fa\"
|
||||||
|
|
||||||
|
|
@ -39,6 +40,13 @@ ifeq ($(BLADERF), yes)
|
||||||
LIBS_SDR += $(shell pkg-config --libs libbladeRF)
|
LIBS_SDR += $(shell pkg-config --libs libbladeRF)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(LIMESDR), yes)
|
||||||
|
SDR_OBJ += sdr_limesdr.o
|
||||||
|
CPPFLAGS += -DENABLE_LIMESDR
|
||||||
|
CFLAGS += $(shell pkg-config --cflags LimeSuite)
|
||||||
|
LIBS_SDR += $(shell pkg-config --libs LimeSuite)
|
||||||
|
endif
|
||||||
|
|
||||||
all: dump1090 view1090
|
all: dump1090 view1090
|
||||||
|
|
||||||
%.o: %.c *.h
|
%.o: %.c *.h
|
||||||
|
|
|
||||||
12
README.md
12
README.md
|
|
@ -36,6 +36,11 @@ see https://flightaware.com/adsb/piaware/install
|
||||||
|
|
||||||
This is packaged with jessie. `sudo apt-get install librtlsdr-dev`
|
This is packaged with jessie. `sudo apt-get install librtlsdr-dev`
|
||||||
|
|
||||||
|
### Dependencies - LimeSDR
|
||||||
|
|
||||||
|
You will need a build of [LimeSuite](https://github.com/myriadrf/LimeSuite).
|
||||||
|
See detailed instruction on [the official Wiki](https://wiki.myriadrf.org/Lime_Suite) how to build and install it.
|
||||||
|
|
||||||
### Actually building it
|
### Actually building it
|
||||||
|
|
||||||
Nothing special, just build it (`dpkg-buildpackage -b`)
|
Nothing special, just build it (`dpkg-buildpackage -b`)
|
||||||
|
|
@ -45,7 +50,7 @@ Nothing special, just build it (`dpkg-buildpackage -b`)
|
||||||
First run `prepare-wheezy-tree.sh`. This will create a package tree in
|
First run `prepare-wheezy-tree.sh`. This will create a package tree in
|
||||||
package-wheezy/. Build in there (`dpkg-buildpackage -b`)
|
package-wheezy/. Build in there (`dpkg-buildpackage -b`)
|
||||||
|
|
||||||
The wheezy build does not include bladeRF support.
|
The wheezy build does not include bladeRF and LimeSDR support.
|
||||||
|
|
||||||
## Building manually
|
## Building manually
|
||||||
|
|
||||||
|
|
@ -56,5 +61,8 @@ install them (and a method for starting them) yourself.
|
||||||
``make BLADERF=no`` will disable bladeRF support and remove the dependency on
|
``make BLADERF=no`` will disable bladeRF support and remove the dependency on
|
||||||
libbladeRF.
|
libbladeRF.
|
||||||
|
|
||||||
``make RTLSDR=no`` will disable rtl-sdr support and remove the dependency on
|
``make RTLSDR=no`` will disable rtl-sdr support and remove the dependency on
|
||||||
librtlsdr.
|
librtlsdr.
|
||||||
|
|
||||||
|
``make LIMESDR=no`` will disable LimeSDR support and remove the dependency on
|
||||||
|
libLimeSuite.
|
||||||
|
|
|
||||||
|
|
@ -267,6 +267,9 @@ void showHelp(void) {
|
||||||
#ifdef ENABLE_BLADERF
|
#ifdef ENABLE_BLADERF
|
||||||
"ENABLE_BLADERF "
|
"ENABLE_BLADERF "
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_LIMESDR
|
||||||
|
"ENABLE_LIMESDR "
|
||||||
|
#endif
|
||||||
#ifdef SC16Q11_TABLE_BITS
|
#ifdef SC16Q11_TABLE_BITS
|
||||||
// This is a little silly, but that's how the preprocessor works..
|
// This is a little silly, but that's how the preprocessor works..
|
||||||
#define _stringize(x) #x
|
#define _stringize(x) #x
|
||||||
|
|
|
||||||
|
|
@ -280,7 +280,7 @@ typedef enum {
|
||||||
//======================== structure declarations =========================
|
//======================== structure declarations =========================
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SDR_NONE, SDR_IFILE, SDR_RTLSDR, SDR_BLADERF
|
SDR_NONE, SDR_IFILE, SDR_RTLSDR, SDR_BLADERF, SDR_LIMESDR
|
||||||
} sdr_type_t;
|
} sdr_type_t;
|
||||||
|
|
||||||
// Structure representing one magnitude buffer
|
// Structure representing one magnitude buffer
|
||||||
|
|
|
||||||
7
sdr.c
7
sdr.c
|
|
@ -27,6 +27,9 @@
|
||||||
#ifdef ENABLE_BLADERF
|
#ifdef ENABLE_BLADERF
|
||||||
# include "sdr_bladerf.h"
|
# include "sdr_bladerf.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_LIMESDR
|
||||||
|
# include "sdr_limesdr.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
@ -85,6 +88,10 @@ static sdr_handler sdr_handlers[] = {
|
||||||
{ "bladerf", SDR_BLADERF, bladeRFInitConfig, bladeRFShowHelp, bladeRFHandleOption, bladeRFOpen, bladeRFRun, bladeRFClose },
|
{ "bladerf", SDR_BLADERF, bladeRFInitConfig, bladeRFShowHelp, bladeRFHandleOption, bladeRFOpen, bladeRFRun, bladeRFClose },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_LIMESDR
|
||||||
|
{ "limesdr", SDR_LIMESDR, limesdrInitConfig, limesdrShowHelp, limesdrHandleOption, limesdrOpen, limesdrRun, limesdrClose },
|
||||||
|
#endif
|
||||||
|
|
||||||
{ "ifile", SDR_IFILE, ifileInitConfig, ifileShowHelp, ifileHandleOption, ifileOpen, ifileRun, ifileClose },
|
{ "ifile", SDR_IFILE, ifileInitConfig, ifileShowHelp, ifileHandleOption, ifileOpen, ifileRun, ifileClose },
|
||||||
{ "none", SDR_NONE, noInitConfig, noShowHelp, noHandleOption, noOpen, noRun, noClose },
|
{ "none", SDR_NONE, noInitConfig, noShowHelp, noHandleOption, noOpen, noRun, noClose },
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,345 @@
|
||||||
|
// Part of dump1090, a Mode S message decoder for RTLSDR devices.
|
||||||
|
//
|
||||||
|
// sdr_limesdr.c: LimeSDR dongle support
|
||||||
|
//
|
||||||
|
// Copyright (c) 2020 Gluttton <gluttton@ukr.net>
|
||||||
|
//
|
||||||
|
// 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/>.
|
||||||
|
|
||||||
|
// This file incorporates work covered by the following copyright and
|
||||||
|
// permission notice:
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 by Salvatore Sanfilippo <antirez@gmail.com>
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
|
// documentation and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "dump1090.h"
|
||||||
|
#include "sdr_limesdr.h"
|
||||||
|
|
||||||
|
#include <lime/LimeSuite.h>
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
lms_device_t *dev;
|
||||||
|
lms_stream_t stream;
|
||||||
|
bool is_stream_opened;
|
||||||
|
bool is_stop;
|
||||||
|
int bytes_in_sample;
|
||||||
|
iq_convert_fn converter;
|
||||||
|
struct converter_state *converter_state;
|
||||||
|
} LimeSDR;
|
||||||
|
|
||||||
|
void limesdrLogHandler(int lvl, const char *msg)
|
||||||
|
{
|
||||||
|
FILE *out = NULL;
|
||||||
|
switch (lvl) {
|
||||||
|
default:
|
||||||
|
case LMS_LOG_DEBUG:
|
||||||
|
return;
|
||||||
|
case LMS_LOG_INFO:
|
||||||
|
out = stdout;
|
||||||
|
break;
|
||||||
|
case LMS_LOG_WARNING:
|
||||||
|
case LMS_LOG_ERROR:
|
||||||
|
case LMS_LOG_CRITICAL:
|
||||||
|
out = stderr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(out, "limesdr: %s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void limesdrInitConfig()
|
||||||
|
{
|
||||||
|
LimeSDR.dev = NULL;
|
||||||
|
LimeSDR.stream.channel = 0;
|
||||||
|
LimeSDR.stream.fifoSize = 1024 * 1024;
|
||||||
|
LimeSDR.stream.throughputVsLatency = 1.0; // best throughput
|
||||||
|
LimeSDR.stream.isTx = false;
|
||||||
|
LimeSDR.stream.dataFmt = LMS_FMT_I16; // should be matched with conveter
|
||||||
|
LimeSDR.is_stream_opened = false;
|
||||||
|
LimeSDR.is_stop = false;
|
||||||
|
LimeSDR.bytes_in_sample = 2 * sizeof(int16_t); // hardcoded for LMS_FMT_I16
|
||||||
|
|
||||||
|
LMS_RegisterLogHandler(limesdrLogHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void limesdrShowHelp()
|
||||||
|
{
|
||||||
|
printf(" limesdr-specific options (use with --device-type limesdr)\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("so far there is no any LimeSDR specific option...\n");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool limesdrHandleOption(int argc, char **argv, int *jptr)
|
||||||
|
{
|
||||||
|
MODES_NOTUSED(argc);
|
||||||
|
MODES_NOTUSED(argv);
|
||||||
|
MODES_NOTUSED(jptr);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool limesdrOpen(void)
|
||||||
|
{
|
||||||
|
const size_t devCountMax = 8;
|
||||||
|
lms_info_str_t list[devCountMax];
|
||||||
|
const int devCount = LMS_GetDeviceList(list);
|
||||||
|
if (devCount < 0) {
|
||||||
|
fprintf(stderr, "limesdr: unable to get a number of connected devices\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devCount < 1) {
|
||||||
|
fprintf(stderr, "limesdr: no connected devices\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LMS_Open(&LimeSDR.dev, list[0], NULL) ) {
|
||||||
|
fprintf(stderr, "limesdr: unable to open device\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LMS_Init(LimeSDR.dev)) {
|
||||||
|
fprintf(stderr, "limesdr: unable to initialize device\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LMS_EnableChannel(LimeSDR.dev, LMS_CH_RX, LimeSDR.stream.channel, true)) {
|
||||||
|
fprintf(stderr, "limesdr: unable to enable RX channel\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LMS_SetLOFrequency(LimeSDR.dev, LMS_CH_RX, LimeSDR.stream.channel, Modes.freq)) {
|
||||||
|
fprintf(stderr, "limesdr: unable to set frequency\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LMS_SetAntenna(LimeSDR.dev, LMS_CH_RX, LimeSDR.stream.channel, LMS_PATH_LNAL)) {
|
||||||
|
fprintf(stderr, "limesdr: unable to set RF port\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LMS_SetSampleRate(LimeSDR.dev, Modes.sample_rate, 0/*default oversample*/)) {
|
||||||
|
fprintf(stderr, "limesdr: unable to set sampling rate\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LMS_SetNormalizedGain(LimeSDR.dev, LMS_CH_RX, LimeSDR.stream.channel, 0.85)) {
|
||||||
|
fprintf(stderr, "limesdr: unable to set gain\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LMS_SetLPFBW(LimeSDR.dev, LMS_CH_RX, LimeSDR.stream.channel, Modes.sample_rate)) {
|
||||||
|
fprintf(stderr, "limesdr: unable to set LP filter\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
LimeSDR.is_stream_opened = true;
|
||||||
|
if (LMS_SetupStream(LimeSDR.dev, &LimeSDR.stream)) {
|
||||||
|
fprintf(stderr, "limesdr: unable to setup stream\n");
|
||||||
|
LimeSDR.is_stream_opened = false;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LMS_Calibrate(LimeSDR.dev, LMS_CH_RX, LimeSDR.stream.channel, 2.5e6/*0.5e5*/, 0)) {
|
||||||
|
fprintf(stderr, "limesdr: unable to calibrate device\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
LimeSDR.converter = init_converter(INPUT_SC16,
|
||||||
|
Modes.sample_rate,
|
||||||
|
Modes.dc_filter,
|
||||||
|
&LimeSDR.converter_state);
|
||||||
|
if (!LimeSDR.converter) {
|
||||||
|
fprintf(stderr, "limesdr: can't initialize sample converter.\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (LimeSDR.is_stream_opened) {
|
||||||
|
LMS_DestroyStream(LimeSDR.dev, &LimeSDR.stream);
|
||||||
|
LimeSDR.is_stream_opened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LimeSDR.dev) {
|
||||||
|
LMS_Close(LimeSDR.dev);
|
||||||
|
LimeSDR.dev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct timespec limesdr_thread_cpu;
|
||||||
|
|
||||||
|
void limesdrCallback(unsigned char *buf, uint32_t len, void *ctx)
|
||||||
|
{
|
||||||
|
struct mag_buf *outbuf;
|
||||||
|
struct mag_buf *lastbuf;
|
||||||
|
uint32_t slen;
|
||||||
|
unsigned next_free_buffer;
|
||||||
|
unsigned free_bufs;
|
||||||
|
unsigned block_duration;
|
||||||
|
|
||||||
|
static int dropping = 0;
|
||||||
|
static uint64_t sampleCounter = 0;
|
||||||
|
|
||||||
|
MODES_NOTUSED(ctx);
|
||||||
|
|
||||||
|
// Lock the data buffer variables before accessing them
|
||||||
|
pthread_mutex_lock(&Modes.data_mutex);
|
||||||
|
if (Modes.exit) {
|
||||||
|
LimeSDR.is_stop = true; // ask our caller to exit
|
||||||
|
}
|
||||||
|
|
||||||
|
next_free_buffer = (Modes.first_free_buffer + 1) % MODES_MAG_BUFFERS;
|
||||||
|
outbuf = &Modes.mag_buffers[Modes.first_free_buffer];
|
||||||
|
lastbuf = &Modes.mag_buffers[(Modes.first_free_buffer + MODES_MAG_BUFFERS - 1) % MODES_MAG_BUFFERS];
|
||||||
|
free_bufs = (Modes.first_filled_buffer - next_free_buffer + MODES_MAG_BUFFERS) % MODES_MAG_BUFFERS;
|
||||||
|
|
||||||
|
// Paranoia! Unlikely, but let's go for belt and suspenders here
|
||||||
|
|
||||||
|
if (len != MODES_RTL_BUF_SIZE) {
|
||||||
|
fprintf(stderr, "weirdness: limesdr gave us a block with an unusual size (got %u bytes, expected %u bytes)\n",
|
||||||
|
(unsigned)len, (unsigned)MODES_RTL_BUF_SIZE);
|
||||||
|
|
||||||
|
if (len > MODES_RTL_BUF_SIZE) {
|
||||||
|
// wat?! Discard the start.
|
||||||
|
unsigned discard = (len - MODES_RTL_BUF_SIZE + 1) / LimeSDR.bytes_in_sample;
|
||||||
|
outbuf->dropped += discard;
|
||||||
|
buf += discard * LimeSDR.bytes_in_sample;
|
||||||
|
len -= discard * LimeSDR.bytes_in_sample;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slen = len / LimeSDR.bytes_in_sample; // Drops any trailing odd sample, that's OK
|
||||||
|
|
||||||
|
if (free_bufs == 0 || (dropping && free_bufs < MODES_MAG_BUFFERS/2)) {
|
||||||
|
// FIFO is full. Drop this block.
|
||||||
|
dropping = 1;
|
||||||
|
outbuf->dropped += slen;
|
||||||
|
sampleCounter += slen;
|
||||||
|
pthread_mutex_unlock(&Modes.data_mutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dropping = 0;
|
||||||
|
pthread_mutex_unlock(&Modes.data_mutex);
|
||||||
|
|
||||||
|
// Compute the sample timestamp and system timestamp for the start of the block
|
||||||
|
outbuf->sampleTimestamp = sampleCounter * 12e6 / Modes.sample_rate;
|
||||||
|
sampleCounter += slen;
|
||||||
|
|
||||||
|
// Get the approx system time for the start of this block
|
||||||
|
block_duration = 1e3 * slen / Modes.sample_rate;
|
||||||
|
outbuf->sysTimestamp = mstime() - block_duration;
|
||||||
|
|
||||||
|
// Copy trailing data from last block (or reset if not valid)
|
||||||
|
if (outbuf->dropped == 0) {
|
||||||
|
memcpy(outbuf->data, lastbuf->data + lastbuf->length, Modes.trailing_samples * sizeof(uint16_t));
|
||||||
|
} else {
|
||||||
|
memset(outbuf->data, 0, Modes.trailing_samples * sizeof(uint16_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the new data
|
||||||
|
outbuf->length = slen;
|
||||||
|
LimeSDR.converter(buf, &outbuf->data[Modes.trailing_samples], slen, LimeSDR.converter_state, &outbuf->mean_level, &outbuf->mean_power);
|
||||||
|
|
||||||
|
// Push the new data to the demodulation thread
|
||||||
|
pthread_mutex_lock(&Modes.data_mutex);
|
||||||
|
|
||||||
|
Modes.mag_buffers[next_free_buffer].dropped = 0;
|
||||||
|
Modes.mag_buffers[next_free_buffer].length = 0; // just in case
|
||||||
|
Modes.first_free_buffer = next_free_buffer;
|
||||||
|
|
||||||
|
// accumulate CPU while holding the mutex, and restart measurement
|
||||||
|
end_cpu_timing(&limesdr_thread_cpu, &Modes.reader_cpu_accumulator);
|
||||||
|
start_cpu_timing(&limesdr_thread_cpu);
|
||||||
|
|
||||||
|
pthread_cond_signal(&Modes.data_cond);
|
||||||
|
pthread_mutex_unlock(&Modes.data_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void limesdrRun()
|
||||||
|
{
|
||||||
|
if (!LimeSDR.dev) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t *buffer = malloc(MODES_RTL_BUF_SIZE);
|
||||||
|
|
||||||
|
LMS_StartStream(&LimeSDR.stream);
|
||||||
|
|
||||||
|
start_cpu_timing(&limesdr_thread_cpu);
|
||||||
|
|
||||||
|
while (!LimeSDR.is_stop) {
|
||||||
|
int sampleCnt = LMS_RecvStream(&LimeSDR.stream, buffer, MODES_RTL_BUF_SIZE / LimeSDR.bytes_in_sample, NULL, 1000);
|
||||||
|
if (sampleCnt) {
|
||||||
|
limesdrCallback((unsigned char *)buffer, sampleCnt * LimeSDR.bytes_in_sample, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Modes.exit) {
|
||||||
|
fprintf(stderr, "limesdr: async read returned unexpectedly.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
LMS_StopStream(&LimeSDR.stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
void limesdrClose()
|
||||||
|
{
|
||||||
|
if (LimeSDR.converter) {
|
||||||
|
cleanup_converter(LimeSDR.converter_state);
|
||||||
|
LimeSDR.converter = NULL;
|
||||||
|
LimeSDR.converter_state = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LMS_StopStream(&LimeSDR.stream);
|
||||||
|
|
||||||
|
if (LimeSDR.is_stream_opened) {
|
||||||
|
LMS_DestroyStream(LimeSDR.dev, &LimeSDR.stream);
|
||||||
|
LimeSDR.is_stream_opened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LimeSDR.dev) {
|
||||||
|
LMS_Close(LimeSDR.dev);
|
||||||
|
LimeSDR.dev = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Part of dump1090, a Mode S message decoder for RTLSDR devices.
|
||||||
|
//
|
||||||
|
// sdr_limesdr.h: LimeSDR dongle support (header)
|
||||||
|
//
|
||||||
|
// Copyright (c) 2020 Gluttton <gluttton@ukr.net>
|
||||||
|
//
|
||||||
|
// 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_LIMESDR_H
|
||||||
|
#define SDR_LIMESDR_H
|
||||||
|
|
||||||
|
void limesdrInitConfig();
|
||||||
|
void limesdrShowHelp();
|
||||||
|
bool limesdrOpen();
|
||||||
|
void limesdrRun();
|
||||||
|
void limesdrClose();
|
||||||
|
bool limesdrHandleOption(int argc, char **argv, int *jptr);
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Reference in New Issue