Category: Software
Product Number: adalm pluto
HI, im trying to use libiio with ADALM pluto 2r2t where im trying to calculate cross correlation in real time. Below is the code i put together, the majority of it is taken from ad9361 receive example in c from ADI forum. I read the libiio documentation for the iio_buffer_first function and i understood that it returns a pointer for a given channel, and can also be used to loop over all channels. Ive defined the cross correlation function up as seen in the code, and im trying to run the cross correlation on the IQ samples in real time as its streaming, for some reason it doesnt output anything. I tried using function pointer, no pointer, void, everything. Any help on how to correct this ?
Sincere appreciation,
Abdalla
#include <stdio.h>
#include <iio.h>
#include <math.h>
#include <unistd.h>
#include <sys/wait.h>
#include <pthread.h>
#include <time.h>
#include <signal.h>
#include <complex.h>
float complex* cross_correlate(float complex* sig1, float complex* sig2, size_t n){
int mid = n / 2;
int lags[n];
float complex correlated[n];
for(int i = 0; i < n; i++) {
lags[i] = i - mid;
correlated[i] = 0.0;
for(int j = 0; j < n; j++){
correlated[i] += sig1[j] * conj(sig2[j - lags[i]]) / n;
// printf("%d %f\n", lags[i], creal(correlated[i]));
}
}
return correlated;
}
int receive(struct iio_context *ctx)
{
struct iio_device *dev;
struct iio_channel *rx0_i, *rx0_q, *rx1_i, *rx1_q;
struct iio_buffer *rxbuf;
dev = iio_context_find_device(ctx, "cf-ad9361-lpc");
rx0_i = iio_device_find_channel(dev, "voltage0", 0);
rx0_q = iio_device_find_channel(dev, "voltage1", 0);
rx1_i = iio_device_find_channel(dev, "voltage2", 0);
rx1_q = iio_device_find_channel(dev, "voltage3", 0);
iio_channel_enable(rx0_i);
iio_channel_enable(rx0_q);
iio_channel_enable(rx1_i);
iio_channel_enable(rx1_q);
rxbuf = iio_device_create_buffer(dev, 4096, false);
if (!rxbuf) {
perror("Could not create RX buffer for chan 0");
shutdown();
}
while (true) {
void *p_dat, *p_end, *t_dat;
ptrdiff_t p_inc;
iio_buffer_refill(rxbuf);
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, t_dat += p_inc) {
const int16_t i = ((int16_t*)p_dat)[0]; // Real (I)
const int16_t q = ((int16_t*)p_dat)[1]; // Imag (Q)
const int16_t i1 = ((int16_t*)p_dat)[2]; // Real (I)
const int16_t q2 = ((int16_t*)p_dat)[3]; // Imag (Q)
// const int16_t I_tot = i + i1;
// const int16_t Q_tot = q + q2;
float complex sig1 = i + I*q;
float complex sig2 = i1 + I*q2;
// printf("%d\t%d\t%d\t%d\n",i, q, i1, q2);
float complex* xcorr = cross_correlate(&sig1, &sig2, 4096);
printf("%f\n", creal(xcorr));
}
}
iio_buffer_destroy(rxbuf);
}
int main (int argc, char **argv)
{
struct iio_context *ctx;
struct iio_device *phy;
ctx = iio_create_context_from_uri("ip:pluto.local");
phy = iio_context_find_device(ctx, "ad9361-phy");
iio_channel_attr_write_longlong(
iio_device_find_channel(phy, "altvoltage0", true),
"frequency",
2400000000); /* RX LO frequency 2.4GHz */
iio_channel_attr_write_longlong(
iio_device_find_channel(phy, "voltage0", false),
"sampling_frequency",
5000000); /* RX baseband rate 5 MSPS */
int pid = fork();
if(pid == 1){
printf("Process failed to create.\n");
return -1;
};
if(pid == 0){
while(1){
receive(ctx);
sleep(1);
};
}
else{
sleep(1);
kill(pid, SIGKILL);
printf("Recieved 1 second worth of data.\n");
wait(NULL);
}
iio_context_destroy(ctx);
return 0;
}