summaryrefslogtreecommitdiff
path: root/examples/ad9371-iiostream.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/ad9371-iiostream.c')
-rw-r--r--examples/ad9371-iiostream.c306
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;
-}