Skip to content

Commit

Permalink
Add ability to configure clock source in SoapySDR from device settings
Browse files Browse the repository at this point in the history
  • Loading branch information
BatchDrake committed Sep 1, 2024
1 parent cdd5729 commit 3629a52
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 2 deletions.
2 changes: 2 additions & 0 deletions analyzer/source.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ extern "C" {
#define SUSCAN_SOURCE_SETTING_PFXLEN (sizeof("setting:") - 1)
#define SUSCAN_STREAM_SETTING_PREFIX "stream:"
#define SUSCAN_STREAM_SETTING_PFXLEN (sizeof("stream:") - 1)
#define SUSCAN_SOAPY_SETTING_PREFIX "soapy:"
#define SUSCAN_SOAPY_SETTING_PFXLEN (sizeof("soapy:") - 1)

#define SUSCAN_SOURCE_DEFAULT_READ_TIMEOUT 100000 /* 100 ms */
#define SUSCAN_SOURCE_ANTIALIAS_REL_SIZE 5
Expand Down
68 changes: 67 additions & 1 deletion analyzer/source/impl/soapysdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,41 @@ suscan_source_soapysdr_find_stream_arg(
return NULL;
}

SUPRIVATE void
suscan_source_soapysdr_debug_clocks(struct suscan_source_soapysdr *self)
{
size_t i = 0;
char *ref_string = NULL;
char *tmp = NULL;

for (i = 0; i < self->clock_sources_count; ++i) {
if (ref_string == NULL) {
SU_TRY(tmp = strdup(self->clock_sources[i]));
} else {
SU_TRY(tmp = strbuild("%s, %s", ref_string, self->clock_sources[i]));
free(ref_string);
}

ref_string = tmp;
}

if (ref_string == NULL)
SU_INFO("Device does not external clock reference\n");
else
SU_INFO("Device supports the following clock references: %s\n", ref_string);

done:
if (ref_string != NULL)
free(ref_string);
}

SUPRIVATE SUBOOL
suscan_source_soapysdr_init_sdr(struct suscan_source_soapysdr *self)
{
suscan_source_config_t *config = self->config;
unsigned int i;
char *antenna = NULL;
const char *key, *desc;
const char *key, *desc, *val;
SoapySDRArgInfo *arg;
SUBOOL ok = SU_FALSE;

Expand Down Expand Up @@ -129,6 +157,9 @@ suscan_source_soapysdr_init_sdr(struct suscan_source_soapysdr *self)
goto done;
}

if (SoapySDRDevice_setClockSource(self->sdr, "external") != 0)
SU_WARNING("Failed to switch to external clock\n");

#if SOAPY_SDR_API_VERSION >= 0x00060000
if (SoapySDRDevice_setFrequencyCorrection(
self->sdr,
Expand Down Expand Up @@ -242,6 +273,19 @@ suscan_source_soapysdr_init_sdr(struct suscan_source_soapysdr *self)
goto done;
}

self->clock_sources = SoapySDRDevice_listClockSources(self->sdr, &self->clock_sources_count);

if (self->clock_sources_count != 0) {
if (self->clock_sources == NULL) {
SU_ERROR(
"Failed to retrieve clock source list: %s\n",
SoapySDRDevice_lastError());
goto done;
}

suscan_source_soapysdr_debug_clocks(self);
}

for (i = 0; i < config->soapy_args->size; ++i) {
if (strncmp(
config->soapy_args->keys[i],
Expand All @@ -267,6 +311,25 @@ suscan_source_soapysdr_init_sdr(struct suscan_source_soapysdr *self)
self->sdr,
key,
config->soapy_args->vals[i]);
} else if (strncmp(
config->soapy_args->keys[i],
SUSCAN_SOAPY_SETTING_PREFIX,
SUSCAN_SOAPY_SETTING_PFXLEN) == 0) {
key = config->soapy_args->keys[i] + SUSCAN_SOAPY_SETTING_PFXLEN;
val = config->soapy_args->vals[i];

if (strcmp(key, "clock") == 0) {
if (SoapySDRDevice_setClockSource(self->sdr, val) != 0) {
SU_ERROR(
"Cannot set clock source to %s: %s\n",
val,
SoapySDRDevice_lastError());
goto done;
}
} else {
SU_ERROR("Unknown SoapySDR-specific tweak `%s'\n", key);
goto done;
}
}
}

Expand Down Expand Up @@ -299,6 +362,9 @@ suscan_source_soapysdr_close(void *ptr)
if (self->settings != NULL)
SoapySDRArgInfoList_clear(self->settings, self->settings_count);

if (self->clock_sources != NULL)
SoapySDRStrings_clear(&self->clock_sources, self->clock_sources_count);

if (self->stream_args != NULL)
SoapySDRArgInfoList_clear(self->stream_args, self->stream_args_count);

Expand Down
4 changes: 3 additions & 1 deletion analyzer/source/impl/soapysdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ struct suscan_source_soapysdr {
size_t settings_count;
SoapySDRArgInfo *stream_args;
size_t stream_args_count;

char **clock_sources;
size_t clock_sources_count;

size_t chan_array[1];
SUFLOAT samp_rate; /* Actual sample rate */
size_t mtu;
Expand Down

0 comments on commit 3629a52

Please sign in to comment.