From afeab80d0f3c1571fb4e711189151f1d81af6965 Mon Sep 17 00:00:00 2001 From: "Travis F. Collins" Date: Thu, 14 Dec 2023 15:32:44 -0700 Subject: [PATCH] Update test code to include RX side Add RX continuity aspects of tests Signed-off-by: Travis F. Collins --- tests/CMakeLists.txt | 1 + tests/hardware/test_ad9364.c | 170 ++++++++++++++++++++++++++++---- tests/standalone/test_version.c | 1 + 3 files changed, 154 insertions(+), 18 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cd2378708..ae872d585 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,3 +1,4 @@ +add_definitions(-UNDEBUG) if(TESTS_DEBUG) add_definitions(-DTESTS_DEBUG) endif() diff --git a/tests/hardware/test_ad9364.c b/tests/hardware/test_ad9364.c index 383f3751e..5a13934ca 100644 --- a/tests/hardware/test_ad9364.c +++ b/tests/hardware/test_ad9364.c @@ -1,3 +1,9 @@ +// This test is designed to verify data from transmit to receive buffers by +// using a ramp signal. The ramp signal is generated on the TX side and then +// received on the RX side. The RX side then checks to make sure the ramp is +// continuous within the buffer but not across buffers. However, every buffer is +// checked to make sure the ramp is continuous. + #include #include #include @@ -5,7 +11,18 @@ #include "iio/iio.h" -#define N_TX_SAMPLES 512 +// Use (void) to silence unused warnings. +#define assertm(exp, msg) assert(((void)msg, exp)) + +// User Set +#define N_TX_SAMPLES 16 +#define RX_OVERSAMPLE 4 +#define SUCCESSIVE_BUFFER_TO_CHECK 2 +#define N_RX_BLOCKS 4 + +// Calculated/Constant +#define N_RX_SAMPLES N_TX_SAMPLES *RX_OVERSAMPLE +#define N_CHANNELS 2 #define BYTES_PER_SAMPLE 2 struct iio_context *ctx; @@ -14,7 +31,9 @@ const struct iio_attr *attr; struct iio_channel *chn; struct iio_channels_mask *txmask, *rxmask; struct iio_buffer *txbuf, *rxbuf; -struct iio_block *txblock, *rxblock; +struct iio_block *txblock; +const struct iio_block *rxblock; +struct iio_stream *rxstream; int main() { @@ -26,36 +45,34 @@ int main() { ctx = iio_create_context(NULL, uri); phy = iio_context_find_device(ctx, "ad9361-phy"); - assert(phy); + assertm(phy, "Unable to find AD9361-phy device"); rx = iio_context_find_device(ctx, "cf-ad9361-lpc"); - assert(rx); + assertm(rx, "Unable to find RX device"); tx = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc"); - assert(tx); + assertm(tx, "Unable to find TX device"); // Configure device into loopback mode attr = iio_device_find_debug_attr(phy, "loopback"); - assert(attr); + assertm(attr, "Unable to find loopback attribute"); iio_attr_write_string(attr, "1"); // TX Side txmask = iio_create_channels_mask(iio_device_get_channels_count(tx)); - assert(txmask); + assertm(txmask, "Unable to create TX mask"); chn = iio_device_find_channel(tx, "voltage0", true); - assert(chn); + assertm(chn, "Unable to find TX channel"); iio_channel_enable(chn, txmask); chn = iio_device_find_channel(tx, "voltage1", true); - assert(chn); + assertm(chn, "Unable to find TX channel"); iio_channel_enable(chn, txmask); txbuf = iio_device_create_buffer(tx, 0, txmask); - err = iio_err(txbuf); - if (err) { - // dev_perror(tx, err, "Unable to create TX buffer"); - assert(err == 0); - } + assertm(txbuf, "Unable to create TX buffer"); - txblock = iio_buffer_create_block(txbuf, N_TX_SAMPLES*BYTES_PER_SAMPLE); + txblock = iio_buffer_create_block(txbuf, N_TX_SAMPLES * BYTES_PER_SAMPLE * + N_CHANNELS); + assertm(txblock, "Unable to create TX block"); // Generate ramp signal on both I and Q channels int16_t *p_dat, *p_end; @@ -75,10 +92,127 @@ int main() { } iio_block_enqueue(txblock, 0, true); iio_buffer_enable(txbuf); + sleep(2); + + // RX Side + rxmask = iio_create_channels_mask(iio_device_get_channels_count(rx)); + assertm(rxmask, "Unable to create RX mask"); + + chn = iio_device_find_channel(rx, "voltage0", false); + assertm(chn, "Unable to find RX channel voltage0"); + iio_channel_enable(chn, rxmask); + chn = iio_device_find_channel(rx, "voltage1", false); + assertm(chn, "Unable to find RX channel voltage1"); + iio_channel_enable(chn, rxmask); + + rxbuf = iio_device_create_buffer(rx, 0, rxmask); + assertm(rxbuf, "Unable to create RX buffer"); + + rxstream = iio_buffer_create_stream(rxbuf, N_RX_BLOCKS, N_RX_SAMPLES); + assertm(rxstream, "Unable to create RX stream"); + + p_inc = iio_device_get_sample_size(rx, rxmask); + chn = iio_device_find_channel(rx, "voltage0", false); + + bool found_start = false; + int16_t ramp_indx = 0; + int16_t looped = 0; + + // Create check vector + bool ramp_found_check_vector[SUCCESSIVE_BUFFER_TO_CHECK]; + bool continuous_check_vector[SUCCESSIVE_BUFFER_TO_CHECK]; + + // Remove first few blocks as they might be old + for (int i = 0; i < 30; i++) { + rxblock = iio_stream_get_next_block(rxstream); + printf("Removing block %d\n", i); + } + + // Check several buffers to make sure no glitches occurred + for (int i = 0; i < SUCCESSIVE_BUFFER_TO_CHECK; i++) { + + printf("Checking buffer %d of %d\n", i + 1, SUCCESSIVE_BUFFER_TO_CHECK); + + rxblock = iio_stream_get_next_block(rxstream); + + // Within a block data should be continuous but not necessarily across + // blocks + found_start = false; + continuous_check_vector[i] = true; // assume good + + for (p_dat = iio_block_first(rxblock, chn); p_dat < p_end; + p_dat += p_inc / sizeof(*p_dat)) { + + // Locate top of ramp + if (p_dat[0] == (N_TX_SAMPLES - 1) && p_dat[1] == (N_TX_SAMPLES - 1) && + !found_start) { + found_start = true; + continue; + } + + // Make sure ramp is continuous + if (found_start) { +#ifdef TESTS_DEBUG + printf("Expected: %d\n", ramp_indx); + printf("Actual: %d, %d (I, Q)\n\n", p_dat[0], p_dat[1]); +#endif + if (p_dat[0] != ramp_indx && p_dat[1] != ramp_indx) { +#ifdef TESTS_DEBUG + printf("--->Expected: %d (Buffer %d)\n", ramp_indx, i); + printf("--->Actual: %d, %d (I, Q) [Buffer %d]\n\n", p_dat[0], + p_dat[1], i); + printf("\n\n"); +#endif + continuous_check_vector[i] = false; + } + if (ramp_indx == (N_TX_SAMPLES - 1)) { + ramp_indx = 0; + looped++; + } else + ramp_indx++; + } + } + + ramp_found_check_vector[i] = found_start; + if (!found_start) + continuous_check_vector[i] = false; + } + + // Examine check vector + bool failed_c1 = false; + bool failed_c2 = false; +#ifdef TESTS_DEBUG + printf("1 == Check Passed, 0 == Failed\n"); + printf("Ramp Check, Contiguous Check (Buffer #)\n"); +#endif + for (int i = 0; i < SUCCESSIVE_BUFFER_TO_CHECK; i++) { +#ifdef TESTS_DEBUG + printf("%d, %d (%d)\n", ramp_found_check_vector[i], + continuous_check_vector[i], i); +#endif + if (!ramp_found_check_vector[i]) + failed_c1 = true; + if (!continuous_check_vector[i]) + failed_c2 = true; + } +#ifdef TESTS_DEBUG + printf("\n"); +#endif + assertm(!failed_c1, "Ramp was not found in all buffers"); + assertm(!failed_c2, "Ramp was not contiguous in all buffers"); + + iio_stream_destroy(rxstream); + iio_buffer_destroy(rxbuf); + +// // Manual check RX (disable asserts above first) +// printf("Open up the time scope to see data. Should be a ramp from 0->%d\n", +// idx - 1); +// sleep(40); + + // Cleanup + iio_block_destroy(txblock); + iio_buffer_destroy(txbuf); - // Sleep for 40 seconds - printf("Open up the time scope to see data. Should be a ramp from 0->%d\n", N_TX_SAMPLES); - sleep(40); return 0; } \ No newline at end of file diff --git a/tests/standalone/test_version.c b/tests/standalone/test_version.c index 5d9c58525..8ba916863 100644 --- a/tests/standalone/test_version.c +++ b/tests/standalone/test_version.c @@ -1,5 +1,6 @@ #include #include +#include #include "iio/iio.h"