diff options
-rw-r--r-- | include/osmo-fl2k.h | 3 | ||||
-rw-r--r-- | src/fl2k_file.c | 23 | ||||
-rw-r--r-- | src/libosmo-fl2k.c | 51 |
3 files changed, 64 insertions, 13 deletions
diff --git a/include/osmo-fl2k.h b/include/osmo-fl2k.h index 8d3cc3b..6a1b3ee 100644 --- a/include/osmo-fl2k.h +++ b/include/osmo-fl2k.h @@ -50,6 +50,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 1d3697d..0da1cbc 100644 --- a/src/fl2k_file.c +++ b/src/fl2k_file.c @@ -40,7 +40,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; @@ -52,6 +53,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); @@ -80,14 +82,20 @@ 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; 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"); @@ -120,11 +128,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; @@ -151,7 +162,7 @@ int main(int argc, char **argv) goto out; } - 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 0285f9a..09380b6 100644 --- a/src/libosmo-fl2k.c +++ b/src/libosmo-fl2k.c @@ -767,6 +767,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, @@ -882,15 +913,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; |