aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmo-fl2k.h3
-rw-r--r--src/fl2k_file.c23
-rw-r--r--src/libosmo-fl2k.c51
3 files changed, 64 insertions, 13 deletions
diff --git a/include/osmo-fl2k.h b/include/osmo-fl2k.h
index 02ad4ad..aefbb8c 100644
--- a/include/osmo-fl2k.h
+++ b/include/osmo-fl2k.h
@@ -51,6 +51,9 @@ typedef struct fl2k_data_info {
/* filled in by application */
int sampletype_signed; /* are samples signed or unsigned? */
+ /* Either iq_buf or (r_buf, g_buf and b_buf) must be non-null */
+ char *iq_buf; /* pointer to data containing interleaved r and g
+ data */
char *r_buf; /* pointer to red buffer */
char *g_buf; /* pointer to green buffer */
char *b_buf; /* pointer to blue buffer */
diff --git a/src/fl2k_file.c b/src/fl2k_file.c
index 5ae199b..6829deb 100644
--- a/src/fl2k_file.c
+++ b/src/fl2k_file.c
@@ -42,7 +42,8 @@
static fl2k_dev_t *dev = NULL;
static volatile int do_exit = 0;
-static volatile int repeat = 1;
+static int repeat = 1;
+static int interleaved = 1;
FILE *file;
char *txbuf = NULL;
@@ -54,6 +55,7 @@ void usage(void)
"\t[-d device_index (default: 0)]\n"
"\t[-r repeat file (default: 1)]\n"
"\t[-s samplerate (default: 100 MS/s)]\n"
+ "\t[-i interleave (input samples are interleaved Red/Green values, useful for I/Q data, default: 0)]\n"
"\tfilename (use '-' to read from stdin)\n\n"
);
exit(1);
@@ -82,7 +84,9 @@ static void sighandler(int signum)
void fl2k_callback(fl2k_data_info_t *data_info)
{
- int r, left = FL2K_BUF_LEN;
+ int r;
+ const int required_samples = FL2K_BUF_LEN * (interleaved ? 2 : 1);
+ int left = required_samples;
static uint32_t repeat_cnt = 0;
if (data_info->device_error) {
@@ -92,10 +96,14 @@ void fl2k_callback(fl2k_data_info_t *data_info)
}
data_info->sampletype_signed = 1;
- data_info->r_buf = txbuf;
+ if (interleaved) {
+ data_info->iq_buf = txbuf;
+ } else {
+ data_info->r_buf = txbuf;
+ }
while (!do_exit && (left > 0)) {
- r = fread(txbuf + (FL2K_BUF_LEN - left), 1, left, file);
+ r = fread(txbuf + (required_samples - left), 1, left, file);
if (ferror(file))
fprintf(stderr, "File Error\n");
@@ -128,11 +136,14 @@ int main(int argc, char **argv)
void *status;
char *filename = NULL;
- while ((opt = getopt(argc, argv, "d:r:s:")) != -1) {
+ while ((opt = getopt(argc, argv, "d:i:r:s:")) != -1) {
switch (opt) {
case 'd':
dev_index = (uint32_t)atoi(optarg);
break;
+ case 'i':
+ interleaved = (int)atoi(optarg);
+ break;
case 'r':
repeat = (int)atoi(optarg);
break;
@@ -166,7 +177,7 @@ int main(int argc, char **argv)
}
}
- txbuf = malloc(FL2K_BUF_LEN);
+ txbuf = malloc(FL2K_BUF_LEN * (interleaved ? 2 : 1));
if (!txbuf) {
fprintf(stderr, "malloc error!\n");
goto out;
diff --git a/src/libosmo-fl2k.c b/src/libosmo-fl2k.c
index 99dcd33..3e166e0 100644
--- a/src/libosmo-fl2k.c
+++ b/src/libosmo-fl2k.c
@@ -799,6 +799,37 @@ static void *fl2k_usb_worker(void *arg)
}
/* Buffer format conversion functions for R, G, B DACs */
+static inline void fl2k_convert_rg_interleaved(
+ char *out,
+ char *in,
+ uint32_t len,
+ uint8_t offset)
+{
+ unsigned int i, j = 0;
+
+ if (!in || !out)
+ return;
+
+ for (i = 0; i < len; i += 24) {
+ out[i+ 6] = in[j++] + offset;
+ out[i+ 5] = in[j++] + offset;
+ out[i+ 1] = in[j++] + offset;
+ out[i+ 0] = in[j++] + offset;
+ out[i+12] = in[j++] + offset;
+ out[i+ 3] = in[j++] + offset;
+ out[i+15] = in[j++] + offset;
+ out[i+14] = in[j++] + offset;
+ out[i+10] = in[j++] + offset;
+ out[i+ 9] = in[j++] + offset;
+ out[i+21] = in[j++] + offset;
+ out[i+20] = in[j++] + offset;
+ out[i+16] = in[j++] + offset;
+ out[i+23] = in[j++] + offset;
+ out[i+19] = in[j++] + offset;
+ out[i+18] = in[j++] + offset;
+ }
+}
+
static inline void fl2k_convert_r(char *out,
char *in,
uint32_t len,
@@ -914,15 +945,21 @@ static void *fl2k_sample_worker(void *arg)
xfer_info = (fl2k_xfer_info_t *)xfer->user_data;
out_buf = (char *)xfer->buffer;
- /* Re-arrange and copy bytes in buffer for DACs */
- fl2k_convert_r(out_buf, data_info.r_buf, dev->xfer_buf_len,
- data_info.sampletype_signed ? 128 : 0);
+ if (data_info.iq_buf) {
+ /* Re-arrange interleaved samples and copy bytes in buffer for DACs */
+ fl2k_convert_rg_interleaved(out_buf, data_info.iq_buf,
+ dev->xfer_buf_len, data_info.sampletype_signed ? 128 : 0);
+ } else {
+ /* Re-arrange and copy bytes in buffer for DACs */
+ fl2k_convert_r(out_buf, data_info.r_buf, dev->xfer_buf_len,
+ data_info.sampletype_signed ? 128 : 0);
- fl2k_convert_g(out_buf, data_info.g_buf, dev->xfer_buf_len,
- data_info.sampletype_signed ? 128 : 0);
+ fl2k_convert_g(out_buf, data_info.g_buf, dev->xfer_buf_len,
+ data_info.sampletype_signed ? 128 : 0);
- fl2k_convert_b(out_buf, data_info.b_buf, dev->xfer_buf_len,
- data_info.sampletype_signed ? 128 : 0);
+ fl2k_convert_b(out_buf, data_info.b_buf, dev->xfer_buf_len,
+ data_info.sampletype_signed ? 128 : 0);
+ }
xfer_info->seq = buf_cnt++;
xfer_info->state = BUF_FILLED;