diff options
Diffstat (limited to 'examples/ad9371-iiostream.c')
-rw-r--r-- | examples/ad9371-iiostream.c | 306 |
1 files changed, 0 insertions, 306 deletions
diff --git a/examples/ad9371-iiostream.c b/examples/ad9371-iiostream.c deleted file mode 100644 index f330377..0000000 --- a/examples/ad9371-iiostream.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * libiio - AD9371 IIO streaming example - * - * Copyright (C) 2014 IABG mbH - * Author: Michael Feilen <feilen_at_iabg.de> - * Copyright (C) 2017 Analog Devices Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - **/ - -#include <stdbool.h> -#include <stdint.h> -#include <string.h> -#include <signal.h> -#include <stdio.h> - -#ifdef __APPLE__ -#include <iio/iio.h> -#else -#include <iio.h> -#endif - -/* helper macros */ -#define MHZ(x) ((long long)(x*1000000.0 + .5)) -#define GHZ(x) ((long long)(x*1000000000.0 + .5)) - -#define ASSERT(expr) { \ - if (!(expr)) { \ - (void) fprintf(stderr, "assertion failed (%s:%d)\n", __FILE__, __LINE__); \ - (void) abort(); \ - } \ -} - -/* RX is input, TX is output */ -enum iodev { RX, TX }; - -/* common RX and TX streaming params */ -struct stream_cfg { - long long lo_hz; // Local oscillator frequency in Hz -}; - -/* static scratch mem for strings */ -static char tmpstr[64]; - -/* IIO structs required for streaming */ -static struct iio_context *ctx = NULL; -static struct iio_channel *rx0_i = NULL; -static struct iio_channel *rx0_q = NULL; -static struct iio_channel *tx0_i = NULL; -static struct iio_channel *tx0_q = NULL; -static struct iio_buffer *rxbuf = NULL; -static struct iio_buffer *txbuf = NULL; - -static bool stop; - -/* cleanup and exit */ -static void shutdown() -{ - printf("* Destroying buffers\n"); - if (rxbuf) { iio_buffer_destroy(rxbuf); } - if (txbuf) { iio_buffer_destroy(txbuf); } - - printf("* Disabling streaming channels\n"); - if (rx0_i) { iio_channel_disable(rx0_i); } - if (rx0_q) { iio_channel_disable(rx0_q); } - if (tx0_i) { iio_channel_disable(tx0_i); } - if (tx0_q) { iio_channel_disable(tx0_q); } - - printf("* Destroying context\n"); - if (ctx) { iio_context_destroy(ctx); } - exit(0); -} - -static void handle_sig(int sig) -{ - printf("Waiting for process to finish...\n"); - stop = true; -} - -/* check return value of attr_write function */ -static void errchk(int v, const char* what) { - if (v < 0) { fprintf(stderr, "Error %d writing to channel \"%s\"\nvalue may not be supported.\n", v, what); shutdown(); } -} - -/* write attribute: long long int */ -static void wr_ch_lli(struct iio_channel *chn, const char* what, long long val) -{ - errchk(iio_channel_attr_write_longlong(chn, what, val), what); -} - -/* write attribute: long long int */ -static long long rd_ch_lli(struct iio_channel *chn, const char* what) -{ - long long val; - - errchk(iio_channel_attr_read_longlong(chn, what, &val), what); - - printf("\t %s: %lld\n", what, val); - return val; -} - -#if 0 -/* write attribute: string */ -static void wr_ch_str(struct iio_channel *chn, const char* what, const char* str) -{ - errchk(iio_channel_attr_write(chn, what, str), what); -} -#endif - -/* helper function generating channel names */ -static char* get_ch_name_mod(const char* type, int id, char modify) -{ - snprintf(tmpstr, sizeof(tmpstr), "%s%d_%c", type, id, modify); - return tmpstr; -} - -/* helper function generating channel names */ -static char* get_ch_name(const char* type, int id) -{ - snprintf(tmpstr, sizeof(tmpstr), "%s%d", type, id); - return tmpstr; -} - -/* returns ad9371 phy device */ -static struct iio_device* get_ad9371_phy(struct iio_context *ctx) -{ - struct iio_device *dev = iio_context_find_device(ctx, "ad9371-phy"); - ASSERT(dev && "No ad9371-phy found"); - return dev; -} - -/* finds AD9371 streaming IIO devices */ -static bool get_ad9371_stream_dev(struct iio_context *ctx, enum iodev d, struct iio_device **dev) -{ - switch (d) { - case TX: *dev = iio_context_find_device(ctx, "axi-ad9371-tx-hpc"); return *dev != NULL; - case RX: *dev = iio_context_find_device(ctx, "axi-ad9371-rx-hpc"); return *dev != NULL; - default: ASSERT(0); return false; - } -} - -/* finds AD9371 streaming IIO channels */ -static bool get_ad9371_stream_ch(struct iio_context *ctx, enum iodev d, struct iio_device *dev, int chid, char modify, struct iio_channel **chn) -{ - *chn = iio_device_find_channel(dev, modify ? get_ch_name_mod("voltage", chid, modify) : get_ch_name("voltage", chid), d == TX); - if (!*chn) - *chn = iio_device_find_channel(dev, modify ? get_ch_name_mod("voltage", chid, modify) : get_ch_name("voltage", chid), d == TX); - return *chn != NULL; -} - -/* finds AD9371 phy IIO configuration channel with id chid */ -static bool get_phy_chan(struct iio_context *ctx, enum iodev d, int chid, struct iio_channel **chn) -{ - switch (d) { - case RX: *chn = iio_device_find_channel(get_ad9371_phy(ctx), get_ch_name("voltage", chid), false); return *chn != NULL; - case TX: *chn = iio_device_find_channel(get_ad9371_phy(ctx), get_ch_name("voltage", chid), true); return *chn != NULL; - default: ASSERT(0); return false; - } -} - -/* finds AD9371 local oscillator IIO configuration channels */ -static bool get_lo_chan(struct iio_context *ctx, enum iodev d, struct iio_channel **chn) -{ - switch (d) { - // LO chan is always output, i.e. true - case RX: *chn = iio_device_find_channel(get_ad9371_phy(ctx), get_ch_name("altvoltage", 0), true); return *chn != NULL; - case TX: *chn = iio_device_find_channel(get_ad9371_phy(ctx), get_ch_name("altvoltage", 1), true); return *chn != NULL; - default: ASSERT(0); return false; - } -} - -/* applies streaming configuration through IIO */ -bool cfg_ad9371_streaming_ch(struct iio_context *ctx, struct stream_cfg *cfg, enum iodev type, int chid) -{ - struct iio_channel *chn = NULL; - - // Configure phy and lo channels - printf("* Acquiring AD9371 phy %s channel %d\n", type == TX ? "TX" : "RX", chid); - if (!get_phy_chan(ctx, type, chid, &chn)) { return false; } - - rd_ch_lli(chn, "rf_bandwidth"); - rd_ch_lli(chn, "sampling_frequency"); - - // Configure LO channel - printf("* Acquiring AD9371 %s lo channel\n", type == TX ? "TX" : "RX"); - if (!get_lo_chan(ctx, type, &chn)) { return false; } - wr_ch_lli(chn, type == TX ? "TX_LO_frequency" : "RX_LO_frequency" , cfg->lo_hz); - return true; -} - -/* simple configuration and streaming */ -int main (int argc, char **argv) -{ - // Streaming devices - struct iio_device *tx; - struct iio_device *rx; - - // RX and TX sample counters - size_t nrx = 0; - size_t ntx = 0; - - // Stream configurations - struct stream_cfg rxcfg; - struct stream_cfg txcfg; - - // Listen to ctrl+c and ASSERT - signal(SIGINT, handle_sig); - - // RX stream config - rxcfg.lo_hz = GHZ(2.5); // 2.5 GHz rf frequency - - // TX stream config - txcfg.lo_hz = GHZ(2.5); // 2.5 GHz rf frequency - - printf("* Acquiring IIO context\n"); - ASSERT((ctx = iio_create_default_context()) && "No context"); - ASSERT(iio_context_get_devices_count(ctx) > 0 && "No devices"); - - printf("* Acquiring AD9371 streaming devices\n"); - ASSERT(get_ad9371_stream_dev(ctx, TX, &tx) && "No tx dev found"); - ASSERT(get_ad9371_stream_dev(ctx, RX, &rx) && "No rx dev found"); - - printf("* Configuring AD9371 for streaming\n"); - ASSERT(cfg_ad9371_streaming_ch(ctx, &rxcfg, RX, 0) && "RX port 0 not found"); - ASSERT(cfg_ad9371_streaming_ch(ctx, &txcfg, TX, 0) && "TX port 0 not found"); - - printf("* Initializing AD9371 IIO streaming channels\n"); - ASSERT(get_ad9371_stream_ch(ctx, RX, rx, 0, 'i', &rx0_i) && "RX chan i not found"); - ASSERT(get_ad9371_stream_ch(ctx, RX, rx, 0, 'q', &rx0_q) && "RX chan q not found"); - ASSERT(get_ad9371_stream_ch(ctx, TX, tx, 0, 0, &tx0_i) && "TX chan i not found"); - ASSERT(get_ad9371_stream_ch(ctx, TX, tx, 1, 0, &tx0_q) && "TX chan q not found"); - - printf("* Enabling IIO streaming channels\n"); - iio_channel_enable(rx0_i); - iio_channel_enable(rx0_q); - iio_channel_enable(tx0_i); - iio_channel_enable(tx0_q); - - printf("* Creating non-cyclic IIO buffers with 1 MiS\n"); - rxbuf = iio_device_create_buffer(rx, 1024*1024, false); - if (!rxbuf) { - perror("Could not create RX buffer"); - shutdown(); - } - txbuf = iio_device_create_buffer(tx, 1024*1024, false); - if (!txbuf) { - perror("Could not create TX buffer"); - shutdown(); - } - - printf("* Starting IO streaming (press CTRL+C to cancel)\n"); - while (!stop) - { - ssize_t nbytes_rx, nbytes_tx; - char *p_dat, *p_end; - ptrdiff_t p_inc; - - // Schedule TX buffer - nbytes_tx = iio_buffer_push(txbuf); - if (nbytes_tx < 0) { printf("Error pushing buf %d\n", (int) nbytes_tx); shutdown(); } - - // Refill RX buffer - nbytes_rx = iio_buffer_refill(rxbuf); - if (nbytes_rx < 0) { printf("Error refilling buf %d\n",(int) nbytes_rx); shutdown(); } - - // READ: Get pointers to RX buf and read IQ from RX buf port 0 - p_inc = iio_buffer_step(rxbuf); - p_end = iio_buffer_end(rxbuf); - for (p_dat = iio_buffer_first(rxbuf, rx0_i); p_dat < p_end; p_dat += p_inc) { - // Example: swap I and Q - const int16_t i = ((int16_t*)p_dat)[0]; // Real (I) - const int16_t q = ((int16_t*)p_dat)[1]; // Imag (Q) - ((int16_t*)p_dat)[0] = q; - ((int16_t*)p_dat)[1] = i; - } - - // WRITE: Get pointers to TX buf and write IQ to TX buf port 0 - p_inc = iio_buffer_step(txbuf); - p_end = iio_buffer_end(txbuf); - for (p_dat = iio_buffer_first(txbuf, tx0_i); p_dat < p_end; p_dat += p_inc) { - // Example: fill with zeros - // 14-bit sample needs to be MSB alligned so shift by 2 - // https://wiki.analog.com/resources/eval/user-guides/ad-fmcomms2-ebz/software/basic_iq_datafiles#binary_format - ((int16_t*)p_dat)[0] = 0 << 2; // Real (I) - ((int16_t*)p_dat)[1] = 0 << 2; // Imag (Q) - } - - // Sample counter increment and status output - nrx += nbytes_rx / iio_device_get_sample_size(rx); - ntx += nbytes_tx / iio_device_get_sample_size(tx); - printf("\tRX %8.2f MSmp, TX %8.2f MSmp\n", nrx/1e6, ntx/1e6); - } - - shutdown(); - - return 0; -} |