I want to use the Phaser FMCW radar code with MATLAB, so it only works on ADLAM-Pluto. First, is there any sample code like this? I need to run the TDD engine with Matlab for TX-RX channel synchronization. Is this possible without Phaser?
I want to use the Phaser FMCW radar code with MATLAB, so it only works on ADLAM-Pluto. First, is there any sample code like this? I need to run the TDD engine with Matlab for TX-RX channel synchronization. Is this possible without Phaser?
I'm using the following Matlab code. Every time I run the code, the signal I see on the Rx side changes its position. I'm trying to determine if TDD is working correctly, but I'm not sure if the results I'm getting are normal. I'd appreciate any information you could provide.
%% Parameters
fs = 30e6; % sample rate
B = 7.5e6; % sweep bandwidth
N = 32768;
Tc = N/fs;
f0 = 0;
f1 = fs/4;
rxGain_dB = 40;
txAtten_dB = -20;
fc = 2e9; % LO
c = 3e8;
%% Pluto TX Configs
plutoURI = 'ip:192.168.2.1';
tx = adi.AD9361.Tx('uri', plutoURI);
tx.CenterFrequency = fc;
tx.SamplingRate = fs;
tx.EnabledChannels = 1;
tx.EnableCyclicBuffers = true;
tx.AttenuationChannel0 = txAtten_dB;
%% Pluto RX Configs
rx = adi.AD9361.Rx('uri', plutoURI);
rx.CenterFrequency = fc;
rx.SamplingRate = fs;
rx.RFBandwidth = B*1.2;
rx.EnabledChannels = 1;
rx.SamplesPerFrame = N;
rx.kernelBuffersCount = 2;
rx.GainControlModeChannel0 = 'manual';
% rx.GainControlModeChannel1 = 'manual';
rx.GainChannel0 = rxGain_dB;
% rx.GainChannel1 = rxGain_dB;
%% TDD Engine Configs
bf_TDD = setupTddEngine();
bf_TDD.Enable = 0;
bf_TDD.EnSyncExternal = 1;
bf_TDD.StartupDelay = 0;
bf_TDD.FrameLength = 8;
bf_TDD.BurstCount = 0; % 0 = repeat tx wave form
% CH0
bf_TDD.Ch0Enable = 1;
bf_TDD.Ch0Polarity = 0;
bf_TDD.Ch0On = 0;
bf_TDD.Ch0Off = 10;
% CH1: RX DMA SYNC
bf_TDD.Ch1Enable = 1;
bf_TDD.Ch1Polarity = 0;
bf_TDD.Ch1On = 0;
bf_TDD.Ch1Off = 10;
% CH2: TX DMA SYNC
bf_TDD.Ch2Enable = 1;
bf_TDD.Ch2Polarity = 0;
bf_TDD.Ch2On = 0;
bf_TDD.Ch2Off = 10;
%% FMCW chirp
t = (0:N-1).' / fs;
realChirp = chirp(t, f0, Tc, f1, 'linear');
% Amplitude scale: 0.9 * 2^11
scale = 0.9 * 2^11;
realChirp = realChirp * scale;
% Hilbert
iqChirp = hilbert(realChirp);
% TX waveform
txWaveform = iqChirp(:); % column vector
%% Transmit configs
% bf_TDD.Enable = 1;
% bf_TDD.SyncSoft = 1; % Soft-sync the TDD engine
% rx();
% tx(txWaveform);
% data = rx();
%%%%%%%%%%%%%%%%%%%%%%%%%%
tx(txWaveform);
bf_TDD.Enable = 1;
bf_TDD.SyncSoft = 1; % Soft-sync the TDD engine
rx();
data = rx();
figure
subplot(2,1,2)
plot(real(data));
hold on;
subplot(2,1,1)
plot(real(txWaveform));
hold on;
function [bf_TDD] = setupTddEngine()
% Setup the TDD Engine. By default no trigger is required to collect data.
%
% Copyright 2023 The MathWorks, Inc.
plutoURI = 'ip:192.168.2.1';
bf_TDD = adi.PlutoTDD('uri', plutoURI);
bf_TDD();
end

Even though I haven't made any changes to the loopback setup, the RX signal position changes every time I turn it on. Is this normal?
Hi Kaloc,
We are working on publishing a demo for the Pluto to show TDD use and radar, but it might be a little while longer. In the meantime, it looks like you have made a lot of progress and are doing all the right stuff. Two things:
1. We don't have a great write up for Pluto TDD yet, the best "documentation" is this talk I did: https://youtu.be/ZnCi-LHJ0GQ?si=zFV9OK_mjlb8QZTw&t=998
2. I think an issue you are running into is an undocumented issue with Pluto TDD, so let me explain it here:
If you want repeatable alignment between transmit and receive then the rx_lo, tx_lo and sample_rate can only be set once after power up. Why is this? I don't know. It's just a quirk of how Pluto gets programmed. Not really any reason, just something we have to work around if you want Tx and Rx to always be lined up. So what I do is, after bootup, I check to see if the default sample_rate and LOs are still there. If they are, then it means I haven't yet programmed them, so I can program a new one. But if they are not the default values, then I know I've already set them and so I won't program new ones (as that would change the timing relationship between the Tx and Rx buffer). Note that reading does not cause the timing to change. But rewriting (even if its the exact same value) will cause the timing to change.
Therefore, what I do is this:
if 30719990<my_sdr.sample_rate<30720009 and 2399999990<my_sdr.rx_lo<2400000009 and 2449999990<my_sdr.tx_lo<2450000009:
my_sdr.sample_rate = int(sample_rate)
my_sdr.rx_lo = int(center_freq)
my_sdr.tx_lo = int(center_freq)
print("Pluto has just booted and I've set the sample rate and LOs!")
It's a little cumbersome, but its worked for me. Give it a try!