Skip to content

Commit

Permalink
Merge pull request #611 from analogdevicesinc/update_pluto_example
Browse files Browse the repository at this point in the history
examples/pluto_tddn: Add a complete example
  • Loading branch information
tfcollins authored Oct 28, 2024
2 parents 67bba95 + fd3180f commit be6d695
Showing 1 changed file with 135 additions and 18 deletions.
153 changes: 135 additions & 18 deletions examples/pluto_tddn.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,143 @@
#
# SPDX short identifier: ADIBSD

import time

import adi
import matplotlib.pyplot as plt
import numpy as np

plt.close("all")

# This script uses the new Pluto TDD engine
# Make sure your Pluto firmware is updated to rev 0.39 (or later)
# And PYADI-IIO is rev 0.18 or greater
# TDD test with Pluto
# Connect a SMA cable from Tx1 to Rx1


# %% Configuration Variables
sample_rate = 10e6
center_freq = 2.1e9
signal_freq = 500e3
rx_gain = 20
tx_gain = -10

# %% Setup SDR
sdr_ip = "ip:192.168.2.1" # usually "ip:192.168.2.1", or "ip:pluto.local"
gpio = adi.one_bit_adc_dac(sdr_ip)
my_sdr = adi.Pluto(uri=sdr_ip)
tddn = adi.tddn(sdr_ip)

# 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
# But if you don't care about this, then program sample_rate and LO's as much as you want
# So after bootup, check if the default sample_rate and LOs are being used, if so then program new ones!
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!")

sdr = adi.Pluto()

# Configure Rx
my_sdr.rx_enabled_channels = [0]
sample_rate = int(my_sdr.sample_rate)
# manual or slow_attack
my_sdr.gain_control_mode_chan0 = "manual"
my_sdr.rx_hardwaregain_chan0 = int(rx_gain)
# Default is 4 Rx buffers are stored, but to immediately see the result, set buffers=1
my_sdr._rxadc.set_kernel_buffers_count(1)

# Configure Tx
my_sdr.tx_enabled_channels = [0]
my_sdr.tx_hardwaregain_chan0 = int(tx_gain)
my_sdr.tx_cyclic_buffer = True # must be true to use the TDD transmit

# Enable phaser logic in pluto
gpio = adi.one_bit_adc_dac("ip:192.168.2.1")
time.sleep(0.5)
# when true, each channel[1] start outputs a pulse to Pluto L10P pin (TXDATA_1V8 on Phaser schematic)
gpio.gpio_phaser_enable = True
time.sleep(0.5)

# Configure TDD properties
tdd = adi.tddn("ip:pluto.local")
tdd.enable = False # make sure the TDD is disabled before changing properties
tdd.frame_length_ms = 4 # each GPIO toggle is spaced 4ms apart
tdd.startup_delay_ms = 0 # do not set a startup delay
tdd.burst_count = 3 # there is a burst of 3 toggles, then off for a long time
tdd.channel[0].on_ms = 0.5 # the first trigger will happen 0.5ms into the buffer
tdd.channel[0].off_ms = 0.6 # each GPIO pulse will be 100us (0.6ms - 0.5ms)
tdd.channel[0].enable = True # enable CH0 output
tdd.sync_external = True # enable external sync trigger
tdd.enable = True # enable TDD engine

rx_time_ms = 4
tx_time_ms = rx_time_ms
frame_length_ms = rx_time_ms
capture_range = 100

frame_length_samples = int((rx_time_ms / 1000) * my_sdr.sample_rate)
N_rx = int(1 * frame_length_samples)
my_sdr.rx_buffer_size = N_rx

tddn.startup_delay_ms = 0
tddn.frame_length_ms = frame_length_ms
tddn.burst_count = 0 # 0 means repeat indefinitely

tddn.channel[0].on_raw = 0
tddn.channel[0].off_raw = 0
tddn.channel[0].polarity = 1
tddn.channel[0].enable = 1

# RX DMA SYNC
tddn.channel[1].on_raw = 0
tddn.channel[1].off_raw = 10
tddn.channel[1].polarity = 0
tddn.channel[1].enable = 1

# TX DMA SYNC
tddn.channel[2].on_raw = 0
tddn.channel[2].off_raw = 10
tddn.channel[2].polarity = 0
tddn.channel[2].enable = 1

tddn.sync_external = True # enable external sync trigger
tddn.enable = True # enable TDD engine

# Create a sinewave waveform
N = int(my_sdr.rx_buffer_size)
fc = signal_freq
ts = 1 / float(sample_rate)
t = np.arange(0, N * ts, ts)
i = np.cos(2 * np.pi * t * fc) * 2 ** 11
q = np.sin(2 * np.pi * t * fc) * 2 ** 11
iq = i + 1j * q

# Send data
print("sending IQ data")
my_sdr.tx(iq)

tddn.sync_soft = 1 # start the TDD transmit

# Print the configuration information
print(f"TX/RX Sampling_rate: {my_sdr.sample_rate}")
print(f"Number of samples in a frame: {frame_length_samples}")
print(f"RX buffer length: {N_rx}")
print(f"TX buffer length: {len(iq)}")
print(f"RX_receive time[ms]: {((1 / my_sdr.sample_rate) * N_rx) * 1000}")
print(f"TX_transmit time[ms]: {((1 / my_sdr.sample_rate) * len(iq)) * 1000}")
print(f"TDD_frame time[ms]: {tddn.frame_length_ms}")
print(f"TDD_frame time[raw]: {tddn.frame_length_raw}")

receive_array = np.zeros((capture_range, frame_length_samples)) * 1j

# Receive data
for r in range(capture_range):
receive_array[r] = my_sdr.rx()

# Plot the received data
for i in range(r):
plt.plot(receive_array[i].real)
plt.xlim(0, 100)
plt.show()

# Pluto transmit shutdown
tddn.enable = 0
for i in range(3):
tddn.channel[i].on_ms = 0
tddn.channel[i].off_raw = 0
tddn.channel[i].polarity = 0
tddn.channel[i].enable = 1
tddn.enable = 1
tddn.enable = 0

my_sdr.tx_destroy_buffer()
print("Pluto Buffer Cleared!")

0 comments on commit be6d695

Please sign in to comment.