Skip to content

Instantly share code, notes, and snippets.

@csete
Created March 27, 2018 11:03
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save csete/ece39ec9f66d751889821fa7619360e4 to your computer and use it in GitHub Desktop.
Save csete/ece39ec9f66d751889821fa7619360e4 to your computer and use it in GitHub Desktop.
Test application for LimeSDR
/*
* gcc -Wall -Wextra -O2 -o limerx limerx.c -lLimeSuite
*
* ./limerx [samprate] [oversmapling]
*/
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/time.h>
#include "lime/LimeSuite.h"
#define SAMPLE_BUFFER_MS 10.f
#define SAMPLE_BUFFER_SEC (1.e-3f * SAMPLE_BUFFER_MS)
#define READ_TIMEOUT_MS (10 * SAMPLE_BUFFER_MS)
#define STATUS_DT_MS 1000
static lms_device_t *device = NULL;
static bool keep_running;
void signal_handler_func(int signal)
{
fprintf(stderr, "Caught signal %d\n", signal);
if (signal == SIGINT || signal == SIGTERM)
keep_running = false;
}
void device_error()
{
if (device != NULL)
LMS_Close(device);
exit(-1);
}
static uint64_t time_ms(void)
{
struct timeval tval;
gettimeofday(&tval, NULL);
return 1e3 * tval.tv_sec + 1e-3 * tval.tv_usec;
}
int main(int argc, char** argv)
{
struct sigaction signal_handler;
lms_info_str_t *device_list;
lms_stream_t stream;
int num_dev;
int16_t *sample_buffer;
size_t sample_count;
int samples_read;
int samples_last;
uint64_t samples_total;
float sample_rate;
int oversampling;
uint64_t tstart, tlast, tnow;
float runtime;
// register signal handler (CTRL-C to stop application)
signal_handler.sa_handler = signal_handler_func;
sigemptyset(&signal_handler.sa_mask);
signal_handler.sa_flags = 0;
sigaction(SIGINT, &signal_handler, NULL);
sigaction(SIGTERM, &signal_handler, NULL);
sigaction(SIGPIPE, &signal_handler, NULL);
// enumerate attached LimeSDR devices and start streaming from the first one
num_dev = LMS_GetDeviceList(NULL);
if (num_dev < 0)
{
fprintf(stderr, "Error probing for LimeSDR devices\n");
device_error();
}
if (num_dev == 0)
{
fprintf(stderr, "No LimeSDR devices found\n");
exit(0);
}
device_list = (lms_info_str_t *) malloc(num_dev * sizeof(lms_info_str_t));
if (LMS_GetDeviceList(device_list) != num_dev)
{
free(device_list);
fprintf(stderr, "LMS_GetDeviceList() returned inconsistent number\n");
device_error();
}
fprintf(stderr, "Found %d LimeSDR devices\n", num_dev);
// open the first device
if (LMS_Open(&device, device_list[0], NULL))
{
fprintf(stderr, "Failed to open LimeSDR\n");
free(device_list);
device_error();
}
fprintf(stderr, "LimeSDR opened: %s\n", device_list[0]);
free(device_list);
/* Initialize device with default configuration
* Do not use if you want to keep existing configuration
* Use LMS_LoadConfig(device, "/path/to/file.ini") to load config from INI
*/
if (LMS_Init(device) != 0)
{
fprintf(stderr, "Error initializing LimeSDR device\n");
device_error();
}
/* Enable RX channel (starting at 0) */
if (LMS_EnableChannel(device, LMS_CH_RX, 0, true) != 0)
{
fprintf(stderr, "Failed to enable RX channel\n");
device_error();
}
/* Set center frequency */
if (LMS_SetLOFrequency(device, LMS_CH_RX, 0, 145e6) != 0)
{
fprintf(stderr, "Failed to set LO frequency\n");
device_error();
}
/* Set sample rate oversampling */
sample_rate = argc > 1 ? atof(argv[1]) : 8.0e6;
oversampling = argc > 2 ? atoi(argv[2]) : 0;
if (LMS_SetSampleRate(device, sample_rate, oversampling) != 0)
{
fprintf(stderr, "Failed to set sample rate\n");
device_error();
}
fprintf(stderr, "Set sample rate %.0f Hz (oversampling %d)\n",
sample_rate, oversampling);
// setup stream
stream.channel = 0;
stream.fifoSize = 1024 * 1024; // samples
stream.throughputVsLatency = 1.0; // optimize for max throughput
stream.isTx = false; // RX channel
stream.dataFmt = LMS_FMT_I12;
if (LMS_SetupStream(device, &stream) != 0)
{
fprintf(stderr, "Error configuring stream\n");
device_error();
}
sample_count = sample_rate * SAMPLE_BUFFER_SEC;
sample_buffer = (int16_t *) malloc(2 * sample_count * sizeof(int16_t));
if (LMS_StartStream(&stream) != 0)
{
fprintf(stderr, "Failed to start streaming\n");
device_error();
}
fprintf(stderr, "Stream started\n");
samples_last = samples_total = 0;
tnow = tstart = tlast = time_ms();
keep_running = true;
while (keep_running)
{
samples_read = LMS_RecvStream(&stream, sample_buffer, sample_count,
NULL, READ_TIMEOUT_MS);
if (samples_read == -1)
{
fprintf(stderr, "An error occurred during streaming\n");
break;
}
tnow = time_ms();
samples_total += samples_read;
samples_last += samples_read;
if (tnow - tlast >= STATUS_DT_MS)
{
fprintf(stderr, "%.3f ksps\n",
(float)samples_last / (float)(tnow - tlast));
tlast = tnow;
samples_last = 0;
}
}
tnow = time_ms();
runtime = tnow - tstart;
fprintf(stderr, "Stopping stream...\n");
LMS_StopStream(&stream);
LMS_DestroyStream(device, &stream);
LMS_Close(device);
if (sample_buffer)
free(sample_buffer);
fprintf(stderr, "Read %" PRIu64 " samples in %.3f sec => %.3f ksps\n",
samples_total, 1.e-3f * runtime, (float)samples_total / runtime);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment